网站页脚怎么做能好看点,怎么访问域名网站,外贸网站风格,网站推广计划怎么做大家好#xff0c;我是深鱼~ 目录
一、游戏介绍
二、文件分装 三、代码实现步骤
1.制作简易游戏菜单 2. 初始化棋盘(11*11) 3.打印棋盘(9*9)
4.布置雷 5.计算(x,y)周围8个坐标的和
6.排查雷 1清屏后打印棋盘
2递归展开
3标记雷
四、完整代… 大家好我是深鱼~ 目录
一、游戏介绍
二、文件分装 三、代码实现步骤
1.制作简易游戏菜单 2. 初始化棋盘(11*11) 3.打印棋盘(9*9)
4.布置雷 5.计算(x,y)周围8个坐标的和
6.排查雷 1清屏后打印棋盘
2递归展开
3标记雷
四、完整代码
game.h:相关函数的声明整个代码要引用的头文件以及宏定义 game.c:实现游戏相关的函数
test.c:整个游戏相关的测试 五、游戏展示 一、游戏介绍 《扫雷》是一款大众类的益智小游戏于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子同时避免踩雷踩到一个雷即全盘皆输 排查雷的规则 1.如果这个位置不是雷就计算这个位置周围8个坐标有几个雷并显示雷的个数 2.如果这个位置是雷就炸死了表示游戏结束 3.如果把不是雷的位置都找出来了那就通过了 二、文件分装 实现这个扫雷游戏我创建了三个文件 源文件 test.c:整个游戏相关的测试 game.c:实现游戏相关的函数 头文件: game.h:相关函数的声明整个代码要引用的头文件以及宏定义 三、代码实现步骤
1.制作简易游戏菜单
这个简易菜单和上一篇文章三字棋一样就不做过多的解释了 test.c void menu()//打印简易菜单
{printf(************************************\n);printf(************ 1.进入游戏 **********\n);printf(************ 0.退出游戏 **********\n);printf(************************************\n);
}
int main()
{int input 0;srand((unsigned int)time(NULL));//空指针NULLdo{menu();printf(请选择);scanf(%d, input);switch (input){case 1:game();break;case 0:printf(退出游戏\n);break;default:printf(输入错误请重新输入\n);break;}} while (input);//注意这里要加上;return 0;
} 2. 初始化棋盘(11*11)
(1)定义两个数组为11*11
定义一个数组(mine数组)表示雷的信息1表示这个坐标是雷0表示不是雷另一个数组(show数组)表示排查雷的信息
假设我们要实现一个9*9的棋盘如果我们只定义一个9*9的二维数组计算周围8个坐标会越界那么我们就需要将数组扩大成11*11的二维数组上下左右分别多一排
(2)为了简洁传一个参数char set表示初始化的字符
初始化棋盘(9*9的外部也要初始化,因为mine和show数组不同再传一个参数set即要初始化的字符内容
(3)宏定义ROWSCOLSROWCOLEASY_COUNT
为了方便修改游戏难度改变棋盘的行和列及雷的个数我们采用宏定义直接进行修改即可 game.h #define ROW 9//可以进行扫雷的行列
#define COL 9#define ROWS ROW2//进行判断的行列
#define COLS COL2#define EASY_COUNT 10 //雷的个数//初始化棋盘(9*9的外部也要初始化
void InitBoard(char board[ROWS][COLS],char ch); game.c //初始化棋盘(9*9的外部也要初始化,为了mine和show数组不同再传一个参数set即要初始化的内容
void InitBoard(char board[ROWS][COLS],char ch)
{for (int i 0; i ROWS; i){for (int j 0; j COLS; j){board[i][j] ch;//自己的棋盘初始化为0,展示的数组初始化为*}}
} 3.打印棋盘(9*9)
1打印出来的棋盘show得是9*9的但是由于定义的数组就是11*11的所以函数传参还得传11*11定义的数组
2因为我们这个游戏是自己输入需要排雷的位置所以最好在棋盘的旁边打印出对应的数字方便输入坐标 game.h //打印棋盘(打印9*9的部分就可以了)
void DisplayBoard(char board[ROWS][COLS]); game.c //打印棋盘(打印9*9的部分就可以了)
void DisplayBoard(char board[ROWS][COLS])//定义的数组是不变的一直都是11*11
{printf(------扫雷------\n);//用来隔开数组//打印列号for (int i 0; i COL; i){printf(%d , i);}printf(\n);for (int i 1; i ROW; i)//传的是11*11打印是9*9也就是从数组下标1开始打印到下标为9{printf(%d , i);//打印行号for (int j 1; j COL; j){printf(%c , board[i][j]);//打印字符用%c}printf(\n);}printf(------扫雷------\n);
} 4.布置雷
1布置雷是在mine数组上布置定义mine数组上1代表有雷0代表没雷这样方便后面计算周围8个坐标的和
2布置雷需要随机布置那就得随机生成横纵坐标跟上篇三字棋生成随机数一样rand函数
,但是注意取模结束后要1因为取模的结果是0-8我们需要生成的坐标是1-9
3这里要注意一点如果一个位置已经布置了雷那么这个位置就不需要再布置了加一条判断语句就可以解决这个问题 game.h //布置雷
void SetMine(char mine[ROWS][COLS]); game.c //布置雷
void SetMine(char mine[ROWS][COLS])
{int count EASY_COUNT;while (count)//注意这个循环进行的次数可能大于10次可能有的位置已经是1或者是多次生成的坐标相同{int x rand() % ROW 1;//%ROW得到的范围是0-8结果1的范围就算1-9int y rand() % COL 1;if (mine[x][y] ! 1){mine[x][y] 1;count--;}}
} 5.计算(x,y)周围8个坐标的和
注意求和的时候需要将字符和数字进行转换加和的时候数组中的是字符0而加和是数字0字符数字-0 eg:11-0 game.c //计算(x,y)周围8个坐标的和
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y - 1] mine[x - 1][y] mine[x - 1][y 1] mine[x][y - 1] mine[x][y 1] mine[x 1][y - 1] mine[x 1][y] mine[x 1][y 1]-8*0;//记住要减去8个0变成数字
} 6.排查雷 排查雷的规则 1.如果这个位置不是雷就计算这个位置周围8个坐标有几个雷并显示雷的个数 2.如果这个位置是雷就炸死了表示游戏结束 3.如果把不是雷的位置都找出来了那就通过了 1传参需要传两个数组mine数组用来判断是否踩中了雷show数组打印出来看
2排雷需要多次进行while语句控制结束当棋盘剩下的格子只剩下10个雷的时间就结束
或者踩到了雷直接break跳出结束 game.h //排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS]); game.c //排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS])
{int x 0;int y 0;int win 0;char ch 0;while (winROW*COL-EASY_COUNT)//当非雷的坐标已经全部排出来了即只剩下雷了就跳出循环{printf(请输入要排查雷的坐标:);scanf(%d %d, x, y);if (x 1 x ROW y 1 y COL){if (mine[x][y] 1)//踩中雷了{system(cls);//清空屏幕printf(很遗憾你被炸死了\n);DisplayBoard(mine);break;}else//不是雷就统计(xy)周围有几个雷:这时候雷定义为1的好处就出来了我们直接把周围坐标的和加起来放入show坐标的对应位置上即可{if (show[x][y] )//为了避免再次输入已经变成空格的坐标{printf(该坐标已排查\n);continue;}else{//展开一片去除和为0,并打印出和非0的位置(递归实现//条件1.这个坐标不是雷//2.这个坐标周围没有雷雷的个数是0//3.这个坐标没有被排查过RemoveZero(mine, show, x, y, win);system(cls);DisplayBoard(show);do {printf(如果需要$对雷进行标记请输入Y无需标记请按Enter键继续\n);while ((ch getchar()) ! \n)//清空缓冲区{;}scanf(%c, ch);if (ch Y){//标记雷并打印Remark(show);}else{continue;}} while (ch ! \n);//进行多次标记}}}else{printf(坐标非法请重新输入\n);}}if (win ROW * COL - EASY_COUNT){system(cls);printf(恭喜你排雷成功\n);}}
优化 1清屏后打印棋盘
system(cls);
头文件#includewindows.h
清屏后再打印show数组棋盘可以让屏幕更干净简洁
system(cls);
DisplayBoard(show);
2递归展开
展开一片去除和为0,并打印出和非0的位置(递归实现 条件1.这个坐标不是雷 2.这个坐标周围没有雷雷的个数是0 3.这个坐标没有被排查过 1递归展开当mine数组计算周围8个坐标的和返回的是0那就把show数组的这个位置变为空格并且再看自己周围的八个坐标是否也为0如果mine数组为0且show数组的对应位置为*那么再对这个坐标的周围8个坐标进行爆炸式展开show数组对应位置为*是为了防止多次把同一个位置变为空格
2传参记得传一个指针来使win即统计GetMineCount的位置每变一个符号剩下的棋格数就少一个对应又成功一步 game.c //展开一片去除和为0,并打印出和非0的位置(递归实现
void RemoveZero(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y,int *num)
{if (x 1 x ROW y 1 y COL)//小数组(9*9)内部才需要计算{//注意加和的时候数组中的是字符0而加和是数字0字符数字-0 eg:11-0int ret GetMineCount(mine, x, y);if (ret 0){show[x][y] ;//如果这个周围坐标和是0,那就变为空格(*num);//变一个空格win也1//看看周围8个坐标是否为0for (int i x - 1; i x 1; i){for (int j y - 1; j y 1; j){if (mine[i][j]0show[i][j] *)//show[i][j] *是为了避免重复RemoveZero(mine, show, i, j,num);}}}else{show[x][y] ret 0;//数字0变成字符(*num);}}
}
3标记雷
如果show数组上想要标记的位置为*则可以标记如果不是*则不可标记 game.c //标记雷
void Remark(char show[ROWS][COLS])
{int x 0;int y 0;while (1){printf(请输入要标记的坐标:\n);scanf(%d %d, x, y);if (x 1 x ROW y 1 y COL){if (show[x][y] *){show[x][y] $;system(cls);DisplayBoard(show);break;}else{printf(该位置不能被标记请重新输入\n);}}else{printf(坐标非法请重新输入\n);}}} 四、完整代码 game.h:相关函数的声明整个代码要引用的头文件以及宏定义 #includestdio.h
#includetime.h
#includestdlib.h
#includewindows.h#define ROW 9//可以进行扫雷的行列
#define COL 9#define ROWS ROW2//进行判断的行列
#define COLS COL2#define EASY_COUNT 10 //雷的个数//初始化棋盘(9*9的外部也要初始化
void InitBoard(char board[ROWS][COLS],char ch);
//打印棋盘(打印9*9的部分就可以了)
void DisplayBoard(char board[ROWS][COLS]);
//布置雷
void SetMine(char mine[ROWS][COLS]);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS]); game.c:实现游戏相关的函数 #includegame.h
//实现游戏相关的代码
//9*9的棋盘上面布置10个雷//排查雷
//1.如果这个位置不是雷就计算这个位置周围8个坐标有几个雷并显示雷的个数
//2.如果这个位置是雷就炸死了表示游戏结束
//3.如果把不是雷的位置都找出来了那就通过了//一个数组表示雷的信息1表示这个坐标是雷0表示不是雷另一个数组表示排查雷的信息
//当要排查数组最外层的雷时计算周围8个坐标会越界这就需要把数组扩充为11*11当然为了两个数组统一起来两个数组都定义11*11//初始化棋盘(9*9的外部也要初始化,为了mine和show数组不同再传一个参数set即要初始化的内容
void InitBoard(char board[ROWS][COLS],char ch)
{for (int i 0; i ROWS; i){for (int j 0; j COLS; j){board[i][j] ch;//自己的棋盘初始化为0,展示的数组初始化为*}}
}//打印棋盘(打印9*9的部分就可以了)
void DisplayBoard(char board[ROWS][COLS])//定义的数组是不变的一直都是11*11
{printf(------扫雷------\n);//用来隔开数组//打印列号for (int i 0; i COL; i){printf(%d , i);}printf(\n);for (int i 1; i ROW; i)//传的是11*11打印是9*9也就是从数组下标1开始打印到下标为9{printf(%d , i);//打印行号for (int j 1; j COL; j){printf(%c , board[i][j]);//打印字符用%c}printf(\n);}printf(------扫雷------\n);
}//布置雷
void SetMine(char mine[ROWS][COLS])
{int count EASY_COUNT;while (count)//注意这个循环进行的次数可能大于10次可能有的位置已经是1或者是多次生成的坐标相同{int x rand() % ROW 1;//%ROW得到的范围是0-8结果1的范围就算1-9int y rand() % COL 1;if (mine[x][y] ! 1){mine[x][y] 1;count--;}}
}//计算(x,y)周围8个坐标的和
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y - 1] mine[x - 1][y] mine[x - 1][y 1] mine[x][y - 1] mine[x][y 1] mine[x 1][y - 1] mine[x 1][y] mine[x 1][y 1]-8*0;//记住要减去8个0变成数字
}//展开一片去除和为0,并打印出和非0的位置(递归实现
void RemoveZero(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y,int *num)
{if (x 1 x ROW y 1 y COL)//小数组(9*9)内部才需要计算{//注意加和的时候数组中的是字符0而加和是数字0字符数字-0 eg:11-0int ret GetMineCount(mine, x, y);if (ret 0){show[x][y] ;//如果这个周围坐标和是0,那就变为空格(*num);//变一个空格win也1//看看周围8个坐标是否为0for (int i x - 1; i x 1; i){for (int j y - 1; j y 1; j){if (mine[i][j]0show[i][j] *)//show[i][j] *是为了避免重复RemoveZero(mine, show, i, j,num);}}}else{show[x][y] ret 0;//数字0变成字符(*num);}}
}//标记雷
void Remark(char show[ROWS][COLS])
{int x 0;int y 0;while (1){printf(请输入要标记的坐标:\n);scanf(%d %d, x, y);if (x 1 x ROW y 1 y COL){if (show[x][y] *){show[x][y] $;system(cls);DisplayBoard(show);break;}else{printf(该位置不能被标记请重新输入\n);}}else{printf(坐标非法请重新输入\n);}}}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS])
{int x 0;int y 0;int win 0;char ch 0;while (winROW*COL-EASY_COUNT)//当非雷的坐标已经全部排出来了即只剩下雷了就跳出循环{printf(请输入要排查雷的坐标:);scanf(%d %d, x, y);if (x 1 x ROW y 1 y COL){if (mine[x][y] 1)//踩中雷了{system(cls);//清空屏幕printf(很遗憾你被炸死了\n);DisplayBoard(mine);break;}else//不是雷就统计(xy)周围有几个雷:这时候雷定义为1的好处就出来了我们直接把周围坐标的和加起来放入show坐标的对应位置上即可{if (show[x][y] )//为了避免再次输入已经变成空格的坐标{printf(该坐标已排查\n);continue;}else{//展开一片去除和为0,并打印出和非0的位置(递归实现//条件1.这个坐标不是雷//2.这个坐标周围没有雷雷的个数是0//3.这个坐标没有被排查过RemoveZero(mine, show, x, y, win);system(cls);DisplayBoard(show);do {printf(如果需要$对雷进行标记请输入Y无需标记请按Enter键继续\n);while ((ch getchar()) ! \n)//清空缓冲区{;}scanf(%c, ch);if (ch Y){//标记雷并打印Remark(show);}else{continue;}} while (ch ! \n);//进行多次标记}}}else{printf(坐标非法请重新输入\n);}}if (win ROW * COL - EASY_COUNT){system(cls);printf(恭喜你排雷成功\n);}} test.c:整个游戏相关的测试 //测试代码
#includegame.h
void menu()//打印简易菜单
{printf(************************************\n);printf(************ 1.进入游戏 **********\n);printf(************ 0.退出游戏 **********\n);printf(************************************\n);
}void game()
{char mine[ROWS][COLS];char show[ROWS][COLS];//初始化棋盘(9*9的外部也要初始化InitBoard(mine, 0);InitBoard(show, *);//打印棋盘(打印9*9的部分就可以了)DisplayBoard(show);//布置雷(放在mine数组9*9中即可SetMine(mine);//排查雷FindMine(mine, show);
}
int main()
{int input 0;srand((unsigned int)time(NULL));//空指针NULLdo{menu();printf(请选择);scanf(%d, input);switch (input){case 1:game();break;case 0:printf(退出游戏\n);break;default:printf(输入错误请重新输入\n);break;}} while (input);//注意这里要加上;return 0;
} 五、游戏展示 扫雷小游戏演示 本次C语言小游戏扫雷的内容就到此啦有什么问题欢迎评论区或者私信交流觉得笔者写的还可以或者自己有些许收获的麻烦铁汁们动动小手给俺来个一键三连万分感谢 !