c语言简易扫雷游戏的实现
一、前言😘
首先我们要知道,在一个工程中,所有的代码是不会放在一个.c文件中的🤣。这样不利于程序员之间的协同合作。我们一般会创建.h和.c文件来放置我们的代码,把函数的声明放在头文件(.h)中,把函数的定义放在源文件(.c)中,在使用的时候包含头文件。
例如:我们要实现一个计算器的代码(假设只有加、减、乘、除),我们一般会把计算器的各个功能模块分配给不同的程序员来进行编写,各个模块的程序员完成任务之后,我们有了#include"add.h"、#include"add.c"、#include"sub.h"、#include"sub.c"、#include"mul.h"、#include"mul.c"、#include"div.h"、#include"div.h"。最后由其他程序员进行组合,这样可以提高效率,节省时间😉。
如下图:
二、简易扫雷代码的实现😍
2.1 扫雷游戏的基本思路😘
1.使用控制台进行扫雷游戏;
2.生成游戏菜单,实现选择进行和退出游戏;
3.生成9*9的方格;
4.在方格中随机10个雷;
5.可以排查雷:
- 选择位置不是雷,则打印周围雷的信息
- 选择位置如果是雷,则游戏结束
- 把非雷位置找出,挑战成功,游戏结束
2.2代码实现😊
1.打印菜单😍
这里我们使用do-while进行打印菜单,利用switch进行选择是否游玩game,并把它们放到对应的位置,如图:
把menu函数的定义放在game.h中。
此时的运行结果:
2.初始化扫雷的棋盘😉
在9*9的方格中,我们需要的储存信息,假设我们把雷视为1,把非雷的位置视为0。在进行游戏时,当点击一次位置(假设为非雷),棋盘需要显示周围雷的信息,如图:
此时的1(周围雷数)会与我们一开始定义的1(雷)产生歧义,所以这里采用建立两个棋盘来分别存储数据来避免这个问题。一个棋盘用来布置雷,另一个棋盘用来显示雷的信息。
依据以上的思路,我们需要显示周围雷的信息,对于边缘的雷,会存在越界的情况,我们无法用代码实现周围雷的信息。
因此,我们将棋盘扩大来存储信息,改为11*11。
我们利用二维数组来生成棋盘,将1和0设为字符形式来进行存储,另一棋盘用”*"来进行显示,巧妙地将数组统一为字符形式。
3.对棋盘进行打印🤣
此时一定要注意打印9*9的棋盘就行!
运行结果演示:
4.布置雷😆
我们需要在9*9的棋盘上随机布置10个雷,注意是9*9!,因为是进行随机布置,我们使用rand进行实现,rand产生的是伪随机数,加以时间进行随机化,不要忘记写头文件!
运行结果演示:
5.排查雷🙌
我们要排查的雷的信息储存在mine数组中,在选择坐标后需要显示信息,所以此时需要把mine数组和show数组的信息放在一个新的函数中,当然所选择的坐标需要在9*9的棋盘中不能越界,对应的坐标(假设为下x、y)也需要传到函数中。
我们首先写第一次选择就被炸死的情况,第一次存活的情况我们再借助另一函数实现,先写一个基本思路,最后我们进行细化。现在我们还不太了解while中的条件,之后我们再进行修改。
现在我们建立一个新函数Getminecount来数我们选择的坐标附近雷的个数。我们只需要将8个坐标的数值相加再减去‘0’(字符)就行,因为我们一开始在mine数组中就是选择以字符形式存储。
int Getminecount(char mine[ROWS][COLS], int x, int y)
{
return 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]+mine[x-1][y] - 8 * '0';
}
进一步优化,显示所选位置周围的雷数。
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
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("被炸死了\n");
Showboard(mine, ROW, COL);
break;
}
else
{
int c = Getminecount(mine, x, y);
show[x][y] = c + '0';
Showboard(show, ROW, COL);
}
}
else
{
printf("输入的坐标有误,请重新输入!\n");
}
}
}
现在我们需要加上while中的条件,游戏一旦找到71个位置没有雷,则游戏结束,成功。我们不妨用win来作为一个计数的效果,如果扫完雷,win就等于71,成功扫雷。但是此时我们会发现,10这个常量经常被重复使用,上面的count也被定义为了10,为了使用方便,我们在game.h中添加#define EASY_COUNT 10。
分析到这里,有两种情况跳出循环,一个是break跳出,;另一个是挑战成功。我们可以使用if语句实现。并展示雷的位置。
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");
Showboard(mine, ROW, COL);
break;
}
else
{
win++;
printf("还剩下%d个位置没有排查\n", ROW * COL - EASY_COUNT - win);
int c = Getminecount(mine, x, y);
show[x][y] = c + '0';
Showboard(show, ROW, COL);
}
}
else
{
printf("输入的坐标有误,请重新输入!\n");
}
}
if (win == ROW * COL - EASY_COUNT)
{
printf("恭喜你,扫雷成功!\n");
Showboard(mine, ROW, COL);
}
}
现在我们可以说这个简易版本的扫雷游戏已经结束了!(超大声)😎
但是呢,扫雷的游戏其实并没有结束,扫雷游戏的其他功能我还没有学会😜,更多内容我会进行学习更新,一定会补上的!😆