中国建设银行福清分行网站,酒类招商网站大全,免费网站管理软件,个人怎么做一个网站扫雷 文章目录 扫雷实现代码什么是扫雷基本功能实现显示选择菜单定义几个二维数组#xff1f;确定数组大小初始化数组布置地雷打印展示数组排查地雷记录指定区域周围地雷的个数判断排雷成功排查地雷实现代码 基本功能的实现代码和效果展示 拓展功能简化游戏界面改变字体颜色实…扫雷 文章目录 扫雷实现代码什么是扫雷基本功能实现显示选择菜单定义几个二维数组确定数组大小初始化数组布置地雷打印展示数组排查地雷记录指定区域周围地雷的个数判断排雷成功排查地雷实现代码 基本功能的实现代码和效果展示 拓展功能简化游戏界面改变字体颜色实现爆炸展开效果实现效果 插旗功能插旗取消所插旗子调整MineFind()函数实现效果 拓展功能实现代码 实现代码
#includestdio.h
#includestdlib.h
#includetime.h
#includeWindows.h
#includestdbool.h#define ROW 9
#define COL 9
#define ROWS ROW 2
#define COLS COL 2
#define MINENUMBER 10void BoardInit(char board[][COLS], int row, int col, char set);
void BoardDisplay(char board[][COLS], int row, int col);
void MineSet(char board[][COLS], int row, int col);
int MineNumber(char board[][COLS], int x, int y);
void MineFind(char mine[][COLS], char show[][COLS], int row, int col);
bool MineFinish(char board[][COLS], int row, int col);
void Explode(char mine[][COLS], char show[][COLS], int x, int y);
void Flag_In(char show[][COLS]);
void Flag_Out(char show[][COLS]);void meau()
{printf(****************\n);printf(*****1.Play*****\n);printf(*****0.Exit*****\n);printf(****************\n);
}void game()
{//生成时间戳srand((unsigned int)time(NULL));//定义存放地雷的数组和展示结果的数组char mineBoard[ROWS][COLS];char showBoard[ROWS][COLS];//对两个数组进行初始化BoardInit(mineBoard, ROWS, COLS, 0);BoardInit(showBoard, ROWS, COLS, *);//设置地雷MineSet(mineBoard, ROW, COL);//BoardDisplay(mineBoard, ROW, COL);BoardDisplay(showBoard, ROW, COL);//排查地雷MineFind(mineBoard, showBoard, ROW, COL);
}void BoardInit(char board[][COLS], int row, int col, char set)
{for (int i 0; i row; i)for (int j 0; j col; j)board[i][j] set;
}void BoardDisplay(char board[][COLS], int row, int col)
{for (int i 0; i col; i){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4 | 16);printf(%d , i);}printf(\n);for (int i 1; i row; i){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4 | 16);printf(%d , i);for (int j 1; j col; j){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7 | 16);if(board[i][j] $)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 6 | 16);printf(%c , board[i][j]);}printf(\n);}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7 | 16);
}void MineSet(char board[][COLS], int row, int col)
{int count 0;while (count MINENUMBER){int x rand() % row 1;int y rand() % col 1;if (board[x][y] 0){board[x][y] 1;count;}}
}void MineFind(char mine[][COLS], char show[][COLS], int row, int col)
{int x, y;char ch;while (1){printf(请输入您要排查的坐标用空格分隔);scanf_s(%d %d, x, y);system(cls);if (show[x][y] * x 0 x row y 0 y col){if (mine[x][y] 1){printf(很遗憾排雷失败\n);BoardDisplay(mine, row, col);return;}else{Explode(mine, show, x, y);if (MineFinish(show, row,col)){printf(恭喜你排雷成功\n);BoardDisplay(mine, row, col);return;}BoardDisplay(show, row, col);getchar();printf(是否需要插旗Y/N\n);if((ch getchar()) Y)Flag_In(show);getchar();printf(是否需要取消所插的旗子Y/N\n);if ((ch getchar()) Y)Flag_Out(show);}}else if (show[x][y] ! * x 0 x row y 0 y col){printf(该位置已经被检查请重新输入\n);BoardDisplay(show, row, col);}else{printf(坐标非法请重新输入\n);BoardDisplay(show, row, col);}}
}int MineNumber(char board[][COLS], int x, int y)
{return (board[x][y - 1] board[x][y 1] board[x - 1][y] board[x - 1][y - 1] board[x - 1][y 1] board[x 1][y] board[x 1][y - 1] board[x 1][y 1]- 8 * 0);
}bool MineFinish(char board[][COLS], int row, int col)
{int count 0;for(int i 1; i row; i)for (int j 1; j col; j){if (board[i][j] ! *){count;if (count row * col - MINENUMBER)return true;}}return false;
}void Explode(char mine[][COLS], char show[][COLS], int x, int y)
{if (show[x][y] || x 1 || y 1 || x ROW || y COL)return;if (MineNumber(mine, x, y) 0)show[x][y] ;else{show[x][y] MineNumber(mine, x, y) 0;return;}Explode(mine, show, x, y - 1);Explode(mine, show, x, y 1);Explode(mine, show, x 1, y 1);Explode(mine, show, x 1, y);Explode(mine, show, x 1, y - 1);Explode(mine, show, x - 1, y 1);Explode(mine, show, x - 1, y - 1);Explode(mine, show, x - 1, y);
}void Flag_In(char show[][COLS])
{int row 0, col 0;printf(您想在哪个位置插入旗子:\n);printf(注用空格分隔输入0 0结束插旗\n);while(1){scanf_s(%d %d, row, col);if (row 0 col 0)break;if (row 1 || row ROW || col 1 || col COL){printf(坐标非法重新输入);continue;}else if (show[row][col] ! *)printf(给位置不能插旗\n);else{system(cls);show[row][col] $;BoardDisplay(show, ROW, COL);}}
}void Flag_Out(char show[][COLS])
{int row, col;printf(您想取消哪个位置的旗子:\n);printf(注用空格分隔输入0 0结束\n);while (1){scanf_s(%d %d, row, col);if (row 0 col 0)break;if (row 1 || row ROW || col 1 || col COL){printf(坐标非法重新输入);continue;}else if (show[row][col] ! $)printf(该位置不是旗子\n);else{system(cls);show[row][col] *;BoardDisplay(show, ROW, COL);}}
}int main()
{system(color 17);int input;meau();printf(请输入您的选择);while (1){scanf_s(%d, input);switch (input){case 1:game();break;case 0:printf(退出游戏感谢游玩\n);break;default :printf(输入错误请重新输入:);break;}meau();printf(是否重新游玩);}return 0;
}什么是扫雷 要用代码来实现扫雷这个小游戏我们就需要先了解扫雷这个游戏的规则和有关操作。 我们先来看一段扫雷游戏的动画 游戏目标在N*N的区域中找到M个随机布置的地雷 若点击的区域不是雷那么就会显示一个数字这个数字代表着这块区域周围雷的个数 若点击的区域是雷那么就表示排雷失败游戏结束
基本功能实现
显示选择菜单 游戏的最开始我们需要提醒用户如何进行游戏以及如何退出游戏 我们可以用以下代码实现 #includestdio.hvoid meau()
{printf(****************\n);printf(*****1.Play*****\n);printf(*****0.Exit*****\n);printf(****************\n);
}int main()
{int input;meau();printf(请输入您的选择);while (1){scanf_s(%d, input);switch (input){case 1:game(); //实现扫雷的函数break;case 0:printf(退出游戏感谢游玩\n);break;default :printf(输入错误请重新输入:);break;}meau();printf(是否重新游玩);}return 0;
}定义几个二维数组 假设游戏区域为大小为N*N的正方形区域 可以明确的是我们需要用一个二维数组来存放这N*N个位置的信息那我们还需不需要定义其他数组呢 根据上面的动画我们可以看到游玩游戏时系统展示给我们的是一个空白的未知区域而没有将这片区域存放的数据即地雷的位置展示给我们因此我们还需要定义一个二维数组用来对用户展示其排查的结果。
确定数组大小 二维数组的大小为多少合适呢可能有小伙伴认为定义一个长宽都为N的二维数组不就行了吗其实这不是最优解我们先将这个问题放一边先来看看我们是如何记录一块区域周围雷的个数的 假设我们要排查的坐标是(X,Y)那么它周围的区域就是这八个坐标(X,Y-1), (X,Y1), (X1,Y), (X1,Y1), (X1,Y-1), (X-1,Y), (X-1,Y1), (X-1,Y-1)如图所示 我们要查看这八个坐标区域是否是雷并记录 那么问题来了如果我们排查的是如下图画线区域的坐标呢假设我们定义的是长宽都为N的二维数组那么当我们排查(0,0),(0,1),(1,0)……这些边界坐标时就会出现数组越界的情况因此我们就有必要适当的扩大。 我们可以将二维数组的长和宽各增加两行/列但有效区域仍然是大小为N*N的区域这样当我们排查原本是边界坐标时就不会出现数组越界的情况了。 为了保证操作的一致性我们也将展示数组的大小定义为(N2)*(N2) /*ROWCOL即真实的区域大小ROWS,COLS即扩容后的大小
*/
#define ROW 9
#define COL 9
#define ROWS ROW 2
#define COLS COL 2void game()
{//定义存放地雷的数组和展示结果的数组//此时[1,ROW]为横纵坐标的有效取值char mineBoard[ROWS][COLS];char showBoard[ROWS][COLS];
}初始化数组 我们规定两个数组都是字符数组 用字符‘1’代表地雷字符‘0’代表非地雷具体原因会在后面讲到 将展示数组全部初始化为‘*’代表未知 /*rowcol即传入数组的行数和列数这里row ROWScol COLS因为要将扩容的区域初始化为没有地雷的状态 set即要初始化的字符
*/
void BoardInit(char board[][COLS], int row, int col, char set)
{for (int i 0; i row; i)for (int j 0; j col; j)board[i][j] set;
}布置地雷 假设我们要随机布置MINENUMBER个地雷 既然涉及到了“随机”这一概念那么显然我们就要用到随机数这一概念 我们可以利用循环在循环里随机生成地雷的坐标只要这个坐标没被布置过地雷即这个坐标代表的字符不是‘1’那么就在这个坐标布置地雷 /*这里row ROWcol COL因为地雷不会被布置在扩容区域扩容区域只是为了方便记录边界区域周围的地雷个数
*/
void MineSet(char board[][COLS], int row, int col)
{int count 0;while (count MINENUMBER){int x rand() % row 1;int y rand() % col 1;if (board[x][y] 0){board[x][y] 1;count;}}
}打印展示数组 布置完地雷后我们就需要打印出展示数组方便用户进行扫雷 为了方便用户确定要排查区域的位置我们可以顺便打印出展示数组的行数和列数如图 /*这里row ROWcol COL扩容区域不需要排查扩容区域只是为了方便记录边界区域周围的地雷个数
*/
void BoardDisplay(char board[][COLS], int row, int col)
{for (int i 0; i col; i)printf(%d , i);printf(\n);for (int i 1; i row; i){printf(%d , i);for (int j 1; j col; j)printf(%c , board[i][j]);printf(\n);}
}排查地雷
接下来就需要用户排查地雷了我们利用循环提醒用户输入要排查的坐标有以下五种情况 如果排查的坐标是雷那么直接退出game()函数表示排雷失败如果排雷失败那么就要向用户展示存放雷的数组让用户明白到底错在了哪如果排查的坐标已经被检查过那么提醒用户重新输入如果排查的坐标非法那么提醒用户重新输入如果排查的坐标不是雷并且还未排雷完毕那么显示该区域周围有几个雷继续循环如果排查的坐标不是雷并且所有雷已经排查完毕那么退出game()函数表示排雷成功 每排查完一次都要重新打印一次展示数组
记录指定区域周围地雷的个数 上面我们讲到要确定一个指定坐标(X,Y)周围地雷的个数只需要查看(X,Y-1), (X,Y1), (X1,Y), (X1,Y1), (X1,Y-1), (X-1,Y), (X-1,Y1), (X-1,Y-1)这八个坐标的值 前面我们已经假设字符‘1’代表地雷字符‘0’代表非地雷由于字符‘0’的ASCII的值为48字符‘1’的ASCII值为49比字符‘0’大一那么我们统计(X,Y)周围地雷的个数就只需要将周围八个坐标储存的值相加然后减去8个字符‘0’即可 这也是将字符‘1’设置为地雷字符‘0’设置为非地雷的巧妙之处可以在计算地雷个数的时候少去很多操作 /*这里row ROWScol COLS这样可以确保排查任意区域操作的一致性数组不会越界
*/
int MineNumber(char board[][COLS], int x, int y)
{return (board[x][y - 1] board[x][y 1] board[x - 1][y] board[x - 1][y - 1] board[x - 1][y 1] board[x 1][y] board[x 1][y - 1] board[x 1][y 1]- 8 * 0);
}判断排雷成功 如果被排查完的区域的总个数等于整块区域的个数减去地雷个数那就说明排雷成功 /*传入的是展示数组showBoard这里row ROWcol COL扩容区域不需要排查扩容区域只是为了方便记录边界区域周围的地雷个数
*/
//如果排雷成功就返回真否则返回假
bool MineFinish(char board[][COLS], int row, int col)
{int count 0; //count用来记录已经排查的区域的个数for(int i 1; i row; i)for (int j 1; j col; j){if (board[i][j] ! *){count;if (count row * col - MINENUMBER) //MINENUMBER就是地雷总个数return true;}}return false;
}排查地雷实现代码
void MineFind(char mine[][COLS], char show[][COLS], int row, int col)
{int x, y;while (1){printf(请输入您要排查的坐标用空格分隔);scanf_s(%d %d, x, y);//如果排查的区域未被检查并且坐标合法if (show[x][y] * x 0 x row y 0 y col){//如果踩到了雷if (mine[x][y] 1){printf(很遗憾排雷失败\n);BoardDisplay(mine, row, col);return;}//否则继续排雷else{show[x][y] MineNumber(mine, x, y) 0;//if (MineFinish(show, row,col)){printf(恭喜你排雷成功\n);BoardDisplay(mine, row, col);return;}BoardDisplay(show, row, col);}}//如果排查的区域合法但已经被检查else if (show[x][y] ! * x 0 x row y 0 y col){printf(该位置已经被检查请重新输入\n);BoardDisplay(show, row, col);}//如果排查的区域不合法 else{printf(坐标非法请重新输入\n);BoardDisplay(show, row, col);}}
}基本功能的实现代码和效果展示 我们先来看看实现效果 实现代码 #includestdio.h
#includestdlib.h
#includetime.h
#includestdbool.h#define ROW 9
#define COL 9
#define ROWS ROW 2
#define COLS COL 2
#define MINENUMBER 10void BoardInit(char board[][COLS], int row, int col, char set);
void BoardDisplay(char board[][COLS], int row, int col);
void MineSet(char board[][COLS], int row, int col);
int MineNumber(char board[][COLS], int x, int y);
void MineFind(char mine[][COLS], char show[][COLS], int row, int col);
bool MineFinish(char board[][COLS], int row, int col);void meau()
{printf(****************\n);printf(*****1.Play*****\n);printf(*****0.Exit*****\n);printf(****************\n);
}void game()
{//生成时间戳srand((unsigned int)time(NULL));//定义存放地雷的数组和展示结果的数组char mineBoard[ROWS][COLS];char showBoard[ROWS][COLS];//对两个数组进行初始化BoardInit(mineBoard, ROWS, COLS, 0);BoardInit(showBoard, ROWS, COLS, *);//设置地雷MineSet(mineBoard, ROW, COL);//打印展示数组BoardDisplay(showBoard, ROW, COL);//排查地雷MineFind(mineBoard, showBoard, ROW, COL);
}void BoardInit(char board[][COLS], int row, int col, char set)
{for (int i 0; i row; i)for (int j 0; j col; j)board[i][j] set;
}void BoardDisplay(char board[][COLS], int row, int col)
{for (int i 0; i col; i)printf(%d , i);printf(\n);for (int i 1; i row; i){printf(%d , i);for (int j 1; j col; j)printf(%c , board[i][j]);printf(\n);}
}void MineSet(char board[][COLS], int row, int col)
{int count 0;while (count MINENUMBER){int x rand() % row 1;int y rand() % col 1;if (board[x][y] 0){board[x][y] 1;count;}}
}void MineFind(char mine[][COLS], char show[][COLS], int row, int col)
{int x, y;while (1){printf(请输入您要排查的坐标用空格分隔);scanf_s(%d %d, x, y);if (show[x][y] * x 0 x row y 0 y col){if (mine[x][y] 1){printf(很遗憾排雷失败\n);BoardDisplay(mine, row, col);return;}else{show[x][y] MineNumber(mine, x, y) 0;if (MineFinish(show, row,col)){printf(恭喜你排雷成功\n);BoardDisplay(mine, row, col);return;}BoardDisplay(show, row, col);}}else if (show[x][y] ! * x 0 x row y 0 y col){printf(该位置已经被检查请重新输入\n);BoardDisplay(show, row, col);}else{printf(坐标非法请重新输入\n);BoardDisplay(show, row, col);}}
}int MineNumber(char board[][COLS], int x, int y)
{return (board[x][y - 1] board[x][y 1] board[x - 1][y] board[x - 1][y - 1] board[x - 1][y 1] board[x 1][y] board[x 1][y - 1] board[x 1][y 1]- 8 * 0);
}bool MineFinish(char board[][COLS], int row, int col)
{int count 0;for(int i 1; i row; i)for (int j 1; j col; j){if (board[i][j] ! *){count;if (count row * col - MINENUMBER)return true;}}return false;
}int main()
{int input;meau(); //展示选择菜单printf(请输入您的选择);while (1){scanf_s(%d, input);switch (input){case 1:game();break;case 0:printf(退出游戏感谢游玩\n);break;default :printf(输入错误请重新输入:);break;}meau();printf(是否重新游玩);}return 0;
}拓展功能
简化游戏界面 根据上面的展示我们可以看到我们每排查一次展示数组就要打印一次这样就会使得游戏界面太过复杂 我们可以使用system(“cls”)函数来清除已经不需要的打印结果 注要包含头文件Windows.h 修改后的MineFind()函数 void MineFind(char mine[][COLS], char show[][COLS], int row, int col)
{int x, y;while (1){printf(请输入您要排查的坐标用空格分隔);scanf_s(%d %d, x, y);//就是多了这样一条语句system(cls);if (show[x][y] * x 0 x row y 0 y col){if (mine[x][y] 1){printf(很遗憾排雷失败\n);BoardDisplay(mine, row, col);return;}else{show[x][y] MineNumber(mine, x, y) 0;if (MineFinish(show, row,col)){printf(恭喜你排雷成功\n);BoardDisplay(mine, row, col);return;}BoardDisplay(show, row, col);}}else if (show[x][y] ! * x 0 x row y 0 y col){printf(该位置已经被检查请重新输入\n);BoardDisplay(show, row, col);}else{printf(坐标非法请重新输入\n);BoardDisplay(show, row, col);}}
}实现效果
改变字体颜色 为了将坐标数字和代表地雷个数的数字作出区分我们可以改变这两种数字的颜色 如果对如何改变字体颜色和背景色还不是太了解可以先看看C语言——修改控制台背景色和字体颜色这篇博客 直接上代码只需要调整打印数组的函数BoardDisplay且在主函数最开始加上system(“color”)函数即可 int main()
{system(color 17);………………;
}void BoardDisplay(char board[][COLS], int row, int col)
{for (int i 0; i col; i){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4 | 16);printf(%d , i);}printf(\n);for (int i 1; i row; i){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4 | 16);printf(%d , i);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7 | 16);for (int j 1; j col; j)printf(%c , board[i][j]);printf(\n);}
}看看效果
实现爆炸展开效果 我们看到网页版的扫雷中会出现点击一个区域就自动展开一片区域的情况如图 要实现这一功能那我们首先就需要知道什么条件下才会出现爆炸展开的情况。 展开条件如果排查的坐标(X,Y)周围地雷的总个数是0既没有地雷那么就自动排查它周围的八个区域即坐标(X,Y-1), (X,Y1), (X1,Y), (X1,Y1), (X1,Y-1), (X-1,Y), (X-1,Y1), (X-1,Y-1)对这八个坐标执行同样的操作不断递归直达每个区域的周围都至少有一个地雷找到爆炸展开的边界 实现这个功能要注意以下几点 注意递归时数组不要越界注意递归时排查重复递归的情况如果排查区域周围地雷的个数为0那么为了界面的简洁就不再将0打印出改为打印空格 Explode()的实现代码 //x,y即用户输入的排查坐标
void Explode(char mine[][COLS], char show[][COLS], int x, int y)
{//如果该位置已经配排查重复递归或坐标无效那么退出这个函数不是结束递归if (show[x][y] || x 1 || y 1 || x ROW || y COL)return;//如果该位置周围的地雷个数为0那么符合递归条件继续排查if (MineNumber(mine, x, y) 0)show[x][y] ;//如果坐标有效但周围的地雷个数不为零那么退出这个函数不是结束递归else{show[x][y] MineNumber(mine, x, y) 0;return;}//自动排查(X,Y)周围的8个坐标Explode(mine, show, x, y - 1);Explode(mine, show, x, y 1);Explode(mine, show, x 1, y 1);Explode(mine, show, x 1, y);Explode(mine, show, x 1, y - 1);Explode(mine, show, x - 1, y 1);Explode(mine, show, x - 1, y - 1);Explode(mine, show, x - 1, y);
}要对MineFind()函数做出相应的修改 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7sF9UEGD-1686494176819)(C:/Users/HUASHUO/Desktop/扫雷.5.gif)]void MineFind(char mine[][COLS], char show[][COLS], int row, int col)
{int x, y;while (1){printf(请输入您要排查的坐标用空格分隔);scanf_s(%d %d, x, y);system(cls);if (show[x][y] * x 0 x row y 0 y col){if (mine[x][y] 1){printf(很遗憾排雷失败\n);BoardDisplay(mine, row, col);return;}else{Explode(mine, show, x, y);if (MineFinish(show, row,col)){printf(恭喜你排雷成功\n);BoardDisplay(mine, row, col);return;}BoardDisplay(show, row, col);}}else if (show[x][y] ! * x 0 x row y 0 y col){printf(该位置已经被检查请重新输入\n);BoardDisplay(show, row, col);}else{printf(坐标非法请重新输入\n);BoardDisplay(show, row, col);}}
}实现效果 插旗功能
我们假设旗子的标志是字符‘$’注用户如果在一个区域插上旗子就说明用户认为这个区域是雷即插旗是为了方便用户排雷实现逻辑并不复杂至少需要注意细节的处理
插旗
void Flag_In(char show[][COLS])
{int row 0, col 0;printf(您想在哪个位置插入旗子:\n);printf(注用空格分隔输入0 0结束插旗\n);while(1){scanf_s(%d %d, row, col);if (row 0 col 0)break;if (row 1 || row ROW || col 1 || col COL){printf(坐标非法重新输入);continue;}else if (show[row][col] ! *)printf(该位置不能插旗\n);else{system(cls);count; //旗子数目加一show[row][col] $;BoardDisplay(show, ROW, COL);}}while (getchar() ! \n); //清空缓冲区
}取消所插旗子
void Flag_Out(char show[][COLS])
{int row, col;printf(您想取消哪个位置的旗子:\n);printf(注用空格分隔输入0 0结束\n);while (1){scanf_s(%d %d, row, col);if (row 0 col 0)break;if (row 1 || row ROW || col 1 || col COL){printf(坐标非法重新输入);continue;}else if (show[row][col] ! $)printf(该位置不是旗子\n);else{system(cls);show[row][col] *;BoardDisplay(show, ROW, COL);}}
}调整MineFind()函数
void MineFind(char mine[][COLS], char show[][COLS], int row, int col)
{int x, y;char ch;while (1){printf(请输入您要排查的坐标用空格分隔);scanf_s(%d %d, x, y);system(cls);if (show[x][y] * x 0 x row y 0 y col){if (mine[x][y] 1){printf(很遗憾排雷失败\n);BoardDisplay(mine, row, col);return;}else{Explode(mine, show, x, y);if (MineFinish(show, row,col)){printf(恭喜你排雷成功\n);BoardDisplay(mine, row, col);return;}BoardDisplay(show, row, col);getchar();printf(是否需要插旗Y/N\n);if((ch getchar()) Y)Flag_In(show);getchar();printf(是否需要取消所插的旗子Y/N\n);if ((ch getchar()) Y)Flag_Out(show);}}else if (show[x][y] ! * x 0 x row y 0 y col){printf(该位置已经被检查请重新输入\n);BoardDisplay(show, row, col);}else{printf(坐标非法请重新输入\n);BoardDisplay(show, row, col);}}
}实现效果 拓展功能实现代码
#includestdio.h
#includestdlib.h
#includetime.h
#includeWindows.h
#includestdbool.h#define ROW 9
#define COL 9
#define ROWS ROW 2
#define COLS COL 2
#define MINENUMBER 10void BoardInit(char board[][COLS], int row, int col, char set);
void BoardDisplay(char board[][COLS], int row, int col);
void MineSet(char board[][COLS], int row, int col);
int MineNumber(char board[][COLS], int x, int y);
void MineFind(char mine[][COLS], char show[][COLS], int row, int col);
bool MineFinish(char board[][COLS], int row, int col);
void Explode(char mine[][COLS], char show[][COLS], int x, int y);
void Flag_In(char show[][COLS]);
void Flag_Out(char show[][COLS]);void meau()
{printf(****************\n);printf(*****1.Play*****\n);printf(*****0.Exit*****\n);printf(****************\n);
}void game()
{//生成时间戳srand((unsigned int)time(NULL));//定义存放地雷的数组和展示结果的数组char mineBoard[ROWS][COLS];char showBoard[ROWS][COLS];//对两个数组进行初始化BoardInit(mineBoard, ROWS, COLS, 0);BoardInit(showBoard, ROWS, COLS, *);//设置地雷MineSet(mineBoard, ROW, COL);//BoardDisplay(mineBoard, ROW, COL);BoardDisplay(showBoard, ROW, COL);//排查地雷MineFind(mineBoard, showBoard, ROW, COL);
}void BoardInit(char board[][COLS], int row, int col, char set)
{for (int i 0; i row; i)for (int j 0; j col; j)board[i][j] set;
}void BoardDisplay(char board[][COLS], int row, int col)
{for (int i 0; i col; i){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4 | 16);printf(%d , i);}printf(\n);for (int i 1; i row; i){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4 | 16);printf(%d , i);for (int j 1; j col; j){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7 | 16);if(board[i][j] $)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 6 | 16);printf(%c , board[i][j]);}printf(\n);}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7 | 16);
}void MineSet(char board[][COLS], int row, int col)
{int count 0;while (count MINENUMBER){int x rand() % row 1;int y rand() % col 1;if (board[x][y] 0){board[x][y] 1;count;}}
}void MineFind(char mine[][COLS], char show[][COLS], int row, int col)
{int x, y;char ch;while (1){printf(请输入您要排查的坐标用空格分隔);scanf_s(%d %d, x, y);system(cls);if (show[x][y] * x 0 x row y 0 y col){if (mine[x][y] 1){printf(很遗憾排雷失败\n);BoardDisplay(mine, row, col);return;}else{Explode(mine, show, x, y);if (MineFinish(show, row,col)){printf(恭喜你排雷成功\n);BoardDisplay(mine, row, col);return;}BoardDisplay(show, row, col);getchar();printf(是否需要插旗Y/N\n);if((ch getchar()) Y)Flag_In(show);getchar();printf(是否需要取消所插的旗子Y/N\n);if ((ch getchar()) Y)Flag_Out(show);}}else if (show[x][y] ! * x 0 x row y 0 y col){printf(该位置已经被检查请重新输入\n);BoardDisplay(show, row, col);}else{printf(坐标非法请重新输入\n);BoardDisplay(show, row, col);}}
}int MineNumber(char board[][COLS], int x, int y)
{return (board[x][y - 1] board[x][y 1] board[x - 1][y] board[x - 1][y - 1] board[x - 1][y 1] board[x 1][y] board[x 1][y - 1] board[x 1][y 1]- 8 * 0);
}bool MineFinish(char board[][COLS], int row, int col)
{int count 0;for(int i 1; i row; i)for (int j 1; j col; j){if (board[i][j] ! *){count;if (count row * col - MINENUMBER)return true;}}return false;
}void Explode(char mine[][COLS], char show[][COLS], int x, int y)
{if (show[x][y] || x 1 || y 1 || x ROW || y COL)return;if (MineNumber(mine, x, y) 0)show[x][y] ;else{show[x][y] MineNumber(mine, x, y) 0;return;}Explode(mine, show, x, y - 1);Explode(mine, show, x, y 1);Explode(mine, show, x 1, y 1);Explode(mine, show, x 1, y);Explode(mine, show, x 1, y - 1);Explode(mine, show, x - 1, y 1);Explode(mine, show, x - 1, y - 1);Explode(mine, show, x - 1, y);
}void Flag_In(char show[][COLS])
{int row 0, col 0;printf(您想在哪个位置插入旗子:\n);printf(注用空格分隔输入0 0结束插旗\n);while(1){scanf_s(%d %d, row, col);if (row 0 col 0)break;if (row 1 || row ROW || col 1 || col COL){printf(坐标非法重新输入);continue;}else if (show[row][col] ! *)printf(给位置不能插旗\n);else{system(cls);show[row][col] $;BoardDisplay(show, ROW, COL);}}
}void Flag_Out(char show[][COLS])
{int row, col;printf(您想取消哪个位置的旗子:\n);printf(注用空格分隔输入0 0结束\n);while (1){scanf_s(%d %d, row, col);if (row 0 col 0)break;if (row 1 || row ROW || col 1 || col COL){printf(坐标非法重新输入);continue;}else if (show[row][col] ! $)printf(该位置不是旗子\n);else{system(cls);show[row][col] *;BoardDisplay(show, ROW, COL);}}
}int main()
{system(color 17);int input;meau();printf(请输入您的选择);while (1){scanf_s(%d, input);switch (input){case 1:game();break;case 0:printf(退出游戏感谢游玩\n);break;default :printf(输入错误请重新输入:);break;}meau();printf(是否重新游玩);}return 0;
}