一、模式选择
1. 要想棋盘可以选择,之前定义的常数(详细看上篇扫雷的设计)就都的换了。用变量表示扫雷数组的打印的大小,创建两个足够大的数组以便不同大小的棋盘布置。
*创建两个数组一个作为雷地布置棋盘,一个作为扫雷的效果棋盘*/
char mine[100][100] = { 0 };
char show[100][100] = { 0 };
/*初始化棋盘函数*/
initboard(mine, 100, 100,' ');
initboard2(show, i, j,'*');
/*布置棋盘函数*/
setboard(mine, i, j,k);
/*打印棋盘函数*/
displayboard(show, i, j);
//displayboard(mine, i, j);
/*排查雷函数*/
findbomb(mine, show, i, j,
2. 判断模式选择条件
void game()
{
int mode, i ,j,k,o=0;
printf("1、简单9*9棋盘 10个雷\n2、中等16*16棋盘 40个雷\n3、困难30*16棋盘 99雷\n");
printf("请选择游戏模式=>:");
scanf_s("%d", &mode);
do
{
switch (mode)
{
case 1:i = 9, j = 9 ,k =10 ;
break;
case 2:i = 16, j = 16 ,k =40;
break;
case 3:i = 16, j = 30 ,k =99;
break;
default:o=1;
break;
}
} while (o);
二、展开为空
1. 首先要把布雷数组赋值为空;
initboard(mine, 100, 100,' ');
void initboard(char arr[100][100],int ROWS,int COLS,char set)
{
int i,j;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
arr[i][j] = set;
}
}
}
2. 为了让get函数的输出依旧是雷的数量,把雷布置为’!’符号
‘!’和‘ ’符号的ascii码表值相差一,只要再将get函数中的‘0’符号改为‘ ’符号,get函数计算的值依旧是雷的数量
void setboard(char arr[100][100], int ROW, int COL,int COUNT)
{
int count = COUNT;
while (count)
{
int x = rand() % ROW + 1;
int y = rand() % COL + 1;
if (arr[x][y] == ' ')
{
arr[x][y] = '!';
count--;
}
}
}
int get(char arr[100][100], int x, int y)
{
int s,i;
s = arr[x - 1][y - 1] + arr[x - 1][y] + arr[x - 1][y + 1] +
arr[x][y - 1] + arr[x][y + 1] +
arr[x + 1][y - 1] + arr[x + 1][y] + arr[x + 1][y + 1];
i = s - 8 * ' ';
return i;
}
3. 递归里的第一个‘0’符号改,是用来将雷的数量转化为字符型的媒介。
void extand(char arr1[100][100], char arr2[100][100], int x, int y)
{
int i, j;
int s = get(arr1, x, y);
if (s != 0)
arr2[x][y] = '0' + s;
else
{
arr2[x][y] = ' ';
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
if(arr2[i][j]== '*'&&arr2[i][j]!='#')
extand(arr1, arr2, i, j);
}
}
}
}
三、递归优化中Bug的解决
上篇递归优化的Bug是:优化前的的游戏获胜判断条件是输入n次坐标,n为棋盘单位大小个数减去雷的数量,但优化后输入坐标的次数减少了。所以要改变获胜判断条件。
1. 定义一个bombcount函数计算棋盘中剩余‘*’的数量。
/*计算剩余‘*’数量*/
int bombcount(char arr[100][100], int ROW, int COL,int COUNT)
{
int i, j, s = 0;
for(i=1;i<=ROW;i++)
for (j = 1; j <=COL; j++)
{
if (arr[i][j] == '*')
s++;
}
if (s == COUNT)
return 1;
return 0;
}
2. 将获胜条件改为bonbcount函数的值等于雷的数量。
void findbomb(char arr1[100][100], char arr2[100][100], int ROW, int COL,int COUNT)
{
int s;
while (1)
{
printf("输入需要排查的位置(x,y)=>:");
int x, y, i, j;
scanf_s("%d%d", &x, &y);
system("cls");
if (x > 0 && x <= ROW && y > 0 && y <= COL)
{
if (arr1[x][y] == '!')
{
printf("很遗憾你被炸死了\n");
printf("雷地分布是这样的:\n");
displayboard(arr1, ROW, COL);
break;
}
else
{
extand(arr1, arr2, x, y);
displayboard(arr2, ROW, COL);
if (bombcount(arr2, ROW, COL, COUNT) == 1)
break;
}
}
else
{
printf("坐标输入错误\n");
displayboard(arr2, ROW, COL);
continue;
}
}
if (bombcount(arr2,ROW,COL,COUNT)==1)
printf("恭喜你排雷成功\n");
}
如果觉得讲的不错还请帮忙点点赞。嘿嘿