扫雷全盘解析

1.程序思路

1.1扫雷游戏的背景

假设游戏为一个9x9的棋盘,那么实际就要实现一个9x9的二维数组。而扫雷游戏的规则,是点击一个元素时,若踩到雷,则游戏失败;若没踩到雷,那么在当前元素显示出此元素一周的炸弹数。

图1:(点击的时棋盘中间部分)(图中1为雷,0为空,图二同)

图2:(点击的是棋盘边缘部分)

想要实现边缘部分,我们可以将边缘的外边扩展出来,并且里面的所有元素都为0,就相当于我们创建了个11*11大小的棋盘,但是只显示当中9*9的部分。

所以要实现扫雷的基础游戏规则,就是要计算出点击元素边缘的雷的个数。

2.代码程序

2.1拆分游戏

将游戏分为多个板块。在游戏未正式开始前,有一个选择菜单,游戏开始后,会出现一个棋盘,棋盘内有雷,我们称为为(装盘和装雷),然后,我们通过输入坐标来实现点击元素的过程,点击后当前元素变为周围雷的个数。

2.2菜单

实现菜单部分,将菜单封装为函数,并使用switch来进行选择。选择1则进行游戏部分,选择0则推出游戏

2.3游戏本体部分

2.3.1创建棋盘

由上述游戏背景所知,我们需要创建一个二维数组来作为棋盘,并且我们需要创建两个数组,一个作为开发者的棋盘,另一个作为游玩者的可使棋盘。

这里即创建成功棋盘,注意二维数组的类型是char 因为我们要存放的是字符。

其中RET和LINE是我们在头文件中已经定义好的,即大棋盘(11*11)的长宽。而Ret和Line则是我们需要将这个大棋盘的内部展示的棋盘的长宽。

2.3.2初始化棋盘

创建好棋盘后,需要先把棋盘初始化。我们把开发者棋盘初始化为0,后续放炸弹(1)的时候会方便;把游玩者的棋盘初始化为*,作成一种不可见的状态。

定义一个函数:


StartMine(ViewMineC,'*');
StartMine(rawMineC,'0');

void StartMine(char Minec[RET][LINE],char set)
{
	int i = 0;
	for (i = 0; i < RET; i++)
	{
		int j = 0;
		for (j = 0; j < LINE; j++)
		{
			Minec[i][j] = set;
		}
	}
}

分别将二维数组传进函数,并把初始化的内容封装为一个set传进函数。注意,这里的初始化是把整个大棋盘都初始化。

2.3.3检查棋盘(打印棋盘)

初始化好棋盘后,我们要检查棋盘,那么就要把棋盘打印出来。这里注意的是,我们需要的是大棋盘中心的那一部分,即长宽是Ret和Line的二维数组。并且,我们需要在所展示出来的棋盘旁显示出坐标。封装一个函数:

void DisplayMine(char Mine[RET][LINE], size_t ret, size_t line)
{
	printf("***********扫雷************\n");
	int i = 0;
	for (i; i <= ret; i++)
	{
		printf("%d  ", i); //打印出第一行数字作为坐标x轴
	}
	printf("\n");
	for (i = 1; i <= ret; i++)
	{
		int j = 1;
		printf("%d  ", i); // 打印出第一列作为坐标y轴
		for (j = 1; j <= line ;j++)
		{
			printf("%c  ", Mine[i][j]); // 打印数组
		}
		printf("\n");
	}
}

把这个函数封装完成后对后续的检查以及编写都有帮助。

2.3.4下雷

然后我们救要开始将雷放进棋盘。这里有一个注意点,我们只需要把雷放进开发者的棋盘,而不是把雷放进游玩者可视棋盘。

那么为了在棋盘内能随机下雷,那么我们就需要时间戳来让每次形成的坐标都不同。不过也不一定每次形成的坐标都不同,所以在每次下雷前我们要检查此坐标是否已经是雷,若不是,再安放。

这里放雷是放进(Ret,Line)大小的棋盘内

SetMine(rawMineC, Ret, Line);

void SetMine(char Mine[RET][LINE], size_t ret, size_t line)
{
	srand((unsigned int)time(NULL)); //定义rand

	int mines = Easy_mode; //设置雷的个数
	while (mines)
	{
		int x = rand() % ret + 1; //这里%ret+1后x的范围就在目标棋盘大小内
		int y = rand() % line + 1;
		if (Mine[x][y] == '0') //检查是否已经是雷
		{
			Mine[x][y] = '1';
			mines--;
		}
	}
}
2.3.5找雷

找雷要完成的逻辑:输入坐标,若此坐标不是雷,则显示出附近雷的个数,并执行下一次找雷;若踩到雷,那么游戏结束,并展示棋盘 。

void FindMine(char Mine[RET][LINE],char show[RET][LINE],size_t ret, size_t line)
{
	int mines = ret * line - Easy_mode; // mines即成功通关所需走的次数
	while (mines) //
	{
		int x = 0;
		int y = 0;
		printf("请输入坐标--->\n");   
		scanf("%d %d", &x, &y);    //输入坐标
		int mine = calMines(Mine, x, y);  //封装一个函数来计算附近雷的个数
		if (x <= ret && x > 0 && y <= line && y > 0)  //坐标要符合要求
		{
			if (Mine[x][y] == '1')
			{
				printf("抱歉,踩到炸弹了\n");
				DisplayMine(Mine, ret, line);
				break;
			}
			else
			{
				show[x][y] = mine + '0';  //因为是char类型的数组,要显示出个数,那么只要用计算 
                                            好返回来的值加上‘0’即可
				mines--;
				DisplayMine(show, Ret, Line);
			}
		}
	}
}

其中计算附近雷的个数封装一个函数:

char calMines(char set[RET][LINE], int x, int y)
{
	return set[x - 1][y - 1] + set[x - 1][y] + set[x - 1][y + 1] +
		set[x][y - 1] + set[x][y + 1] +
		set[x + 1][y - 1] + set[x + 1][y] + set[x + 1][y + 1]
		- 8 * '0';
}

2.4函数申明

将函数申明全部放进头文件中,避免重定义

3.完

感谢阅读^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值