尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

C 语言自学笔记 08:扫雷游戏实践(初版)

C 语言自学笔记 08:扫雷游戏实践(初版) 一、游戏设计分析首先扫雷是一个棋盘游戏我们可以设计一个9*9的棋盘就可以用二位数组来设计用1表示雷0表示非雷默认布置10个雷当我们进行排查时如果排查到雷直接失败如果不是雷就显示周围有几个雷。但是当我们排查外圈时可能会出现越界的现象这时我们不妨再在外面扩大一圈设计成11*11的棋盘大小我们的雷和游戏区还是在9*9区域内。当我们进行游玩时排查的数据和棋盘的数据必定会出现冲突比如排查出坐标附近有1个雷那么显示1这个1就会和雷的1冲突而且我们的布置雷的棋盘也不能让玩家知道所以这时候需要两个棋盘一个棋盘mine是我们的底层布置雷的棋盘一个棋盘show是展示给玩家扫雷的棋盘我们的mine棋盘中的雷用字符1表示非雷用字符0表示show棋盘用*表示。二、游戏设计首先我们新建三个文件一个test.c文件用来存放游戏逻辑的实现一个game.c文件用来具体实现游戏的问题一个game.h文件用来声明game.c中的函数方便test.c调用。我们把所有的头文件都放在game.h中其他文件只需要#include game.h就行在test.c中我们首先实现整个游戏的执行逻辑#define _CRT_SECURE_NO_WARNINGS #include game.h int main() { do { menu(); printf(请输入); int i 0; scanf(%d, i); if (i 1) { game(); } else if (i 0) { break; } else { printf(请输入1、0\n); } } while (1); printf(游戏已关闭); return 0; }首先打印菜单1-游玩0-退出让玩家输入如果输入的数字不对就提示玩家重新输入玩不过瘾可以继续玩所以我们用while实现。menu()函数实现逻辑如下所有和游戏相关的函数实现都放在game.c中也要记得在game.h中定义。void menu() { printf(----------------------------\n); printf(-----------1.play-----------\n); printf(-----------0.exit-----------\n); printf(----------------------------\n); }写完整个逻辑后对游戏进行具体实现首先为了游戏后期可以扩充所有的行列和雷数用宏来定义方便后期修改时只需要修改宏定义即可#define _CRT_SECURE_NO_WARNINGS #define ROW 9 #define COL 9 #define ROWS ROW 2 #define COLS COL 2 #define EASY_COUNT 10 #include stdio.h #include stdlib.h #include time.h //所有定义都放在game.h中void game() { char mine[ROWS][COLS] { 0 }; char show[ROWS][COLS] { 0 }; init_Board(mine, ROWS, COLS, 0);//初始化棋盘 init_Board(show, ROWS, COLS, *); printf(--------扫雷游戏开始--------\n); display_Board(show, ROW, COL);//展示游戏棋盘给玩家 set_Mine(mine, ROW, COL);//布置雷 find_Board(mine, show, ROW, COL);//排查雷 }这些函数的定义都要放在game.h文件中实现就在这个函数上面。首先是需要两个棋盘一个mine存放我们的雷一个show展示给玩家的棋盘然后对这两个棋盘进行初始化void init_Board(char board[][COLS], int r, int c, char set) { for (int i 0; i r; i) { for (int j 0; j c; j) { board[i][j] set; } } }然后把初始化后的show棋盘展示给玩家因为游戏区是9*9这部分所以只展示9*9区域的内容void display_Board(char board[][COLS], int r, int c) { int i 0; int j 0; for (i 1; i r; i) { for (j 1; j c; j) { printf(%c , board[i][j]); } printf(\n); } printf(\n); }但是只展示棋盘的话不方便玩家排雷所以我们给游戏区加上行列数方便玩家排查,所以我们加上行列号void display_Board(char board[][COLS], int r, int c) { int i 0; int j 0; for (j 0; j c; j) { printf(%d , j); }//首先打印出列号从0开始到9 printf(\n); for (i 1; i r; i) { printf(%d , i);//然后在打印每一次棋盘内容时先把行号打印出来 for (j 1; j c; j) { printf(%c , board[i][j]); } printf(\n); } printf(\n); }下一步就是布置雷了void set_Mine(char board[][COLS], int r, int c) { srand((unsigned int)time(NULL)); int count 0; /*for (count 0; count EASY_COUNT; count) { int x rand() % r 1; int y rand() % c 1; if (board[x][y] ! 1) { board[x][y] 1; } }*//*为了避免重复同一个坐标count还是会自增将count放到if里*/ while (count EASY_COUNT)//布置10个雷在棋盘1-9范围内 { int x rand() % r 1; int y rand() % c 1; if (board[x][y] ! 1)//10个雷位置不能重复 { board[x][y] 1; count; } } }接着排查雷void find_Board(char mine[][COLS], char show[][COLS], int r, int c) { int x 0; int y 0; int win 0; while (win r * c - EASY_COUNT) { printf(请输入坐标); scanf(%d %d, x, y); if (x 1 x r y 1 y c) { if (show[x][y] *) { if (mine[x][y] 1 win 0) { mine[x][y] 0; int nx 0; int ny 0; do { nx rand() % r 1; ny rand() % c 1; } while (mine[nx][ny] 1); mine[nx][ny] 1; } if (mine[x][y] 0) { size_t count getMineCount(mine, x ,y); show[x][y] (char)(count 0); display_Board(show, ROW, COL); win; } else { display_Board(mine, ROW, COL); printf(你踩到雷被炸死了游戏失败\n); break; } } else { printf(该坐标已被排查请重新输入\n); } } else { printf(请输入合法坐标\n); } } if (win r * c - EASY_COUNT) { printf(排雷成功\n); } }排查雷要把两个棋盘都传入进来因为对mine棋盘进行排查的数据要存储到show上把9*9游戏区的行列也传入函数中首先创建xy作为坐标来进行排查win表示排查格子的个数刚开始是0如果排查的格子数需要排查的格子数9*9-雷数10win71就进入排查让玩家输入要排查的坐标对这个坐标进行多次判断第一次是输入坐标是否合法是否在9*9范围内第二次是判断这个坐标是否被排查过如果不是则进入排查首先如果第一次就排到雷就把这个雷给移走这个雷不能布置在已经是雷的区域如果不是第一次且没有排到雷就统计这个坐标周围雷的个数int getMineCount(char mine[][COLS], int x, int y) { int i 0; int j 0; int count 0; for (i -1; i 1; i) { for (j -1; j 1; j) { count count (mine[x i][y j] - 0); } } return count; }使用getMineCount这个函数进行统计一个数的字符减去一个字符0就是他的十进制数如‘10’-010;把周围一圈的数进行求和计算0y-1yy1x-1未知未知未知x未知0未知x1未知未知未知然后在show棋盘的这个坐标上显示这个数字因为show棋盘存储的是字符所以把数字加上字符‘0’再强转转化为字符型如统计的数为22‘0’50char(50) ‘2’把这个字符数字赋值给show棋盘这个坐标然后打印出show棋盘显示给玩家win排查格加一。如果排查到的是雷就失败直接退出循环如果所有的空格都排查出了就跳出循环判断排查的格数是否和需要排查的格数相同相同就输出获胜。然后退出game()函数进行下一次循环下一次再次输入1就继续游戏0就退出当退出时就显示游戏已关闭。三、说明1、本次扫雷版本不包含图形化界面只在终端进行游玩也就是控制台形式。2、没有实现如果排查位置不是雷周围也没有雷可以展开周围的一片这个需要学习函数递归等后期让AI 拓展3、没有实现可以标记雷。4、没有实现可以加上排雷的时间显示。5、没有实现游戏难度选择代码中只设置了EASY_COUNT难度后期可拓展中等16*16棋盘40个雷困难30*16棋盘99个雷。四、在线扫雷游戏这里提供一个在线扫雷游戏方便理解扫雷游戏机制https://www.minesweeper.cn/
返回列表