如果我们想用C语言学过的函数数组的方法写一个扫雷游戏,应该怎么来做呢?
首先,我们考虑扫雷游戏的开始以及结束游戏的方法,在打开时,我们会看到一个菜单,让我们选择开始游戏或者结束游戏,我们写一个函数来表示菜单
void mune() {
printf("\a");
printf("--------扫雷游戏--------\n");
printf("************************\n");
printf("*******1.开始游戏*******\n");
printf("*******0.退出游戏*******\n");
printf("************************\n");
}
很好,现在我们想实现输入1开始游戏,输入0结束游戏,同时我们在玩完一局后还可以在选择是否再进行游戏,因此,我们可以设置一个循环,主程序中的代码如下:
int main() {
int i = 0;
do {
mune();
scanf("%d", &i);
switch(i) {
case 1:
system("cls");
printf("开始游戏\n");
break;
case 0:
printf("再见\n");
break;
default:
printf("输入错误,请重新输入");
break;
};
} while (i);
return 0;
}
在这个循环中,会先显示菜单,如果我们输入1会跳出开始游戏,输入0会显示再见,输入其他数字会显示输入错误,然后再进行这个循环,循环结束的条件是i=0,此时正好是case 0的情况。
其中,代码:
system("cls");
含义是情况当前界面,可以让我们的屏幕更加清晰
很好,现在我们只需要写关于开始游戏的内容就可以了
我们计划设计一个最简单的扫雷游戏,我们平时玩的扫雷游戏的样式如下:
我们主要还原方框里的内容,这是个9*9的方框,里面放入10个地雷,我们实现的顺序实际就是埋地雷和找地雷的过程
如果我们想放置地雷,就需要一个9*9的二维数组,来进行放置,在排查雷的过程,如果我们踩到了地雷,就会直接游戏失败,如果我们没有踩到地雷,就会显示这个方格周围八个格子中地雷的数目,但是我们发现,如果我们只设置一个9*9的二维数组的话,我们在检测的时候可能会出现越界的情况,因此,我们可以考虑扩大范围,设置11*11的数组。
同时,我们要有一个数组拿来埋地雷,另一个展示给游戏玩家看,所以我们应该创建两个二维数组。
在编写代码之前,我们先把需要的变量进行定义,ROW代表游戏行数,COL代表游戏列数,EasyCount代表地雷个数,ROWS,COLS代表需要创建的数组的情况。
#define EasyCount 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
char game[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
如图,我们创建了两个数组,这两个数组的初始值都是0
game数组用于放置地雷,show数组用来给游戏玩家展示
对于game数组而言,我们可以让所有没地雷的位置为0,所有有地雷的位置放1,对于show数组,我们可以让未检测的位置为*,检测的位置为数字,因此我们需要进行一下初始化。
我们写这样的函数:
void InitBoard(char arr[ROWS][COLS], int a , int b , char k)
{
int i = 0, j = 0;
for (i = 0; i < a; i++) {
for (j = 0; j < b; j++) {
arr[i][j] = k;
}
}
}
对于这个函数而言,我们需要输入数组名,数组的行数和列数,以及我们需要赋值的字符‘k’,就会把这个数组的所有内容都进行赋值为k。
InitBoard(game, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
我们把game全部赋值为0,show全部赋值为*
我们也可以利用遍历的方法写出一个函数,展示出我们初始化后的数组,但是,我们展示的是9*9的,所以应该这样来书写:
void ShowBoard(char arr[ROWS][COLS], int a, int b) {
int i = 0 , j = 0;
for (j = 0; j <= b; j++) {
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= a; i++) {
printf("%d", i);
for (j = 1; j <= b; j++)
{
printf(" %c", arr[i][j]);
}
printf("\n");
}
}
输入数组名,应该展示的行数和列数,就可以输出数组了
下面我们进行埋地雷的工作,由于全部是随机的,我们会运用到随机数,因此我们需要在主函数中写下:
srand((unsigned int)time(NULL));
创建一个函数,利用随机数将game数组中的某些位置放置地雷:
void MakeBoom(char arr[ROWS][COLS], int a, int b,int count) {
while (count) {
int x = rand() %a + 1;
int y = rand() %b + 1;
if (arr[x][y] == '0') {
arr[x][y] = '1';
count--;
}
}
}
我们需要让埋入的地雷数字是我们想要的,因此在这里需要加入我们要埋的地雷数量,此函数利用了while循环,可以将game数组进行好
void FindBoom(char show[ROWS][COLS], char game[ROWS][COLS], int a, int b, int count) {
time_t t1 = time(0);
int i = 0 , j = 0;
int win = 0;
TimeLoad(t1);
while (win < ROW * COL - count) {
printf("请输入一个坐标");
scanf("%d%d", &i, &j);
system("cls");
if (i > 0 && i <= ROW && j > 0 && j <= COL) {
if (game[i][j] == '1') {
system("cls");
printf("\a游戏结束,你失败了\n");
ShowBoard(game, ROW, COL);
int k = 0;
printf("请按0返回主菜单");
do {
scanf("%d", &k);
if (k) break;
} while (k);
system("cls");
break;
}
else {
int num = game[i - 1][j] +
game[i - 1][j - 1] +
game[i][j - 1] +
game[i + 1][j - 1] +
game[i + 1][j] +
game[i + 1][j + 1] +
game[i][j + 1] +
game[i - 1][j + 1] - 8 * '0';
show[i][j] = num + '0';
ShowBoard(show, ROW, COL);
win++;
}
}
else {
printf("你输入的内容非法,请再次输入\n");
}
}
if (win + count == ROW * COL) {
printf("恭喜,你赢了\n");
int t =TimeLoad(t1);
printf("你一共用时%d秒\n", t);
int k = 0;
printf("请按0返回主菜单");
do {
scanf("%d", &k);
if (k) break;
} while (k);
system("cls");
}
}
很好,我们写了排查雷的代码,让玩家输入一个坐标我们进行检测,首先判断是否越界,然后判断是否是地雷,如果排到地雷会直接失败,如果没有排到地雷,就检测附近的地雷数量,知道我们将所有的格子排查完毕,会显示我们进行游戏所用的时间。
然后将这些代码整合起来,就可以得到简单的扫雷游戏了!