在上面我们学习了函数以及数组,还有分支与循环的基本内容,那么现在我们就可以利用这些基本内容来实现一个小游戏了——扫雷(简易版)
首先我们要清楚这个游戏是怎么实现的,就和你做数学题一样,先想好思路,搭好框架,再动手,事半功倍,同时在这里我们为了使我们的逻辑更加清晰明了,下面我们采用多文件的方式实现,在game.h中完成对函数的声明,在game.c中完成游戏实现的相关函数,最后在sweep_mines.c中游戏的实现。
简易版扫雷具体的实现步骤我认为可以分为以下几点:
1.游戏初始界面设置
首先我们需要一个初始游戏界面来开始这个游戏,这个呢,我们可以用一个do...while循环实现,因为do...while可以在开始游戏前进入循环一次,即打印初始游戏界面,同时我们还可以使玩家选择开始游戏或者退出游戏;
2.初始化数组及打印
其次我们要了解这个游戏的具体实现方法,不难看出,扫雷本质上就是两个二维数组,一个二维数组展示给玩家看,而另外一个二维数组存放雷阵的数据,所以我们需要一个函数来对这两个数组进行初始化。在这里为了保证对玩家的神秘感,对展示给玩家看的二维数组我们可以全部初始化为字符’*‘,同时我们也需要有一个函数对其进行打印展示给玩家看,而雷阵我们为了和上面数组类型保持一致,我们可以全部初始化为字符’0‘,对于初始化函数的设置因为两个数字初始化内容的不同所以我们可以再加一个参数char set,这样我们就可以只用一个函数来实现两个数组的初始化,而不用繁琐的使用两个同样的函数来进行初始化了;
3.设置雷
完成初始化后,我们就有了一个展示阵和一个雷阵,可是在雷阵中我们全为字符’0‘,并没有雷,这时我们就需要对雷阵进行处理,使之存放一定雷的个数,而在这里我们将雷设置为字符’1‘使之与字符’0‘做出一定的区分;
4.游戏实现
最后就是玩家进行的操作——即游戏的最后实现,玩家排雷然后判断游戏失败或胜利,而在玩家排雷的过程中我们需要对排查区周围的一个九宫格内雷的数量进行统计,而在边缘地区,为了使数组不越界,所以我们在上面初始化数组时可以多加一行一列,这样就不会越界了;
清楚上面这些内容后,我们发现扫雷其实并不难,就是实现4个函数就可以完成了,所以下面我们就可以动手来实现相关代码了:
首先是头文件game.h完成相关声明
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define mine_count 10//雷的数量
#define LIN 9
#define ROW 9
#define LINS 11 //为了不越界多加一行一列
#define ROWS 11
void Init(char arr[LINS][ROWS], int lins, int rows, char set);
void Print(char arr[LINS][ROWS], int lin, int row);
void Setmine(char arr[LINS][ROWS], int x, int y, int count);
void Play_game(char arr[LINS][ROWS], char arr1[LINS][ROWS], int lin, int row);
再就是函数game.h相关代码及注释
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Init(char arr[LINS][ROWS], int lins, int rows, char set)
//初始化函数为了方便多加一个参数char set,一次完成对多个数组的初始化
{
int i = 0;
//设置行
for (i = 0; i < lins; i++)
{
int j = 0;
//设置列
for (j = 0; j < rows; j++)
{
arr[i][j] = set;
}
}
}
void Print(char arr[LINS][ROWS], int lin, int row)//打印阵函数
{
int i;
printf("------ 扫雷 -----\n");
for (i = 0; i <= lin; i++)
{
printf("%d ", i);//打印行
}
printf("\n");
for (i = 1; i <= lin; i++)
{
int j = 1;
printf("%d ", i);//打印列
for (j = 1; j <= row; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
printf("------ 扫雷 -----\n");
}
void Setmine(char arr[LINS][ROWS], int lin, int row, int count)//设置雷函数
{
int x = 0, y = 0;
while (count)
{
x = rand() % 9 + 1; //%9+1使x和y的范围是在1~9之间随机数
y = rand() % 9 + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '0' + 1;
count--;
}
}
}
static int Getminecount(char arr[LINS][ROWS], int x, int y)//统计坐标周围雷个数的函数
{
return arr[x - 1][y - 1] + arr[x - 1][y] + arr[x - 1][y + 1]
+ arr[x][y - 1] + arr[x][y + 1] + arr[x + 1][y - 1] +
arr[x + 1][y] + arr[x + 1][y + 1] - 8 * '0';
//统计坐标(x,y)周围雷的个数
}
void Play_game(char arr[LINS][ROWS],char arr1[LINS][ROWS], int lin, int row)//游戏实现函数
{
int x, y, count = 0; //count统计排查区域的数量
while (count < (lin * row - mine_count)) //当大于时游戏胜利
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
system("CLS"); //清除屏幕使界面看起来更加好看
if ((x >= 1 && x <= 9) && (y >= 1 && y <= 9))
{
if (arr1[x][y] != '0')
{
printf("游戏失败!\n继续游戏请输入1,退出游戏请输入0\n");
Print(arr1, LIN, ROW);
break;
}
else
{
int n = Getminecount(arr1, x, y);
arr[x][y] = '0' + n;
system("CLS");
Print(arr, LIN, ROW);
count++;
}
}
else
printf("坐标越界,输入错误\n");
}
if (count == (lin * row - mine_count))
{
printf("恭喜你,游戏胜利");
}
}
最后就是实现sweep_mines.c代码来完成游戏运行
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void scene()
{
printf("******************************\n");
printf("*********** 1.play *********\n");
printf("*********** 0.exit *********\n");
printf("******************************\n");
}
void game()
{
char mine[LINS][ROWS];
char show[LINS][ROWS];
Init(mine, LINS, ROWS, '0'); //初始化雷阵
Init(show, LINS, ROWS, '*'); //初始化展示阵
Print(show, LIN, ROW); //打印展示阵
Setmine(mine, LIN, ROW, mine_count);//设置雷
//Print(mine, LIN, ROW); //打印雷阵更加直观看到雷在哪方便调试最后记得删除
Play_game(show,mine, LIN, ROW); //游戏实现
}
int main()
{
int a;
scene();
srand((unsigned int)time(NULL));
printf("请输入数字选择对应功能:");
do
{
scanf("%d", &a);
switch (a)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入非法,请重新输入\n");
}
} while (a);
return 0;
}
这样我们就完成了一个简易版扫雷了,如果还想对其进行完善,可以在后面和我一起学完递归后再来实现。