函数和数组的实现→扫雷游戏

扫雷作为童年小游戏,相信各位在玩时也好奇过它的原理如何,今天我们就借助c语言来简单的实现它。

5e14dddccac441e6859b55dfd166081a.jpg

 

前期工作:

多个文件实现:使得程序清晰明了                                  

头文件里可以进行声明,写宏定义,写包含库函数等等(并在各个源文件里所包含)。如下图:d397e971aeed404999c370939fcfed90.png

游戏过程函数→game()函数的书写:

8f0a9d3596aa49f1b6b1f24269187d67.png

游戏界面的设置:

fb415516d5b548ed93a7bad363d01e01.png

446e5fc34ec246edae7fa8a384600dd3.png

扫雷应分为两个数组进行,一个是扫雷的内在运行→包括数组的赋值、雷的设置;一个是扫雷的外在显示→包括数组的输出、排雷的结果。

 

数组初始化:

要将每个位置(即11行11列)都进行初始化,而不是单独中间的部分(即9行9列)   ,代码如下:            

void InitBoard(char arr[ROWS][COLS], int rows, int cols, int set)     //赋值要将每个位置都赋上初值
{
	int i = 0;
	int j = 0;
	//for (i = 0; i <=rows; i++)       
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j <cols; j++)
		{
			arr[i][j] = set;                     
		}
	}
}

 初始化后的结果如下:      28c04bf756724d6d933ac2f17c92fe81.png                              

布置雷

使用srand函数时,unsigned int要用括号括起来                  记得将产生随机数的过程放在循环里,这样才能产生多个随机值,否则只会产生一个随机数                              注意放置的雷是字符型'1',不是数字1,原本定义的字符'0'同理             

代码如下:

void SetMine(char arr[ROWS][COLS], int row, int col)
{
	int h = 0;
	int i = 0;
	int l = 0;
	//h = rand() % row + 1;      //要将产生随机值的过程放在循环里,这样才能产生多个随机值,否则只能生成一个随机值
	//l = rand() % col + 1;
	for (i = 1; i <= leishu; i++)     
	{  
		h = rand() % row + 1;
		l = rand() % col + 1;
	//	if (arr[h][l] == 0)   //****应注意数组中的元素是字符型*****
	//		arr[h][l] = 1;
		if (arr[h][l] == '0')
			arr[h][l] = '1';
	
	else
		i--;
	}
}

 

数组输出

输出只需要输出中间的部分(即9行9列),边围部分是防止越界的 ,代码如下:

void DisplayBoard(char arr[ROWS][COLS], int row, int col)         //输出只需要输出中间部分即可,外围是为了防止越界的
{
	int b = 0;
	int c = 0;
	int i = 0;
	int j = 0;
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (b = 1; b <= row; b++)
	{
		printf("%d ", b);                  //***这行是用来输出列序号***
		for (c = 1 ;c <= col ; c++)
		{
			printf("%c ", arr[b][c]);
		}
		printf("\n");
	}
}

                         

排查雷:将mine的内容放到show里去

字符与数字的转化:在确认排查位置周围雷数时以整形类型返回,且在外层数组上显示是以字符型形式,所以要进行字符和数字的转换                                                      转化方法:一个字符减去字符0就等于它的数字,如      '5'-'0'=5 ,反之同理

要将排查位置周围的雷数显示在外层数组上,以便玩家进行下一步排查 。确认周围雷数的代码如下:

int geshu(char arr[ROWS][COLS], int zwls, int x, int y) 
	{
	zwls = arr[x - 1][y - 1] + arr[x - 1][y + 1] + arr[x + 1][y - 1] + arr[x + 1][y + 1] + arr[x][y - 1]+
		 arr[x - 1][y] + arr[x][y + 1] + arr[x + 1][y] - 8 * '0';
	return zwls;
	}

接下来便是对游戏过程的分析:                                               1.玩家排查所以雷数获胜                    2.玩家踩到雷失败       3.玩家排查了不在数组范围(即游戏范围)内的雷--要提醒玩家重新选择                                                                               依此写出代码如下:

void FindMine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)          
{
	int zwls = 0;
	int x = 0;
	int y = 0;
	int i = 0;
	while (1)
	{
		printf("\n");
		DisplayBoard(mine, ROW, COL);
		printf("请选择你要排查的位置:");
		scanf_s("%d,%d", &x, &y);
			zwls = geshu(mine, zwls, x, y);
		//int xsls = zwls + '0';                   
		char xsls = zwls + '0';                          //显示在数组上的是字符
	//if (x >0&& x= < rows && y > 0 && y <= cols)         //rows、cols不能在内部9*9时使用
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (mine[x][y] == '0')
			{
				show[x][y] = xsls;
				DisplayBoard(show, ROW, COL);
				i++;                                  
				if (i == row * col - leishu)
				{
					printf("恭喜你,排雷成功");
					break;
				}

			}
			else
			{
				printf("你踩到雷了,游戏结束");
				InitBoard(mine, ROWS, COLS, '0');
				break;
			}
		}
		else
		{
			printf("输入错误,请重新输入\n");
			DisplayBoard(show, ROW, COL);
		}
	}
}

 

过程BUG:

编程的过程中总会因为各个情况产生bug,让人头疼不已,小编就将自己编写过程中遇到的bug展示出来,希望各位引以为戒

❶如果循环赋值等情况出现超出数组的内存→即数组元素个数,就会在运行时使该数组变量堆栈损坏          

bf6d0c607c5d408fbcc155355c1d9eba.jpg

❷自定义函数的数组参数要写上行、列,只写个数组名会报错

e7d01c4d2ea6420894ca475b7c43b2b3.jpg

 ❸定义函数如果和声明不同,在使用时会发生错误(运行不了时,也可以从警告处寻找错误)

3b55857743814b99bf65486634d2e937.jpg

 

欧克,本篇文章就到这里了,希望大家多多支持         \(`Δ’)/

 

 

 

 

 

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值