目录
1.前言
扫雷作为大家耳熟能详的游戏相信不少人玩过,肯定有很多人会好奇它是如何实现的,所以今天我们将运用数组与函数的知识来完成这个C语言小游戏, 通过这个项目, 相信大家一定能通过它掌握用函数,数组等工具并用其构建起一个小项目
让我们先来回忆一下扫雷:
![]()
以9×9为例,81方格个中存放着10个雷,以一个小方格为中心的一圈内存在多少雷,这个方格就显示多少雷,所以我们要利用提示一步一步的把10个雷排查完,才能获得游戏胜利
所以我们应该怎么去实现呢🤔🤔?
1.利用数组, 定义若干个二维数组,进行初始化,雷的存放
2.利用函数,将我们所需的功能分模块编写,既简明清晰,又能提升我们的效率
所以我们可以定义 2个.c文件用于存放游戏模块以及代码的实现,用.h文件进行声明所用函数
即 game.h test.c game.c
2.游戏主体的实现
2.1 使用menu函数实现主界面的打印
我们将其放入test.c中
void menu()
{
printf("*********************\n");
printf("****0.exit 1.play****\n");
printf("*********************\n");
}
再通过switch和do...while语句实现玩家的选择
int main()
{
int input = 0;
do
{
menu();
srand((unsigned int)time(NULL));//生成随机数
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 0:printf("退出游戏");
break;
case 1:game();
break;
default:printf("输入错误, 请重新输入\n");
}
} while (input);
return 0;
}
2.2 使用game函数实现游戏
在实现之前,我们想象一个空的9×9雷盘,有雷的地方我们布置为1,没有雷的地方为零,这样在后续对数组数据的处理中我们便可以直接相加
但此时我们会发现在边缘区域查找雷的时候可能会发现这些情况:
1.数组越界我们无法统计周围雷的信息
2.当我们统计完其中一个小方格周围的雷数时,放进小方格所对应数组中,在下一个小方格排雷过程中可能会产生歧义
所以我们可以将雷盘扩大为11×11,同时定义2个二维数组一个存放雷的信息, 一个用与存放排查雷的信息
所以我们可以先在game.h中定义行与列的大小(方便日后改变雷盘大小)
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
2.2.1 用初始化棋盘函数初始化两个棋盘
先定义两个函数 一个用来初始化雷的信息 一个用来隐藏雷的信息
Initboard(mine, ROWS, COLS, '0');//初始化为0 Initboard(show, ROWS, COLS, '*');//初始化为*
并在game.h中定义 在game.c中实现
两个棋盘的初始化:
void Initboard(char arr[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) arr[i][j] = set; } }
2.2.2 将初始化后的棋盘进行打印
定义两个函数,一个用来隐藏雷的信息, 一个用来显示雷的信息
Displayboard(show, ROW, COL);//只需打印9×9中的内容 //Displayboard(mine, ROW, COL);//用于查看雷的布局 在后续查看雷是否成功放置可以使用
同样在game.h中定义 在game.c中实现
打印棋盘:
void Displayboard(char arr[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("*********扫雷*********\n"); //打印列号 for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i);//打印行号 for (j = 1; j <= col; j++) { printf("%c ", arr[i][j]); } printf("\n"); } printf("*********扫雷*********\n"); }
结果:
2.2.3 在棋盘中布置雷
定义一个函数用于布置雷
Setmine(mine, ROW, COL); Displayboard(show, ROW, COL);
同样在game.h中声明,在game.c中实现
用于随机生成雷
void Setmine(char arr[ROWS][COLS], int row, int col) { //生成雷 int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (arr[x][y] == '0') { arr[x][y] = '1'; count--; } } }
成功生成10个雷
2.2.4 使玩家能够排查雷
定义一个函数用于排查雷
Findmine(mine, show, ROW, COL);
同样在game.h中声明,在game.c中实现
函数的实现
void Findmine(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 - EASY_COUNT) { printf("请输入要排查的坐标:"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (arr[x][y] == '1') { printf("很遗憾,你被炸死了\n"); Displayboard(show, ROW, COL); break; } else { //非雷,统计雷 int n = Getminecount(); show[x][y] = n + '0'; Displayboard(show, ROW, COL); win++; } } else printf("坐标非法,请重新输入"); }
其中统计雷用Getminecount函数实现
- 小知识点:数字加上字符‘0’ 可以转为相应的数字字符
- 同理数字字符减去字符‘0’ 可以得到相应的数字
2.2.5 统计小方块周围雷的个数
定义一个函数用于统计雷数,并用一个整形变量接收,然后转为字符型放在show数组中
int n = Getminecount(mine, x, y);
同样在game.h中声明,在game.c中实现
函数的实现
int Getminecount(char mine[ROWS][COLS], int x, int y) { return (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] + mine[x + 1][y] + mine[x + 1][y - 1] - 8 * '0'); }
2.3 游戏胜利的判断
在此处我们可以在game.h 中定义一个 EASY_COUNT 用于存放雷的个数 当我们后续测试游戏胜利的代码时,可以直接改变EASY_COUNT的值,更方便调试
判断胜利的实现
if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功\n"); Displayboard(mine, ROW, COL); }
3.总代码
1. game.h —— 函数的定义与声明
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<time.h> #include<stdlib.h> #define ROW 9 #define COL 9 #define EASY_COUNT 10 #define ROWS ROW+2 #define COLS COL+2 //初始化棋盘 void Initboard(char arr[ROWS][COLS], int rows, int cols, char set); //打印棋盘 void Displayboard(char arr[ROWS][COLS], int row, int col); //设置雷 void Setmine(char arr[ROWS][COLS], int row, int col); //排查雷 void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
2. game.c ——游戏主体模块的实现
#include"game.h" //初始化棋盘 void Initboard(char arr[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) arr[i][j] = set; } } //展示棋盘 void Displayboard(char arr[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("*********扫雷*********\n"); //打印列号 for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i);//打印行号 for (j = 1; j <= col; j++) { printf("%c ", arr[i][j]); } printf("\n"); } printf("*********扫雷*********\n"); } //设置雷 void Setmine(char arr[ROWS][COLS], int row, int col) { //生成雷 int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (arr[x][y] == '0') { arr[x][y] = '1'; count--; } } } //获取周围有几个雷 int Getminecount(char mine[ROWS][COLS], int x, int y) { return (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] + mine[x + 1][y] + mine[x + 1][y - 1] - 8 * '0'); } //排查雷 void Findmine(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 - EASY_COUNT) { printf("请输入要排查的坐标:"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("很遗憾,你被炸死了\n"); Displayboard(mine, ROW, COL); break; } else { //非雷,统计雷 int n = Getminecount(mine, x, y); show[x][y] = n + '0'; Displayboard(show, ROW, COL); win++; } } else printf("坐标非法,请重新输入"); } //游戏胜利 if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功\n"); Displayboard(mine, ROW, COL); } }
3. test.c ——游戏菜单以及函数的引用
#include"game.h" void menu() { printf("*********************\n"); printf("****0.exit 1.play****\n"); printf("*********************\n"); } void game() { char mine[ROWS][COLS]; char show[ROWS][COLS]; //初始化棋盘 Initboard(mine, ROWS, COLS, '0');//初始化为0 Initboard(show, ROWS, COLS, '*');//初始化为* //打印棋盘 //Displayboard(show, ROW, COL);//只需打印9×9中的内容 //Displayboard(mine, ROW, COL);//用于查看雷的布局 //布置雷 Setmine(mine, ROW, COL); Displayboard(show, ROW, COL); //Displayboard(mine, ROW, COL);//用于查看雷的布局 //排查雷 Findmine(mine, show, ROW, COL); } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请选择:"); scanf("%d", &input); switch (input) { case 0:printf("退出游戏"); break; case 1:game(); break; default:printf("输入错误, 请重新输入\n"); } } while (input); return 0; }
- 运行截图