简单扫雷的实现

目录

扫雷实现的思路

表盘的实现

布置地雷

进行扫雷


扫雷实现的思路

        扫雷是一款人尽皆知的小游戏,使用c语言就可以把它简单的实现起来,如:

        如上图所示,可以看到扫雷的实现首先就要打印出一个棋盘,规模大小自行决定,本文就使用9×9的规格进行讲解。设置好棋盘我们就要“藏雷”,比如我们可以随机地放进10颗地雷进入表盘,所以这时候就要再创建一个表盘,这部分完成后,我们就可以开始输入坐标扫雷,在游戏结束的时候展示出“藏雷”的表盘就行。游戏内容的实现如下所示:

void gogame()//游戏内容
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//初始化
	init(mine, ROWS, COLS, '0');
	init(show, ROWS, COLS, '*');
	//放雷
	set(mine, ROW, COL);
	//展示
	display(show, ROW, COL);
	//排雷
	find(mine,show,ROW,COL);


}

表盘的实现

        首先为进入游戏设置好入口:

int main()
{
	srand((unsigned int)time(NULL));//设置随机数起点,下文有说明
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				gogame();
				break;
			case 0:
				printf("游戏结束\n");
				break;
			default:
				printf("输入错误,请重新刷输入\n");
				break;
		}
	} while (input);//输入0时退出循环



	return 0;
}

        首先我们要创建9×9的表格,这可以通过二维数组来实现,在此之前我们先建立头文件进行定义宏和引头文件方便源文件的使用。

#include <stdio.h>
#define ROW 9//行
#define COL 9//列

创建表盘的时候我们思考一个问题,扫雷是如何进行游戏的?我们知道一个位置周围有几个雷就会显示数字代表雷的个数,那我们思考在这下面几个位置怎么检测周围的雷呢?

 我们可以看出这些位置并非周围都有空间,如果想要和其他的位置一样检测,我们可以通过加格子来实现,在上下左右各加上一行一列用11×11表盘方便于布置地雷,展示表盘则为9×9。这个顾虑解决之后我们就开始正式初始化表盘了(其中展示的棋盘用*来表示空格,布置雷的棋盘用0来表示旗子,1来表示雷)。

#include <stdio.h>


#define ROW 9
#define COL 9

#define ROWS 11
#define COLS 11
#define COUNT 10//雷的个数

void init(char str[ROWS][COLS],int row,int col,char a)//初始化数组
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			 str[i][j] = a;
		}

	}

初始化棋盘后,我们要展示出来效果如本文第一张图所示代码如下:

void display(char str[ROWS][COLS], int row, int col)//展示雷盘
{
	printf("*******扫雷游戏********\n");//用于分割便于查看
	int i = 0;
	int j = 0;
	for (j = 0; j <= col; j++)//打印列数
	{
		printf("%d ", j);
		
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//打印行数
		for (j = 1; j <= col; j++)
		{
			printf("%c ", str[i][j]);
		}
		printf("\n");
	}
	printf("*******扫雷游戏********\n");

}

布置地雷

        实现表盘后,就要开始游戏的内核:布置地雷。我们知道虽然我们创建了11×11的表盘,但布雷还是要在其中的9×9范围进行,这次的布雷我们使用电脑随机下雷,更为方便。这里要使用rand函数和time函数,详情再此不过多阐述,主要的功能就是产生随机数(有需要的小伙伴可查看上篇博客或者使用MSDN工具自行查阅)。

void set(char str[ROWS][COLS], int row, int col)//布置地雷
{
	int x = 0;
	int y = 0;
	int t = COUNT;
	while (t)
	{
			x = rand() % row + 1;
			y = rand() % col + 1;
			if (str[x][y] == '0')
			{
				str[x][y] = '1';
				t--;
			}
		
		
	}


}

设置好地雷后我们可以打印出来看一下情况,当然在正式运行过程中不会打印出来。

 我们可以看到用1来表示的地雷共有十个。这一步就算完成了。


进行扫雷

        完成上述几步后,就来到了最后一个模块,我们知道在游玩扫雷时不仅会显示周围雷的个数,在一大片位置没有雷的情况会自动展开就如下图所示:

 它的原理是如果你的周围没有地雷你会变成空格,接着进行对你周围的位置再次进行检测,如果符合周围无雷的情况就会再次变成空格,直到有一个位置周围存在雷,这个循环就会结束,所以这里就要用到函数的递归来实现。其次地雷的个数是怎么判断的呢?我们上面是用字符1来表示地雷,‘1’-‘0’由ascll表可知结果为1,那么周围有几个‘1’就代表有几个雷,我们将周围的结果加一起所显示的就是周围雷数。

int getmine(char mine[ROWS][COLS],int x,int y)//检测坐标周围地雷个数
{
	
		return (mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x][y - 1] +
		mine[x + 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y + 1] +
		mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0');

}

解决好个数问题,扫雷的详情就如以下代码所示(其中一些细节由注释解释):

void find(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)//扫雷(具有展开功能)
{
	int x = 0;
	int y = 0;
	int t = 0;
	while (t < row * col - 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");
					display(mine, ROW, COL);
					break;
				}
				else
				{
					t++;
					int count = getmine(mine, x, y);
					if (count == 0)
					{
						show[x][y] = ' ';
						spread(mine,show,x,y,ROW,COL);展开功能的函数,具有递归效果
						display(show, ROW, COL);
					}
					else
					{
						show[x][y] = count + '0';//以字符形式表示数字
						display(show, ROW, COL);

					}
				}
			}

			else
			{
				printf("坐标已被排查,请重新输入\n");
			}
		}
		else
			printf("非法输入,请重新输入坐标\n");

	}
	if (t == row * col - COUNT)
	{
		printf("扫雷成功,游戏胜利!\n");
		display(mine, ROW, COL);

	}

}
void spread(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y,int row,int col)//展开空格
{
	int a = 0;
	int b = 0;
	int count = 0;
	if (x >= 1 && x <= row && y >= 1 && y <= col)
	{
		for (a = -1; a <= 1; a++)
		{
			for (b = -1; b <= 1; b++)
			{
				if (mine[x + a][y + b] == '0')
				{
					count = getmine(mine, x+a, y+b);
					if (count == 0)
					{
						if (show[x + a][y + b] == '*')//保证没被排查过
						{
							show[x + a][y + b] = ' ';
							spread(mine, show, x + a, y + b, ROW, COL);//递归
						}
					}
				}
				else
				{
					show[x][y] = count + '0';
					display(show, ROW, COL);

				}
			}
		}
	}

}

这样一来整个程序就完成了,玩家可以通过更改宏自行更改表盘的规模和地雷的个数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值