
专栏导读
🍁作者简介:余悸,在读本科生一枚,致力于 C++方向学习。
🍁收录于 C++ 专栏,本专栏主要内容为 C++ 初阶、 C++ 进阶、 STL 详解等,持续更新中!
🍁相关专栏推荐:C语言初阶 、C语言进阶 、数据结构与算法 (C语言描述)、 C++ 、 Linux 、 Mysql

雷区可以连续展开

相信大家都玩过扫雷吧,这里简单介绍一下扫雷的规则:
点击某个位置,如果这个位置有雷,玩家就会被炸,展示雷盘中所有雷的位置,游戏结束,如果这个位置没有雷,且以这个位置为中心的九宫格也没有雷,则这个位置被翻开,若以这个位置为中心的九宫格有雷,则统计以这个位置为中心的九宫格中雷的个数,并且显示在九宫格的中心位置,点开所有非雷位置则游戏胜利,在途中点到雷则游戏失败。
思路:使用EasyX(上期有介绍)图形库实现;口和鼠标点击操作,加上图片素材进行贴图,实现扫雷界面。通过图片素材和游戏数据的交互实现游戏效果。项目采用多文件联合编程,让整个项目的框架更加清晰,包括game.h存放头文件,函数声明等文件,game.cpp存放项目所需函数的定义(实现),test.cpp中为主函数。
接下来让我们顺着这个思路对扫雷游戏进行实现吧。
由于受Easy X图形库限制,我们创建的源文件后缀要为 .cpp,接下来我们创建本次项目的源文件和头文件。




至此,项目就创建完成了。接下来正式开始实现扫雷,准备好了吗?
首先将这次项目所要用到的头文件定义到game.h中,然后再game.cpp和test.cpp中引用game.h库,注意这里应用本地的库使用 " "。
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
然后将常用的常量采用宏定义方式定义到game.h中
#define ROW 10
#define COL 10
#define IMGW 40
接下来正式进入扫雷逻辑的实现。
通过对游戏地图的理解我们不难得出结论:我们可以使用二位数组来存放游戏数据,并将0作为初始状态,-1作为雷。
//定义地图
int map[ROW][COL] = {
0};
//ROW和COL为宏定义常量10,默认地图十行十列
接下来我们封装函数对地图进行打印,注意我们采用多文件联合编程,将函数的定义(实现)放到game.cpp中,在game.h进行声明
//声明
void showMap(int map[ROW][COL];
void showMap(int map[ROW][COL])
{
//使用嵌套循环遍历数组
for (int i = 0; i < ROW; i++)
{
for (int k = 0; k < COL; k++)
{
printf("%2d ", map[i][k]);//%2d让数据进行右对齐
}
printf("\n");
}
printf("\n");
}
下面我们给地图中随机埋雷(默认10颗,用-1表示),这里要用到随机数,srand函数和rand函数,需要引time.h和stdlib.h,随机数的生成这里不过多赘述。
//设置随机数种子
srand((unsigned int)time(NULL));
//给地图里随机埋雷,雷用-1表示
for (int i = 0; i < 10; )
{
int r = rand() % 10; //[0,10)
int c = rand() % 10;
//避免布置雷的坐标相同(去重)
if (map[r][c] == 0)
{
map[r][c] = -1;
i++;
}
}
我们将这个功能封装成initMap函数,在game.cpp中进行声明,在test.cpp中的主函数中调用即可
initMap(map);
接下来我们实现一个逻辑,统计格子为中心九宫格内的雷的数量
先遍历二维数组,在遍历九宫格,就可以统计到以该各自为中心的九宫格中所有雷的数量了,为防止数组越界,我们加上一点条件判断。

并且将这个功能封装到showMap函数中
void initMap(int map[ROW][COL])
{
//每次游戏前重置map (置0)
cnt = 0;
memset(map, 0, ROW * COL * sizeof(int));
//给地图里随机埋雷,雷用-1表示
for (int i = 0; i < 10; )
{
int r = rand() % 10; //[0,10)
int c = rand() % 10;
//避免布置雷的坐标相同(去重)
if (map[r][c] == 0)
{
map[r][c] = -1;
i++;
}
}
//雷所在的九宫格所有的格子的数值加一 (雷除外) 遍历地图
for (int i = 0; i < ROW; i++)
{
for (int k = 0; k < COL; k++)
{
//遍历雷所在的九宫格
if (map[i][k] == -1)
{
for (int r = i - 1; r <= i + 1; r++)
{
for (int c = k - 1; c <= k + 1; c++)
{
//边界九宫格可能会越界(数组越界问题)
if ((c >= 0 && c < ROW) && (r >= 0 && r < COL) && (map[r][c] != -1))
{
map[r][c]++;
}
}
}
}
}
}
}
下面我们将数据和图形界面进行交互,素材放在结尾自取
//把数据转成对应的图形界面
IMAGE img[12];//定义图片数组
//加载图片
for (int i = 0; i < 12; i++)
{
char fileName[50] = {