电商平台网站建设合同,电脑咋建网站,泗县口碑营销互联网营销推荐咨询,wordpress默认模板目录在哪里✨✨欢迎大家来到贝蒂大讲堂✨✨ #x1f388;#x1f388;养成好习惯#xff0c;先赞后看哦~#x1f388;#x1f388; 所属专栏#xff1a;贝蒂的游戏 贝蒂的主页#xff1a;Betty‘s blog 引言#xff1a; 扫雷相信大家小时候到玩过吧#xff0c;那… ✨✨欢迎大家来到贝蒂大讲堂✨✨ 养成好习惯先赞后看哦~ 所属专栏贝蒂的游戏 贝蒂的主页Betty‘s blog 引言 扫雷相信大家小时候到玩过吧那我们通过目前已学的知识自己实现一个扫雷小游戏呢答案自然是肯定的。 本章你可能会用到的知识 1. 数组的使用小小数组给贝蒂坐下 2. 随机数的生成贝蒂的捣蛋小游戏
1. 游戏要求 1. 玩家可以通过菜单选择玩游戏和退出游戏。 2. 默认棋盘为9×9的格子。 3. 默认雷的个数为10。 4可以排查雷 1 如果位置不是雷就显⽰周围有⼏个雷并且循环展开。 2如果位置是雷就炸死游戏结束 3把除10个雷之外的所有⾮雷都找出来排雷成功游戏结束 4玩家可以对认为是雷的位置进行可能是雷或肯定是雷的标记。 2. 游戏分析
1. 我们要在9×9的棋盘上操作自然使用数组模拟并且我们先假设0代表无雷1代表雷
2. 玩家选择一个格子排查如果没雷将显示周围八个格子雷的个数。 为了解决可能得数组越界问题所以尝试在外围增加“一圈”。 3. 但是我们不可能把这个棋盘布置的信息给玩家看所以要创建两个数组一个数组(mine)负责布置雷的信息一个数组(show)负责展现给玩家看。
4. 如果玩家排查的位置没有雷我们将显示周围雷的个数为了不与布置雷的信息冲突所以将无雷改为‘0’有雷改为‘1’。
5. 玩家棋盘初始全为‘*’代表未排查。 3. 多文件操作 为了方便代码的管理和保证游戏实现逻辑的清晰性我们将采用多文件管理的模式。 1创建头文件game.h包含所有头文件(其他源文件只需引用它即可)以及所有游戏功能的展现。 2创建源文件game.c负责所有功能的具体代码实现。 3创建源文件main.c负责展现游戏实现的总体逻辑。
4. 简易菜单的实现 4.1功能 1.玩家可以通过选择1进入游戏0退出游戏。 2.选错的话提醒玩家重新选择。 4.2代码实现 为了完成这些目标我们可以简单的do-while,switch结构实现。 代码如下
void menu()
{printf(****************************\n);printf(******* 1. play ******\n);printf(******* 0. exit ******\n);printf(****************************\n);
}
int main()
{int input 0;srand((unsigned int)time(NULL));//设置时间种子do{menu();//简易菜单的实现printf(请选择:);scanf(%d, input);switch (input){case 1:system(cls);//清空屏幕头文件stdlib.hgame();break;case 0:printf(退出游戏\n);break;default:printf(选择错误重新选择\n);break;}} while (input);//选0结束游戏return 0;
}
5. 游戏功能实现 5.1 预定义信息
#define ROW 9//棋盘的行
#define COL 9//棋盘的列
#define ROWS ROW2//扩展后的行
#define COLS COL2//扩展后的列
#define MINES 10//雷的个数
#includestdio.h
#includestdlib.h
#includetime.h 5.2 初始化棋盘 1要求 1. mine棋盘初始化为全‘0’。 2. show棋盘初始化为全‘1’。 2实现
void InitBoard(char board[ROWS][COLS], int rows ,int cols, char set)
{int i 0;for (i 0; i rows; i){int j 0;for (j 0; j cols; j){board[i][j] set;}}
}
贝蒂说“因为在game.c中实现游戏的具体功能所以千万不要忘了在game.h中声明哦~” 5.3 打印棋盘 1要求 1. 打印出棋盘中的元素。 2. 利用---,|模拟出棋盘框。 3. 显示出每行每列的序号。 2实现
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{printf(-----------------扫雷游戏----------------\n);for (int i 0; i col; i){if (i 0){printf( );//四个空格}else{printf( %d , i);//两个空格一个数字}}printf(\n);for (int i 0; i col; i){if (i 0){printf( |);//三个空格}else{printf(---|);}}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);for (int j 1; j col; j){if (j 1){printf( );//三个空格printf(|---|);}else{printf(---|);}}printf(\n);}printf(-------------------结束线----------------\n);
} 3效果展示 5.4 埋雷 1要求 1.在mine棋盘中随机布置10个雷雷为‘0’。 2.重复位置不能布置。 2实现
void SetMine(char board[ROWS][COLS], int row, int col)
{int num MINES;while (num){int x rand() % row 1;int y rand() % col 1;if (board[x][y] 0){board[x][y] 1;num--;}}
}
3效果展示 5.5 排雷和标记 1要求· 1. 玩家可以选择排雷或者标记。 2. 保证玩家输入的值合法。 3. 对于同一个坐标第一次标记为代表肯定是雷第二次标记为代表可能是雷第三次 标记恢复‘*’。!的数量最多等于雷的数量 4. 标记时统计正确标记雷的个数。 5. 排雷时玩家输入要排除的坐标如果是雷则游戏结束如果不是雷则统计周围雷的个数。 6. 如果周围没有雷则向周围展开至有雷或者有标志位置为止。 贝蒂说“因为布置的雷为‘1’字符在内存中是以ascii码值存储所以统计方法为将周围八个格子值加起来减去8*‘0’。” 2排雷与递归排雷的实现
int GetMineCount(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[x1][y]mine[x 1][y 1] mine[x][y 1] mine[x - 1][y 1] - 8 * 0);
}
void SpreadBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)//递归排雷
{if (x 1 || xROW || y 1 || yCOL)//坐标不合理不递归{return;}if (show[x][y] ! *)//递归结束条件{return;}int count GetMineCount(mine, x, y);if (count 0)//无雷继续扩展{show[x][y] ;//扩建为 SpreadBoard(mine,show, x, y 1);SpreadBoard(mine,show, x, y - 1);SpreadBoard(mine, show, x 1, y - 1);SpreadBoard(mine, show, x 1, y 1);SpreadBoard(mine, show, x 1, y);SpreadBoard(mine, show, x - 1, y 1);SpreadBoard(mine, show, x - 1, y - 1);SpreadBoard(mine, show, x - 1, y);}else{show[x][y] 0 count;//有雷输出个数}
}
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//排查雷
{int x 0;int y 0;printf(请输入你要排查的坐标:);scanf(%d%d, x, y);if (x 1 x row y 1 y col)//坐标要合法{if (show[x][y] ! *){if (show[x][y] ! || show[x][y] ?){printf(该位置已被标记暂时不可排雷\n);}else{printf(该位置已排雷不可重复排雷\n);}}else{if (mine[x][y] 1){return 0;//被炸死}else{SpreadBoard(mine, show, x, y);//递归扩展}}}else{printf(坐标非法\n);}return 1;
} 效果展示 3标记的实现
void MineMark(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col,int *p)
{static int sum 0;//判断的个数if (sum MINES){printf(已满请减少的使用\n);}int x 0, y 0;printf(请输入标记的坐标:);scanf(%d%d, x, y);if (x 1 x row y 1 y col)//输入的坐标数值合法{if (show[x][y] *)//第一次标记{if (sum MINES){show[x][y] !;if (mine[x][y] 1){(*p);//统计标记正确雷的个数}sum;//的个数1}}else if (show[x][y] !)//第二次标记{show[x][y] ?;if (mine[x][y] 1){(*p)--;//标记正确雷的个数减1}sum--;}else if(show[x][y]?)//第三次标记{show[x][y] *;}else{printf(该位置已经排查过不能标记\n);}}else{printf(输入坐标不合法请重新输入\n);}
}
5.6 胜利条件
1要求 1. 成功用‘!’标记所有雷的正确位置游戏胜利。 2. 或者成功排查完除雷外所有格子游戏胜利。 2实现
int IsWin(char board[ROWS][COLS],int row,int col, int* p)
{int count 0;for (int i 1; i row; i)//遍历所有格子看看是否已经排查完{for (int j 1; j col; j){if (board[i][j] ! * board[i][j] ! ! board[i][j] ! ?){count;}}}if (count row * col - MINES||*pMINES)//如果排查完或者成功标记完雷的个数{return 1;//游戏胜利}return 0;
}6. 游戏主逻辑的搭建 6.1搭建顺序 1. 初始化棋盘。 2. 埋雷。 3. 玩家选择标记还是埋雷。 4. 判断玩家是否被炸死。 5. 判断玩家是否胜利。 6.如果步骤4或5未成功执行就重复执行步骤3,4,5。 6.2 实现
void game()
{char mine[ROWS][COLS]; //存放布置好的雷char show[ROWS][COLS]; //展示棋盘InitBoard(mine, ROWS, COLS, 0);InitBoard(show, ROWS, COLS, *);//打印棋盘//DisplayBoard(mine, ROW, COL);//DisplayBoard(show, ROW, COL);//1. 布置雷SetMine(mine, ROW, COL);//DisplayBoard(mine, ROW, COL);//2. 排查雷//FindMine(mine, show, ROW, COL);int input 0;int flag 0;int num -1;while (1){DisplayBoard(show, ROW, COL);choose();printf(请选择排雷或者标记\n);scanf(%d, input);switch (input){case 1:numFindMine(mine, show, ROW, COL);Sleep(900);//停顿0.9秒system(cls);//刷新棋盘break;case 2:MineMark(mine, show, ROW, COL, flag);Sleep(900);system(cls);//刷新棋盘break;default:printf(输入非法情重新输入\n);Sleep(900);system(cls);//刷新棋盘break;}if (num 0)//判断是否被炸死{DisplayBoard(show, ROW, COL);DisplayBoard(mine, ROW, COL);printf(很遗憾你被炸死了\n);break;}int retIsWin(show,ROW,COL,flag);if (ret)//判断是否胜利{DisplayBoard(show, ROW, COL);DisplayBoard(mine, ROW, COL);printf(恭喜你扫雷成功\n);break;}}
} 6.3 补充 为了让玩家正确理解如何进行游戏我们应该提前告诉玩家游戏规则。
void rules()
{printf(游戏规则如下\n);printf(1.你可以通过排雷和标记逐渐逼近胜利条件\n);printf(2.对同一坐标标记1次是!标记2次是?第3次恢复*\n);printf(3.标记!代表肯定是雷标记?代表可能是雷\n);printf(4.标记!的次数最多为雷的个数\n);printf(5.如果选中雷则游戏失败\n);printf(6.当成功标记所有雷或者排查完所有格子游戏胜利\n);
}
7. 源码 1main.c #includegame.h
void menu()
{printf(****************************\n);printf(******* 1. play ******\n);printf(******* 0. exit ******\n);printf(****************************\n);
}
void choose()
{printf(********************************************\n);printf(*************** 1. 排雷 *************\n);printf(*************** 2. 标记 *************\n);printf(********************************************\n);
}
void rules()
{printf(游戏规则如下\n);printf(1.你可以通过排雷和标记逐渐逼近胜利条件\n);printf(2.对同一坐标标记1次是!标记2次是?第3次恢复*\n);printf(3.标记!代表肯定是雷标记?代表可能是雷\n);printf(4.标记!的次数最多为雷的个数\n);printf(5.如果选中雷则游戏失败\n);printf(6.当成功标记所有雷或者排查完所有格子游戏胜利\n);
}
void game()
{char mine[ROWS][COLS]; //存放布置好的雷char show[ROWS][COLS]; //展示棋盘InitBoard(mine, ROWS, COLS, 0);InitBoard(show, ROWS, COLS, *);//打印棋盘//DisplayBoard(mine, ROW, COL);//DisplayBoard(show, ROW, COL);//1. 布置雷SetMine(mine, ROW, COL);//DisplayBoard(mine, ROW, COL);//2. 排查雷//FindMine(mine, show, ROW, COL);int input 0;int flag 0;int num -1;while (1){DisplayBoard(show, ROW, COL);choose();printf(请选择排雷或者标记\n);scanf(%d, input);switch (input){case 1:numFindMine(mine, show, ROW, COL);Sleep(900);//停顿0.9秒system(cls);//刷新棋盘break;case 2:MineMark(mine, show, ROW, COL, flag);Sleep(900);system(cls);//刷新棋盘break;default:printf(输入非法情重新输入\n);Sleep(900);system(cls);//刷新棋盘break;}if (num 0)//判断是否被砸死{DisplayBoard(show, ROW, COL);DisplayBoard(mine, ROW, COL);printf(很遗憾你被炸死了\n);break;}int retIsWin(show,ROW,COL,flag);if (ret){DisplayBoard(show, ROW, COL);DisplayBoard(mine, ROW, COL);printf(恭喜你扫雷成功\n);break;}}
}
int main()
{int input 0;srand((unsigned int)time(NULL));//设置时间种子printf( 欢迎来到贝蒂的扫雷游戏\n);do{menu();//简易菜单的实现rules();printf(请选择:);scanf(%d, input);switch (input){case 1:system(cls);//清空屏幕头文件stdlib.hgame();break;case 0:printf(退出游戏\n);break;default:printf(选择错误重新选择\n);break;}} while (input);//选0结束游戏return 0;
}
2game.h
#define ROW 9//棋盘的行
#define COL 9//棋盘的列
#define ROWS ROW2//扩展后的行
#define COLS COL2//扩展后的列
#define MINES 10//雷的个数
#includestdio.h
#includestdlib.h
#includetime.h
#includewindows.h
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);//初始化棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);//打印棋盘
void SetMine(char board[ROWS][COLS], int row, int col);//布置雷
void MineMark(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int*p);//标记雷
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//排雷
int IsWin(char board[ROWS][COLS],int row,int col,int *p);//判断是否胜利
3game.c
#includegame.h
void InitBoard(char board[ROWS][COLS], int rows ,int cols, char set)
{int i 0;for (i 0; i rows; i){int j 0;for (j 0; j cols; j){board[i][j] set;}}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{printf(-----------------扫雷游戏----------------\n);for (int i 0; i col; i){if (i 0){printf( );//四个空格}else{printf( %d , i);//两个空格一个数字}}printf(\n);for (int i 0; i col; i){if (i 0){printf( |);//三个空格}else{printf(---|);}}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);for (int j 1; j col; j){if (j 1){printf( |);//三个空格printf(---|);}else{printf(---|);}}printf(\n);}printf(-------------------结束线----------------\n);
}
void SetMine(char board[ROWS][COLS], int row, int col)
{int num MINES;while (num){int x rand() % row 1;int y rand() % col 1;if (board[x][y] 0){board[x][y] 1;num--;}}
}
void MineMark(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col,int *p)
{static int sum 0;//判断的个数if (sum MINES){printf(已满请减少的使用\n);}int x 0, y 0;printf(请输入标记的坐标:);scanf(%d%d, x, y);if (x 1 x row y 1 y col)//输入的坐标数值合法{if (show[x][y] *)//第一次标记{if (sum MINES){show[x][y] !;if (mine[x][y] 1){(*p);//统计正确雷的个数}sum;//的个数1}}else if (show[x][y] !)//第二次标记{show[x][y] ?;if (mine[x][y] 1){(*p)--;}sum--;}else if(show[x][y]?)//第三次标记{show[x][y] *;}else{printf(该位置已经排查过不能标记\n);}}else{printf(输入坐标不合法请重新输入\n);}
}
int GetMineCount(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[x1][y]mine[x 1][y 1] mine[x][y 1] mine[x - 1][y 1] - 8 * 0);
}
void SpreadBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)//递归排雷
{if (x 1 || xROW || y 1 || yCOL)//坐标不合理不递归{return;}if (show[x][y] ! *)//递归结束条件{return;}int count GetMineCount(mine, x, y);if (count 0)//无雷继续扩展{show[x][y] ;//扩建为 SpreadBoard(mine,show, x, y 1);SpreadBoard(mine,show, x, y - 1);SpreadBoard(mine, show, x 1, y - 1);SpreadBoard(mine, show, x 1, y 1);SpreadBoard(mine, show, x 1, y);SpreadBoard(mine, show, x - 1, y 1);SpreadBoard(mine, show, x - 1, y - 1);SpreadBoard(mine, show, x - 1, y);}else{show[x][y] 0 count;//有雷输出个数}
}
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//排查雷
{int x 0;int y 0;printf(请输入你要排查的坐标:);scanf(%d%d, x, y);if (x 1 x row y 1 y col)//坐标要合法{if (show[x][y] ! *){if (show[x][y] ! || show[x][y] ?){printf(该位置已被标记暂时不可排雷\n);}else{printf(该位置已排雷不可重复排雷\n);}}else{if (mine[x][y] 1){return 0;//被炸死}else{SpreadBoard(mine, show, x, y);//递归扩展}}}else{printf(坐标非法\n);}return 1;
}
int IsWin(char board[ROWS][COLS],int row,int col, int* p)
{int count 0;for (int i 1; i row; i)//遍历所有格子看看是否已经排查完{for (int j 1; j col; j){if (board[i][j] ! * board[i][j] ! ! board[i][j] ! ?){count;}}}if (count row * col - MINES||*pMINES)//如果排查完或者成功标记完雷的个数{return 1;//游戏胜利}return 0;
}完结撒花完结撒花