一.
扫雷游戏的要求:
1. 使用控制台实现扫雷游戏。
2.游戏可以通过菜单继续玩或者退出游戏。
3.扫雷的棋盘是9*9。
4.默认随机布置十个雷。
5.可以排查雷:
如果位置不是雷,显示周围有几个雷。
如果位置是雷,就被炸死游戏结束。
把除10个雷之外的非雷都找出来,排雷成功,游戏结束。
二.
1.扫雷游戏的实现:
首先可以创建两个 .c 文件用来实现函数(一个编译主函数,另一个编译自定义函数),创建一个 .h 文件用来实现函数的声明,类型的声明。如下:
接下来开始编译主函数,首先题目要求为:要通过菜单来继续玩或者退出游戏
所以我们可以通过 do while 循环来控制,当输入为1时玩或继续玩,输入0时退出游戏。
即可以创建一个 input 整型变量 同时 scanf 来往 input 里存储值并通过 switch 来判断。
如果为1:进入游戏函数
如果为0:打印 "游戏结束,退出游戏" 并 break 跳出循环
如果为其他情况:会打印 "选择错误,重新选择"并 break
之后 input 若为真(再次进入循环),为假(循环结束)。
//Mine sweeper.c下
int main()
{
int input = 0;
srand((unsigned int)time(NULL))//使用time函数的返回值设置随机数种子
do
{
menu();
printf("请选择:>>>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束,退出游戏!\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
而在游戏开始当然需要显示菜单,来指导玩家进行选择
所以创建一个无返回类型的menu函数,在屏幕上显示出来。
//编辑菜单函数
void menu()
{
printf("********************\n");
printf("********************\n");
printf("***** 1 . play *****\n");
printf("***** 2 . exit *****\n");
printf("********************\n");
printf("********************\n");
}
之后开始重头戏 选择1 进入game()函数
2. game() 函数
在输入 1 进入游戏后,由于布置的雷和排查的雷的信息都需要存储,题目要求是在 9*9 的棋盘上,因此需要创建 9*9 的二维数组。
即若在某个位置布置雷,是雷的话存放 1 ,没有雷存放 0 。
而在假设排查过程中会发现问题:
若排查坐标 (2,5) ,访问周围一圈8个位置,统计周围雷的个数为 1 。
若排查坐标 (8,6) 时,根据扫雷规则 (8,6) 坐标会访问一圈八个位置统计雷的数量
这就会出现越界问题,因此为防止越界可以在创建数组时将数组扩大一圈,雷依旧布置中间9*9的位置,周围扩大的不去布置雷。
而这时又会发现问题,我们在棋盘上布置雷的信息(1)和非雷的信息(0),假设我们排查一个坐标 (a,b) ,(a,b)该坐标不是雷,但是(a,b)周围有 1 个雷,雷的个数需要存储并打印出来,作为排查雷的重要信息。而雷的个数信息要存放到哪里?如果放在了布置雷的数组中,这个数组中就会有 雷的信息,非雷的信息,雷的个数。非常容易造成混淆不够方便。
因此有一个解决方案:可以创建两个数组,专门给一个数组(Mine)存放雷的信息,另一个数组(Show)存放排查出雷的信息。这样就不会互相干扰,同时在Mine数组中排查雷,排查出的信息传到Show数组。
并且在创建棋盘时为了显示雷的坐标信息并且防止越界所以数组应定义为 11*11。
创建两个字符数组:
在game()函数下创建两个字符数组,同时在自定义头文件 MIme sweeper.h 定义变量
void game()
{
char Mine[ROWS][COLS];//Mine数组用于存放雷
char Show[ROWS][COLS];//Show数组用于排雷
}
初始化字符数组:
Mine棋盘初始化为'0' Show棋盘初始化为'*'。
将实参 :数组名,行和列,和棋盘内容传入自定义函数InitBoard中;
//二维数组 行 列 传入的字符
void(char[ROWS][COLS],int ROWS,int COLS,char set)
{
for(int i = 0;i<ROWS;i++)//遍历行
{
for(int j = 0;j<COLS;j++)//遍历列
{
char[i][j] = set;//将二维数组每个元素赋值传入的字符
}
}
}
这就完成了两个棋盘的初始化。
布置雷:
接下来就在Mine数组棋盘中布置雷,我们可以写一个布置雷的函数
同样我们可以定义变量雷的个数,方便以后进行修改。
在自定义头文件中进行定义
而由于每次进行游戏都希望雷的位置是随机的,所以需要随机数:首先设置随机数种子srand(用time函数的返回值设置[需要包含 <time.h> 头文件] )
rand随机值范围的设置方法: a + rand()%(b-a+1) (生成a~b范围的随机值)
由此我们得出函数
void Setboom(char arr[ROWS][COLS], int row, int col)
{ //count存放雷的个数
int count = EASY_Count;
while (count)//循环:当雷布置完跳出循环
{
int x = rand() % row + 1;//行的随机值(范围1-9)
int y = rand() % col + 1;//列的随机值(范围1-9)
if (arr[x][y] == '0')//坐标不是雷时进入语句
{
arr[x][y] = '1';//将这个坐标布置雷
count--;//减少雷的个数
}
}
}
未完待续。