【C语言】扫雷高级版:可进行展开

    xiaoxiao2022-07-13  153

      这次是写一个扫雷的小游戏,可实现周围没雷时展开和第一次排雷不被炸死(防止欧皇直接暴毙!)。

    首先我们先梳理代码思路:

    1、既然要展示和布雷,所以我们需要2个二维数组,一个用来展示给观众,一个显示雷利于我们编程,我们将雷数组初始化为 0 ,将展示的数组初始化为 * ,保持神秘~ 2、我们需要将雷布置到雷数组中去,当然是随机布置; 3、我们还需要一个安全函数,就是当第一次排雷的时候不被炸死;(就是如果第一次排的是雷,就将此位置的雷转移) 4、排雷的过程,包括了如何展开,还有表明旁边有几颗雷;

    1、初始化数组(mine和show),而且为了边上的坐标也能排雷,所以需要建的数组要比棋盘多两行两列。然后就是初始化数组(mine初始化为字符0,show初始化为 *)

    void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } }

    2、打印数组,当然要都打印出来以便我们测试(为了排雷方便,我们给数组加上了序号)

    void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("----------------------------------\n"); for (i = 0; i <= col; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("----------------------------------\n"); }

    3、将雷布置到 mine数组中去,这里我们需要用到随机数,我们用的是rand()这个函数来产生随机数,当然范围要控制在数组范围中

    void SetMine(char mine[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int count = EASY_COUNT; while (count) { x = rand() % row + 1; y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } }

    4、安全函数,这个函数的作用是保证我们第一次排雷不被炸死…

    void SafeMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col) { int ret = 1; int x = 0; int y = 0; int count = 0; printf("请输入你要排查的坐标:"); scanf("%d%d", &x,&y); if (mine[x][y] == '1') { mine[x][y] = '0'; count = GetMine(mine, x, y); show[x][y] = count + '0'; while (ret) { if (mine[x][y] == '1') { int m = rand() % 9 + 1; int n = rand() % 9 + 1; mine[x][y] = '0'; mine[m][n] = '1'; } ret--; } } OpenMine(mine, show, row, col,x,y); DisplayBoard(show, row, col); }

    5、最后就是排雷的过程了,展开函数也在里面(展开函数是用递归来完成的)

    void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; int count = 0; while (1) { printf("请输入要排查的坐标:"); scanf("%d%d", &x, &y); if (x >= 0 && x <= row && y >= 0 && y <= col) { if (mine[x][y] == '1') { printf("很遗憾,你被炸死了!\n"); DisplayBoard(mine, row, col); break; } else { count = GetMine(mine, x, y); show[x][y] = count+'0'; OpenMine(mine, show, row, col, x, y); DisplayBoard(show, row, col); if (MyWin(show,row,col) == EASY_COUNT) { break; } } } else { printf("坐标非法,请重新输入!\n"); } } if (MyWin(show, row, col) == EASY_COUNT) { printf("恭喜你排雷成功!\n"); DisplayBoard(mine, row, col); } } void OpenMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y) { int ret = 0; ret = GetMine(mine, x, y); if (ret == 0) { show[x][y] = ' '; if (x - 1>0 && y>0 && show[x - 1][y] == '*') OpenMine(mine, show, row, col, x - 1, y); if (x - 1>0 && y + 1 <= col && show[x - 1][y + 1] == '*') OpenMine(mine, show, row, col, x - 1, y + 1); if (x>0 && y + 1 <= col && show[x][y + 1] == '*') OpenMine(mine, show, row, col, x, y + 1); if (x + 1 <= row && y + 1 <= col && show[x + 1][y + 1] == '*') OpenMine(mine, show, row, col, x + 1, y + 1); if (x + 1 <= row && y>0 && show[x + 1][y] == '*') OpenMine(mine, show, row, col, x + 1, y); if (x + 1 <= row && y - 1>0 && show[x + 1][y - 1] == '*') OpenMine(mine, show, row, col, x + 1, y - 1); if (x>0 && y - 1>0 && show[x][y - 1] == '*') OpenMine(mine, show, row, col, x, y - 1); if (x - 1>0 && y - 1>0 && show[x - 1][y - 1] == '*') OpenMine(mine, show, row, col, x - 1, y - 1); } else { show[x][y] = GetMine(mine, x, y) + '0'; } }

    6、其中有一个GetMine函数是用来统计周围有多少雷,这个函数写的很巧妙,这也是我们为什么非要设计0和1作为雷数组

    int GetMine(char mine[ROWS][COLS], int x, int y) { return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + + mine[x + 1][y + 1] + mine[x][y + 1] + + mine[x - 1][y + 1] - 8 * '0'; }

    总结:这个游戏总体来说不是很难,难点就在于展开的那里,是用递归来进行完成的,总体设计和三子棋的界面一样,我们需要注意的就是雷的布置和雷的统计还有雷的展开。

    最新回复(0)