1.程序思路
1.1扫雷游戏的背景
假设游戏为一个9x9的棋盘,那么实际就要实现一个9x9的二维数组。而扫雷游戏的规则,是点击一个元素时,若踩到雷,则游戏失败;若没踩到雷,那么在当前元素显示出此元素一周的炸弹数。
图1:(点击的时棋盘中间部分)(图中1为雷,0为空,图二同)
图2:(点击的是棋盘边缘部分)
想要实现边缘部分,我们可以将边缘的外边扩展出来,并且里面的所有元素都为0,就相当于我们创建了个11*11大小的棋盘,但是只显示当中9*9的部分。
所以要实现扫雷的基础游戏规则,就是要计算出点击元素边缘的雷的个数。
2.代码程序
2.1拆分游戏
将游戏分为多个板块。在游戏未正式开始前,有一个选择菜单,游戏开始后,会出现一个棋盘,棋盘内有雷,我们称为为(装盘和装雷),然后,我们通过输入坐标来实现点击元素的过程,点击后当前元素变为周围雷的个数。
2.2菜单
实现菜单部分,将菜单封装为函数,并使用switch来进行选择。选择1则进行游戏部分,选择0则推出游戏
2.3游戏本体部分
2.3.1创建棋盘
由上述游戏背景所知,我们需要创建一个二维数组来作为棋盘,并且我们需要创建两个数组,一个作为开发者的棋盘,另一个作为游玩者的可使棋盘。
这里即创建成功棋盘,注意二维数组的类型是char 因为我们要存放的是字符。
其中RET和LINE是我们在头文件中已经定义好的,即大棋盘(11*11)的长宽。而Ret和Line则是我们需要将这个大棋盘的内部展示的棋盘的长宽。
2.3.2初始化棋盘
创建好棋盘后,需要先把棋盘初始化。我们把开发者棋盘初始化为0,后续放炸弹(1)的时候会方便;把游玩者的棋盘初始化为*,作成一种不可见的状态。
定义一个函数:
StartMine(ViewMineC,'*');
StartMine(rawMineC,'0');
void StartMine(char Minec[RET][LINE],char set)
{
int i = 0;
for (i = 0; i < RET; i++)
{
int j = 0;
for (j = 0; j < LINE; j++)
{
Minec[i][j] = set;
}
}
}
分别将二维数组传进函数,并把初始化的内容封装为一个set传进函数。注意,这里的初始化是把整个大棋盘都初始化。
2.3.3检查棋盘(打印棋盘)
初始化好棋盘后,我们要检查棋盘,那么就要把棋盘打印出来。这里注意的是,我们需要的是大棋盘中心的那一部分,即长宽是Ret和Line的二维数组。并且,我们需要在所展示出来的棋盘旁显示出坐标。封装一个函数:
void DisplayMine(char Mine[RET][LINE], size_t ret, size_t line)
{
printf("***********扫雷************\n");
int i = 0;
for (i; i <= ret; i++)
{
printf("%d ", i); //打印出第一行数字作为坐标x轴
}
printf("\n");
for (i = 1; i <= ret; i++)
{
int j = 1;
printf("%d ", i); // 打印出第一列作为坐标y轴
for (j = 1; j <= line ;j++)
{
printf("%c ", Mine[i][j]); // 打印数组
}
printf("\n");
}
}
把这个函数封装完成后对后续的检查以及编写都有帮助。
2.3.4下雷
然后我们救要开始将雷放进棋盘。这里有一个注意点,我们只需要把雷放进开发者的棋盘,而不是把雷放进游玩者可视棋盘。
那么为了在棋盘内能随机下雷,那么我们就需要时间戳来让每次形成的坐标都不同。不过也不一定每次形成的坐标都不同,所以在每次下雷前我们要检查此坐标是否已经是雷,若不是,再安放。
这里放雷是放进(Ret,Line)大小的棋盘内
SetMine(rawMineC, Ret, Line);
void SetMine(char Mine[RET][LINE], size_t ret, size_t line)
{
srand((unsigned int)time(NULL)); //定义rand
int mines = Easy_mode; //设置雷的个数
while (mines)
{
int x = rand() % ret + 1; //这里%ret+1后x的范围就在目标棋盘大小内
int y = rand() % line + 1;
if (Mine[x][y] == '0') //检查是否已经是雷
{
Mine[x][y] = '1';
mines--;
}
}
}
2.3.5找雷
找雷要完成的逻辑:输入坐标,若此坐标不是雷,则显示出附近雷的个数,并执行下一次找雷;若踩到雷,那么游戏结束,并展示棋盘 。
void FindMine(char Mine[RET][LINE],char show[RET][LINE],size_t ret, size_t line)
{
int mines = ret * line - Easy_mode; // mines即成功通关所需走的次数
while (mines) //
{
int x = 0;
int y = 0;
printf("请输入坐标--->\n");
scanf("%d %d", &x, &y); //输入坐标
int mine = calMines(Mine, x, y); //封装一个函数来计算附近雷的个数
if (x <= ret && x > 0 && y <= line && y > 0) //坐标要符合要求
{
if (Mine[x][y] == '1')
{
printf("抱歉,踩到炸弹了\n");
DisplayMine(Mine, ret, line);
break;
}
else
{
show[x][y] = mine + '0'; //因为是char类型的数组,要显示出个数,那么只要用计算
好返回来的值加上‘0’即可
mines--;
DisplayMine(show, Ret, Line);
}
}
}
}
其中计算附近雷的个数封装一个函数:
char calMines(char set[RET][LINE], int x, int y)
{
return set[x - 1][y - 1] + set[x - 1][y] + set[x - 1][y + 1] +
set[x][y - 1] + set[x][y + 1] +
set[x + 1][y - 1] + set[x + 1][y] + set[x + 1][y + 1]
- 8 * '0';
}
2.4函数申明
将函数申明全部放进头文件中,避免重定义
3.完
感谢阅读^_^