《扫雷》是一款大众类的益智小游戏,雷区中随机布置一定数量的地雷,玩家需要尽快找出所有不是地雷的方块,但不许踩到地雷。
一、游戏简介及思路
笔者以99一共81个格子的扫雷为例,我们可以把每一个格子中的数据都对应到一个99的二维数组的相应位置之中。而二维数组相关的知识也就给予了我们把扫雷游戏实现下去的可能性。
-
首先我们需要两个二维数组,一个用来存放生成的雷的位置,一个则用来生成玩家看到的截面。对两个数组进行初始化,把第一个数组全部放入‘0’,第二个数组全部放入‘ * ’ 。但如果我们是要做99的扫雷的话数组就要是1111的数组,因为当你选定一个坐标后是会显示这个坐标周围8个格子中雷的数目。如果数组也是9*9的话那么选择边界坐标时就会导致数组越界。
-
第二步是生成雷,通过rand()函数生成的随机坐标将生成的10个雷放入坐标中去。这里要注意生成的时候坐标不能够重复,且数组的两个下标都要在1到9之间。
-
最后把对应坐标周围的雷的个数传递到第二个数组中再打印出来即可。这里要注意我们用的数组是char型的,那么放入第一个数组中的‘0’是以ASCII码值的形式存在的,对应的是48,如果有一个雷就把‘0’+1,最后直接放入第二个数组就是对应个数的ASCII值。
二、实现逻辑及代码
1、主程序的实现
- 实现逻辑:
首先建立test.c用来实现主程序,打印出菜单之后再通过do while 语句和switch语句的嵌套来实现游戏的开始与退出。
- 实现代码:
int main()
{
printf("*************************\n");
printf("*******开始游戏(1)*******\n");
printf("*******结束游戏(0)*******\n");
printf("*************************\n");
int a = 0;
do
{
printf("请输入:");
scanf("%d", &a);
char arr1[hang][lie] = { 0 };
char arr2[hang][lie] = { 0 };
switch (a)
{
case 1:
srand((unsigned int)time(NULL));
printf("游戏开始:\n");
sl(arr1, arr2);
printf("游戏结束,是否开启下一把(1.是 0.否)。\n");
break;
case 0:
break;
default:
printf("输入错误,");
}
} while (a);
printf("游戏结束。\n");
return 0;
}
2、游戏函数的实现
- 游戏主体函数实现:
首先进入函数要先把2个数组传递过去,传递过去之后对两个数组进行初始化。把第一个数组全部放入‘0’,第二个数组全部放入‘ * ’。之后再生成雷的数据放入第一个数组之中。完成之后进入do while循环。每次循环打印一次棋盘,玩家下一次棋。当玩家排完所有雷之后游戏胜利,即在这里玩家下了71次之后还没有踩到雷。
void sl(char arr1[hang][lie],char arr2[hang][lie])
{
int a = 1;
int sum = 1;
ini(arr1, '0');
ini(arr2, '*');
create(arr1);
//print(arr1);//作弊模式
do
{
print(arr2);
a = start(arr1, arr2, sum);
sum++;
} while (a);
}
3、函数声明
- 在game.h文件中进行声明
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define hang 11
#define lie 11
#define hangs 9
#define lies 9
void ini(char arr[hang][lie], char a);//初始化数组
void create(char arr1[hang][lie]);//生成10个雷
void print(char arr[hang][lie]);//打印棋盘
int start(char arr1[hang][lie], char arr2[hang][lie], int sum);//游戏函数
4、游戏运行函数实现
- 初始化函数:
由于两个都是11*11的char型二维数组,所以可以通过同一个函数来实现初始化。其中这里的a分别用来接收‘0’和‘ * ’。
void ini(char arr[hang][lie], char a)
{
for (int i = 0; i < hang; i++)
{
for (int j = 0; j < lie; j++)
{
arr[i][j] = a;
}
}
}
- 生成雷的函数
生成雷的时候数组的x坐标和y坐标一定都要在1到9之间。同时不能够重复设置在一个坐标之中。
void create(char arr1[hang][lie])
{
int x = 0;
int y = 0;
for (int i = 0; i < 10; i++)
{
do
{
x = rand() % 9 + 1;
y = rand() % 9 + 1;
if ('0' == arr1[x][y])
{
arr1[x][y] = '1';
break;
}
} while (1);
}
}
- 打印函数
为了看起来美观,在打印棋盘的同时可以把格子打印出来,类似与三子棋的效果。代码实现思路可见我以前的三子棋博客
http://t.csdn.cn/T8GY4
实现之后效果如图:
void print(char arr[hang][lie])
{
printf(" 1 2 3 4 5 6 7 8 9\n");
for (int i = 1; i <= hangs; i++)
{
printf("%d ", i);
for (int j = 1; j <= lies; j++)
{
if (j < lies)
printf(" %c |", arr[i][j]);
else
printf(" %c \n", arr[i][j]);
}
if (i < hangs)
{
printf(" ");
for (int j = 1; j <= lies; j++)
{
if (j < lies)
printf("---|");
else
printf("---\n");
}
}
}
}
- 玩家操作函数
这里的实现较为复杂,首先要把玩家输入的坐标存储起来,然后取出这个坐标对应八个位置的坐标,判断他们是否为1,为1则‘0’+1,在找完周围8个坐标后把它放入第二个数组的对应位置替换
‘ * ’。同时要注意输入的坐标范围不能超出1~9而且不能重复,否则重新输入。只有输入成功之后sum才会+1.
int start(char arr1[hang][lie], char arr2[hang][lie],int sum)
{
int x = 0;
int y = 0;
char s = '0';
printf("请输入坐标:");
do
{
scanf("%d %d", &x, &y);
if (((x >= 1 && x <= 9) && (y >= 1 && y <= 9)) && ('*' == arr2[x][y]))
{
if ('1' == arr1[x][y])
{
printf("挖到雷了,");
return 0;
}
else
{
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if ('1' == arr1[i][j])
s++;
}
}
arr2[x][y] = s;
}
break;
}
else
printf("非法坐标,请重新输入坐标:");
} while (1);
if (sum < hang * lie - 10)
return 1;
else
{
printf("恭喜您游戏获胜!\n");
return 0;
}
}