扫雷游戏设计过程
我们既然知道扫雷游戏需要满足的规则,那么就跟着思路,一步一步进入程序
游戏界面设计
首先,在游戏开始之前,有一个菜单栏,那么,我们使用printf函数来直接打印菜单,并且让用户输入选择,开始游戏,或者退出游戏。用户在选择之后,程序进行判断,是进入游戏或者退出游戏,当用户输入错误时,提示用户输入错误,请重新输入。这样整个程序的界面逻辑就出来了
void menu()
{
printf("*************************\n");
printf("******* 1. play ********\n");
printf("******* 0. exit ********\n");
printf("*************************\n");
}
void test()
{
int input =0;
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
switch (input)//根据你的选择来判断
{
case 1:
printf("开始扫雷游戏\n");
game();//游戏过程
break;
case 0:
printf("游戏结束,退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
菜单的效果是这样的
扫雷游戏棋盘设计
设置两个一样的棋盘,一个棋盘(mine)用于存放雷的信息,一个棋盘(show)对用户展示信息。mine棋盘上我们用1来表示雷,0来表示无雷,show棋盘上我们用 * 表示还没有排雷的地方,用数字来表示排雷地方周围有几个雷,由于设计方便,show棋盘中需要填充的是字符 ‘ * ’,所以mine棋盘无雷放入字符 ‘0’,埋雷放入字符 ‘1’。
同时为了方便更改后续棋盘大小我们在game.h文件中定义两个符号ROW和COL来代表棋盘长度和宽度
#define ROW 9
#define COL 9
设置和初始化棋盘
首先我们要创建两个9*9的棋盘如下
因为这样的棋盘不方便我们查看,所以我们在棋盘的左边和上边加上数字,同时,要考虑到棋盘边缘要统计周围雷的数量,所以棋盘的大小就是(ROW+2)*(COL+2)。为了方便我们后续运用,我们在定义两个符号。注意的是,我们在使用我们定义的内容时,一定要引用其头文件呦。
#define ROWS ROW+2
#define COLS COL+2
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
0 | |||||||||||
1 | |||||||||||
2 | |||||||||||
3 | |||||||||||
4 | |||||||||||
5 | |||||||||||
6 | |||||||||||
7 | |||||||||||
8 | |||||||||||
9 | |||||||||||
10 |
知道棋盘的大小之后,进行初始化,,将mine中填入字符‘0’,show棋盘中放入‘*’。
void game()//扫雷游戏
{
char mine[ROWS][COLS] = {0};
char show[ROWS][COLS] = {0};
//初始化棋盘 mine
InitBoard(mine,ROWS,COLS,'0');
InitBoard(show,ROWS,COLS,'*');
}
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
arr[i][j] = set;
}
}
}
布置雷
棋盘已经设置好了,接下来我们埋雷,我们可以随机生成两个1-9的随机数来表示雷的坐标,
int x = rand() % row + 1;
int y = rand() % col + 1;
为了后续可以更改雷的数量,我们定义一个符号
#define EASY_COUNT 10//雷
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
arr[x][y] = '1';
count--;
}
}
但是这样就可能会出现重复埋雷,所以我们在埋雷之前要先判断这个地方是否存在雷
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
}
count--;
}
}
打印棋盘
void PrintBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
printf("------扫雷游戏-----\n");
for (i = 0; i <= col; i++)//列号
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);//行号
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
经过检查我们扫雷游戏基本成型,现在进行排查雷的操作
排查雷
首先我们要给用户一个提醒“请输入要排查的坐标:”。然后要判断用户输入的坐标是否有效,同时还要注意用户坐标是否重复排查
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
printf("请输入你要排查的坐标:")
scanf("%d %d", &x, &b);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')
{
//排查规则
}
else
{
printf("您已排查,请重新输入!");
}
}
else
{
printf("坐标无效,请重新输入!");
}
}
然后我们来填充排查规则,我们知道,如果排查坐标是 ‘1’.踩到雷了,游戏结束。如果排查坐标是 ‘0’,我们就要计算周边的雷的数量。
计算雷的数量
x-1,y-1 | x-1,y | x-1,y+1 |
x,y-1 | x,y | x,y+1 |
x+1,y-1 | x+1,y | x+1,y+1 |
因为字符1与数字1相差一个字符0. 所以排查位置四周的八个坐标的字符相加再减去8个字符0就是这个坐标周围雷的个数
static int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
int count = 0;
count = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1]
+ mine[x][y - 1] + mine[x][y + 1]
+ mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1]
- 8 * '0';
return count;
}
同样我们也可以写成循环
static int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
int count = 0;
int i = 0;
int j = 0;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
count = count + (mine[i][j]-'0');
}
}
return count;
}
这样扫雷基本完成,但是我们在运行时发现,我们将不是雷的地方都已经排查清楚,但是无法退出,所以我们要加一个计数,配合while循环,这个数字就代表我们非雷的数量,用棋盘总数减去雷数减去已排查的数量来表示,如果这个数字为零,就代表排雷成功,结束游戏。
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win<row*col-EASY_COUNT)
{
printf("请输入你要排查的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
PrintBoard(mine, ROW, COL);
break;
}
else
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
PrintBoard(show, ROW, COL);
win++;
}
}
else
{
printf("您已排查,请重新输入!");
}
}
else
{
printf("坐标无效,请重新输入!");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
PrintBoard(mine, ROW, COL);
}
}
这样简单的扫雷游戏就出来了。
以上内容,如果有任何问题,请留言或私信我。期待与大家沟通交流。