前言
用C语言写一个简单的扫雷游戏。
首先要有以下几个步骤:
1:初始化棋盘。
2:打印棋盘。
3:埋雷。
4:扫雷。
我们可以尝试用多文件的方式来写,这样简洁明了,也方便代码的检查。
以下开始实现:
主体函数搭建
首先创建一个源文件test.c用来放主函数,
主函数内用do{}while()循环可以实现多次扫雷游戏,switch选择开始游戏还是退出游戏,如果选择错误,会出现“选择错误,重新选择”的字样。
游戏开始时我们也可以打印一个简单的菜单,如下图:
采用一个简单的函数调用,可以实现菜单打印。
case 1:采用了game()用来分装游戏代码,这里需要创建多文件,在源文件里面创建一个 game.c 文件,在头文件里面创建一个 game.h 文件,如图:
game.h 放置创建函数的声明,
game.c 放置游戏代码,
test.c 放置主函数,
注意:game,c和test.c 都要包含game.h 的头文件,才能使用 game.h 里面的函数.
游戏代码实现
1:初始化棋盘
首先定义一个二维数组,用来打印棋盘,
但是
扫雷菜单的表示需要多种元素,如果用 ’0‘ 来表示没有雷,用 ’1‘ 来表示有雷,
初始化打印菜单时还需要其他符号来表示隐藏的雷;这就需要多种元素来表示,
所以定义数组时不妨用两个数组来表示
char mine[ROWS]COLS] 表示埋雷的棋盘;
char show[ROWS][COLS] 表示展示给用户的棋盘;
如图
为了表示方便,数组的行和列事先在头文件 gane,h 定义过,这里用变量表示
如图:
定义棋盘后开始初始化棋盘,
在 test.c 创建一个函数 chushihuaqipan,在game.h 声明,然后在 game.c 里实现,
接下来的函数也是这个流程;
如下图示例:
在 game.h 里定义函数:
因为 chushihuaqipan 函数没有返回值,所以用 void 表示
函数里的形参可以和主函数里的实参名字不同,为了避免混淆,用小写变量名表示,
在 game.c 里实现函数:
char set 这个变量可以很好的打印字符,我们要打印两个棋盘,又要重复利用这个函数, set 就可以巧妙地解决这个问题:
这样就可以用一个函数打印两个棋盘;
在 test.c 里调用函数:
2 :打印棋盘
依旧是在 game.h 声明一个函数 dayinqipan ,在 game.c 里面实现,
如下图:
这是打印棋盘的代码实现,我们打印的是 9 X 9 的棋盘,用两个for 循环嵌套很轻松就可以实现,
注意换行!
3:埋雷
为了确保每次雷的位置不同,我们需要用到随机数的函数,下面请看示例:
随机数的种子可以放在主函数里面,确保每次随机数的种子都不一样,做到真正的随机。
埋雷时,如果这个地方已经有雷了,就不用在埋雷了,要用到一个 if() 判断语句。
4:扫雷
扫雷是游戏的主要代码,首先我们要输入坐标,用if 语句判断坐标是否下 9 X 9 的棋盘内,
然后用 if 嵌套判断该位置是否是雷,如果不是雷,那么计算雷周围一圈雷的个数,
计算雷的个数可以再用一个函数:
由于棋盘上使用字符 ’ 0 ‘ 来表示的,而打印雷的个数是整形雷,所以计算雷的个数之后要减去字符
’ 0 ‘ 得到整形 0,
如下图示例:
以上就是扫雷游戏的代码解析,希望给大家一些帮助!
记得点赞哟!!!
附:扫雷代码
game.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 //初始化棋盘 void chushihuaqipan(char arr[ROWS][COLS], int rows, int cols, char set); //打印棋盘 void dayinqipan(char arr[ROWS][COLS], int row, int col); //布置雷 void buzhilei(char arr[ROWS][COLS], int row, int col); //排查雷 void paichalei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //初始化棋盘 void chushihuaqipan(char arr[ROWS][COLS], int rows, int cols, char set) { int i = 0; for ( i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { arr[i][j] = set; } } } //打印棋盘 void dayinqipan(char arr[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++) { printf("%d ", i); for (int j = 1; j <= col; j++) { printf("%c ", arr[i][j]); } printf("\n"); } } //布置雷 void buzhilei(char arr[ROWS][COLS], int row, int col) { int count = 10; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (arr[x][y] == '0') { arr[x][y] = '1'; count--; } } } //雷的个数 int leidegeshu(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[x-1][y] + mine[x-1][y-1]+ mine[x][y-1] + mine[x+1][y-1]-8*'0'; } //排查雷 void paichalei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (win < row * col - 10) { printf("请输入你要排查的坐标:"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("很遗憾!你被雷炸死了\n"); dayinqipan(mine, ROW, COL); break; } else { int count = leidegeshu(mine, x, y); show[x][y] = count + '0'; dayinqipan(show, ROW, COL); win++; } } else { printf("坐标非法,请重新输入:"); } } if (win == row * col - 10) { printf("恭喜你,排雷成功\n"); dayinqipan(mine, ROW, COL); } }
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //打印菜单 void menu(void) { printf("***********************\n"); printf("***** 1.play *****\n"); printf("***** 0.exit *****\n"); printf("***********************\n"); } void game() { //定义棋盘 char mine[ROWS][COLS]; char show[ROWS][COLS]; //初始化棋盘 chushihuaqipan(mine, ROWS, COLS, '0'); chushihuaqipan(show, ROWS, COLS, '*'); //打印棋盘 dayinqipan(show, ROW, COL); //dayinqipan(mine, ROW, COL); //布置雷 buzhilei(mine, ROW, COL); //dayinqipan(mine, ROW, COL); //排查雷 paichalei(mine, show, ROW, COL); } int main() { int input = 0; srand((unsigned int) time(NULL)); do { menu(); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default : printf("选择错误,重新选择\n"); break; } } while (input); return 0; }