007 【编程之路扫雷游戏】(C语言实现)( 二 )

<= col; j++){printf("%c ", board[i][j]);}printf("\n");}printf("-------------------\n");}
这里所打印出来的棋盘是展示棋盘,而不是雷区棋盘 。我们在函数传参的时候把'*'传个展示棋盘,让其保持待探索的感觉 。效果如下
布置雷区
void SetMine(char board[ROWS][COLS], int row, int col){int x = 0, y = 0;int count = AMOUNT;//AMOUNT是我们定义的雷的数量while (count){x = rand() % row + 1;//(0~8)+1==1~9y = rand() % col + 1;//(0~8)+1==1~9if (board[x][y] == '0'){board[x][y] = '1';//雷我们用字符'1'来表示,因为形参的类型是charcount--;}}}
rand()函数和main()函数中的srand()函数随机生成了个雷 。
对于rand函数和srand函数不懂的可以参考这一篇文章
rand()和srand()函数的用法的博客-CSDN博客和rand函数怎么用
确定周围雷数量值
int AmountMine(char board[ROWS][COLS], int x, int y){return (board[x - 1][y] +board[x - 1][y - 1] +board[x][y - 1] +board[x + 1][y - 1] +board[x + 1][y] +board[x + 1][y + 1] +board[x][y + 1] +board[x - 1][y + 1] - 8 * '0');//减去8*'0':因为我们的雷区中都是字符型的'0'//非雷'1'//雷 。//所以如果有n个雷,就会产生n*'1'-n*'0'的整数 。('1'-'0'=1)}
对于玩家排查的一个(x,y)的格子,我们应该返回周围一圈有多少雷,如下图
标记雷
void FlagMine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col, int x, int y){if (x >= 1 && x <= row && y >= 1 && y <= col){show[x][y] = '!';}}
我们把标记的雷在展示数组上用'!'标记 。
取消标记
void FlagCancel(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col, int x, int y){if (show[x][y] == '!'){show[x][y] = '*';}}
我们想把原来标记的取消,直接在改成'*'即可 。
递归展开空白安全区
void Spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y){int around_x = 0;int around_y = 0;int count = 0;//坐标合法if (x >= 1 && x <= 9 && y >= 1 && y <= 9){//遍历周围坐标for (around_x = -1; around_x <= 1; around_x++){for (around_y = -1; around_y <= 1; around_y++){//如果这个坐标不是雷if (mine[x + around_x][y + around_y] == '0'){//统计周围雷的个数count = AmountMine(mine, x + around_x, y + around_y);if (count == 0){if (show[x + around_x][y + around_y] == '*'){show[x + around_x][y + around_y] = ' ';Spread(mine, show, x + around_x, y + around_y);}}//如果是雷就直接在展示棋盘上显示周围有几个雷的数字else{show[x + around_x][y + around_y] = count + '0';}}}}}}
统计被正确标记的雷数
int ClearMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){int i = 0, j = 0;int end = 0;for (i = 1; i <= row; i++){for (j = 1; j <= col; j++){if (mine[i][j] == '1' && show[i][j] == '!')//在雷区棋盘上是雷并且在展示棋盘上是'!'才是被标记的正确的雷end++;}}return end;}
如果玩家把所有的雷标记出来,那么就直接胜利了 。
扫雷的具体过程
void FindMine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col){int n = 0, x = 0, y = 0;int win = 0;//统计被标记的个数(可能被标记的都是雷,也有可能标错)int flag = 0;//falg为0代表未取消标记,为1代表被取消标记//这是我为了方便展示棋盘而设置的int fail = 0;//fail为0代表没有被炸死,为1代表被炸死again:while (win