扫雷游戏的实现
前言:本文讲解的是如何实现最基本的9×9的控制台模式的扫雷游戏
可以实现的功能有如下
1.可以通过游戏菜单进入或退出游戏
2.随机布置10个雷
3.如果选择的位置是雷,游戏结束
如果选择的位置不是雷,会显示周围雷的个数
1.思路分析
首先,我们需要考虑整个游戏的一个实现逻辑。
1.我们先给玩家呈现我们的菜单,之后通过玩家的选择,也就是玩家输入的数字来判断玩家是要进入游戏还是退出游戏,由此可见,这个环节我们可以通过分支结构来实现。
2.之后当玩家开始游戏后,我们首先需要给玩家呈现出一个9×9的游戏棋盘,供玩家扫雷。
3.并且我们需要放雷,在本过程中,我们是先将棋盘呈现出来,之后再放雷。
4.通过玩家的选择我们输出不同的结果,如果不是雷,我们输出这个点周围的八个点一共有几个雷,如果是雷,我们呈现出雷的排放图,再提示玩家游戏结束。由此可见,整个过程中,我们至少需要两个棋盘来实现整个过程。
2.思路实现
1.有上述思路分析,我们想到棋盘也就是数组,本游戏需要的就是二维数组。
2.因为我们需要扫出来周围的雷,而如果我们单纯设置9×9的二维数组,那么数组周围的点位在显示周围雷的个数的时候会出现问题,所以我们可以设置一个11×11的数组,将周围包起来。
3.两个棋盘,一个用来放雷,另一个用来排雷,为了整体的方便,我们都设置成字符的数组,因为这样可以使用同一套函数。
4.像这种很大的程序,里面会包含很多函数,我们可以使用多个.c文件和.h文件相互配合协作。
在这里,我将整个程序的所有函数的定义都放在game.c文件里,需要用到的函数声明和所有头文件都放在game.c文件里,而游戏过程的实现放在test.c的文件里。
3.代码实现
game.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//这些库函数的头文件都在这里写就OK了,以后只要在别的源文件里引用#include "game.h"
#include <stdlib.h>
#include <time.h>
void setboard(char arr[11][11]);
void showboard(char arr[11][11]);
void setmine(char arr[11][11]);
int check(char arr[11][11], int x, int y);
void showmine(char arr[11][11], int x, int y, char z);
test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("*******************\n");
printf("******1.play*******\n");
printf("******0.exit*******\n");
printf("*******************\n");
}
void game()
{
char arr1[11][11] = { '0' };
char arr2[11][11] = { '0' };
setboard(arr1);
setboard(arr2);
printf("*********扫雷*********\n");
showboard(arr1);
printf("*********扫雷*********\n");
setmine(arr1);
//showboard(arr1);//可以在测试的时候用来观察放置雷的情况
int i = 0, j = 0, count = 71;//81个格子,10个雷
while (count > 0)
{
printf("请输入:");
scanf("%d %d", &i, &j);
if (arr1[i][j] == '1')
{
printf("你被炸死了,游戏结束\n");
showboard(arr1);
break;
}
else
{
int a = check(arr1, i, j);
a = a + 48;
showmine(arr2, i, j, a);//输入a的时候是以字符的形式输入的,因为是字符类型的数组
count--;
}
}
if (0 == count)
{
printf("恭喜你,排雷成功\n");
}
}
int main()
{
srand((unsigned int)time(NULL));//语句,必须必须放在main函数里面。
start:
menu();
int i = 0;
begin:
printf("请选择:");
scanf("%d", &i);
switch (i)
{
case 1:
{
printf("开始游戏\n");
game();
printf("再玩一次吗?\n");
goto start;
break;
}
case 0:
{
printf("游戏结束\n");
break;
}
default:
{
printf("输入错误,请重新输入\n");
goto begin;
}
}
}
game.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void setboard(char arr[11][11])
{
int i = 0, j = 0;
for (i = 0; i < 11; i++)
{
for (j = 0; j < 11; j++)
{
arr[i][j] = '*';
}
}
}
void showboard(char arr[11][11])
{
int i = 0, j = 0, k = 0;
printf(" ");
for (k = 1; k <= 9; k++)
{
printf("%d ", k);
}
printf("\n");
for (i = 1; i < 10; i++)
{
printf("%d ", i);
for (j = 1; j < 10; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
void setmine(char arr[11][11])
{
int i = 0, j = 0;
for (i = 0; i < 11; i++)
{
for (j = 0; j < 11; j++)
{
arr[i][j] = '0';
}
}
int count = 10;
while (count > 0)
{
int r = 1 + rand() % 9;
int s = 1 + rand() % 9;
if (arr[r][s] == '0')//判断是否重复
{
arr[r][s] = '1';
count--;
}
}
}
int check(char arr[11][11], int x, int y)
{
int i = 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';//得到雷的个数,而且是数字
return i;
}
void showmine(char arr[11][11], int x, int y, char z)
{
int i = 0, j = 0, k = 0;
printf(" ");
for (k = 1; k <= 9; k++)
{
printf("%d ", k);
}
printf("\n");
for (i = 1; i < 10; i++)
{
printf("%d ", i);
for (j = 1; j < 10; j++)
{
if ((i == x) && (j == y))
{
arr[i][j] = z;
}
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
4.易错
1.我们放置的是一个11×11的数组,数组周围一圈放置的都是0,我们呈现给大家的是行1-9,列1-9,行和列的0和10是不用呈现出来的。所以在设计打印棋盘的函数的时候,注意for循环的起始和截止。
2.随机放雷的实现,有三点很重要,1.注意是生成1-9的随机数,不要生成0-10。2.行和列的随机数必须要不同,切记。3.一定要记住避免随机数的重复,所以需要一步判断。
3.写的时候一定要耐心,注意不要出现细节上的错误。