思路
实现扫雷小游戏的设计,首先要有两个棋盘(一大一小,用数组实现),一个隐藏雷的位置,一个给玩家看(没有任何提示价值,不会影响游戏的公正性),两个数组同时存在但同时之只展示一种,若玩家未踩雷,则只展示隐藏雷的数组,已扫的位置置为0,若玩家踩雷,则显示已踩雷,游戏结束并显示所有雷的分布;然后要初始棋盘;再生成十个雷的位置;扫雷,若扫中则本局游戏结束,若没扫中则扫的地方的符号变成相邻地方有雷的数量。
注:文章末有该游戏全代码
1.创建文件
此次扫雷游戏需要创建三个文件分别为game.h , game.c , text.c
头文件game.c用于对函数的声明
源文件text.c用于游戏主函数及游戏测试
源文件game.c用于功能的具体实现
2.菜单的打印
在text.c文件中创建一个menu函数用于打印菜单内容。
创建test函数用于实现菜单功能的实现。
该功能的实现运用了do while循环与switch语句,通过用户的输入进入对应的功能实现不同的效果。
此代码的缺点是用户只能输入数字,无法输入字母等其他符号。
3.游戏逻辑
当用户输入1时将进入game函数,game函数功能的实现分为图中四个部分。
3.1初始化棋盘
该扫雷游戏是9*9大小的棋盘
ps1 首先game()函数中创建两个数组mine,show分别为存放雷的信息,存放被查出的雷的信息。
ps2 在头文件game.h中定义ROW,COL,ROWS,COLS的值,便于后续更改棋盘的大小。
9*9的棋盘却要创建11*11的ROWS*COLS是为了便于后续统计边缘上非雷棋子周围雷的个数
棋盘的初始化
创建一个Initboard函数分别初始化两个棋盘
最终用户看到的只是Initboard(show,ROWS,COLS,'*')函数展示出的棋盘
在头文件game.h中对该函数进行声明
在源文件game.c中对Initboard函数的功能具体化实现
通过两个for循环初始化棋盘
3.2打印棋盘
初始化棋盘之后需要进行打印棋盘
在头文件game.h中对该函数进行声明
在源文件game.c中将该函数进行具体化实现
此时我们可以给棋盘加上坐标,将函数改为如图
3.3布置雷
在game()函数中创建setmine()函数
在源文件game.h中对该函数进行声明
声明过后在game.c中对该函数进行实现
此处用到了随机数,需在源文件text.c中的text()函数中添加
srand((unsigned)time(NULL)) 以及在头文件game.h中添加#include
此时如果想查看随机生成雷的位置,
需要将函数DispalyBoard(mine, ROW, COL)挪动到函数setmine(mine,ROW,COL)之后
3.4排查雷
在源文件text.c中的game()函数中创建Findmine()函数
在头文件game.h中对该函数进行声明
在game.c中对该函数进行具体实现
统计周围雷的个数
至此该游戏已经完成
缺点:该代码只实现了最基本的扫雷,无法做到传统扫雷的计时,插旗以及扫到的坐标周围雷的数量为0时空出一片无雷区的功能。
4.全代码
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"mine.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 DispalyBoard(char board[ROWS][COLS], int row, int col) { int i = 0; for (i = 0; i <=row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++)//因为展现给用户9*9的棋盘即可,所以i=1,i<=row(9) { printf("%d ",i); int j = 0; for (j = 1; j <= col; j++)//和上述解释相同 { printf("%c ", board[i][j]); } printf("\n");//换行 } } //布置雷是在棋盘上随机找十个坐标 void setmine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT;//雷的个数 int x = 0; int y = 0; while (count) { //利用随机数生成雷的坐标 x = rand()%row+1;//范围1-9 y = rand()%col+1;//范围1-9 if (mine[x][y] != '1')//如果随机的位置没有雷即不为1 布置一个雷 { mine[x][y] = '1'; count--; //布置一个雷之后,雷的个数-1 直到-为0后不再进行循环 } } } //排查雷 int get_mine_count(char mine[ROWS][COLS], int x,int y) { return mine[x - 1][y - 1] + mine[x - 1][y] + 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'; } //输入一个坐标 //判断坐标是否越界 //如果不是,就统计这个位置周围的雷的个数,直到获胜或炸死 void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int win = 0; int x = 0; int y = 0; while (1) { printf("请输入你要排查的坐标》"); scanf("%d %d",&x,&y); if (x>=1 &&x<=row&&y>=1&&y<=col)//判断坐标是否越界 { if (mine[x][y] == '1')//判断这个位置是不是雷 //如果是雷,就炸死,游戏结束 { printf("很遗憾你被炸死了"); DispalyBoard(mine, ROW, COL);//死亡之后,打印雷的分布图 break; } else //如果不是,就统计这个位置周围的雷的个数,直到获胜或炸死 { int count = get_mine_count(mine, x, y); show[x][y] = count + '0'; DispalyBoard(show, ROW, COL);//获胜之后,打印雷的分布图 win++; } } else { printf("输入的坐标有误"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你排雷成功\n"); DispalyBoard(mine, ROW, COL); } }
text.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"mine.h" void menu()//目录 { printf(" <欢迎来到扫雷游戏> \n"); printf("************************\n"); printf("********1.play**********\n"); printf("********0.exit**********\n"); printf("************************\n"); } void game() { char mine[ROWS][COLS] = {0};//存放雷的信息 char show[ROWS][COLS] = {0};//存放排查出的雷的信息 //初始化棋盘 Initboard(mine,ROWS,COLS,'0'); Initboard(show, ROWS, COLS, '*'); //打印棋盘 DispalyBoard(show, ROW, COL); //布置雷 setmine(mine,ROW,COL); DispalyBoard(mine, ROW, COL); //排查雷 Findmine(mine, show, ROW, COL); } void test() { //打印目录 int sel = 0; srand((unsigned)time(NULL)); do { menu(); scanf("%d", &sel); switch (sel) { case(1): printf("欢迎来到扫雷游戏!\n"); game(); break; case(0): printf("退出扫雷游戏\n"); break; default: printf("输入错误请重新输入\n"); break; } } while (sel); return 0; } int main() { test(); return 0; }
game.h
#pragma once #include#define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 #include //初始化棋盘 void Initboard(char board[ROWS][COLS], int rows, int cols, char set); //打印棋盘 void DispalyBoard(char board[ROWS][COLS],int row,int col); //布置雷 void setmine(char mine[ROWS][COLS], int row, int col); //排查雷 void Findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);