数组和函数实践:扫雷游戏玩法和棋盘初始化(1)

各位少年,大家好,我是博主那一脸阳光,我们学会了数组,exturn声明外部文件,static修饰静态变量,那么很显然,我们需要用到我们学习这些,实现一个扫雷游戏。

扫雷游戏介绍以及玩法

在这里插入图片描述
在地图上布置十个雷
排查雷:如果位置是雷,就炸死了,游戏结束,不是雷,就统计 :就统计周围雷的个数,并显示。
请添加图片描述
在这里插入图片描述
这个1表示周围格子有雷,如果把所有非雷的位置找到,游戏结束,如果碰到雷游戏结束。
在这里插入图片描述

如何实现9*9扫雷

数据的分析和设计

数据结构的分析
扫雷过程中,布置雷和排查除的雷信息都需要存储,所以我们需要一定的数据结构来存储这些信息,因为我们需要在99的棋盘上布置的信息和排查雷,我们首先想到的就是创建一个99的数组来存放信息。

那如果这个位置布置雷,我们就存放1,没有布置雷就存放0.

在这里插入图片描述
那问题出来了,如果说我们要访问第0行第0列,我们知道一个方块等排查旁边一个元素,那么很显然,这里出现了越界。所以说要创建11杠11的模块来实现。

多文件的使用

我们在写一性大型游戏的时候,往往需要N多行代码,比如说这个比较小众的扫雷,就需要两百块C语言代码,我们才能达到最总目的
在这里插入图片描述
我们主要分为这三个模块性,来帮我们实现扫雷这个游戏的代码,我们会使用到自定义头文件,使用多文件会让我们代码更加方面简介,易修改。
在这里插入图片描述
我们创建了三个文件,然后我们来编写程序即可,test c我们放代码的文本,自定义函数在game。c中使用,然后放到test。c
game。h放头文件以及define定义,总之game点h是来测试游戏的。

#include<stdio.h>
void menu()
{
	printf("*******************\n");
	printf("******  1.play  ********\n");
	printf("******  0.exit  *********\n");
	printf("*******************\n");
}
int main()
{
	int input = 0;
	do
	{
		menu();
		priintf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("扫雷\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
	} while (input);
	return 0;
}

do while:如果我们打开这个游戏,肯定要玩一次,先玩一次,玩完以后再判断do-while玩不玩下次的问题(1)代表false玩,0代表true假不玩,我们这里不需要多判断用switch语句是最好的。
好,我们把扫雷换成自定义函数game(),来实现这个游戏

#include<stdio.h>
void menu()
{
	printf("*******************\n");
	printf("******  1.play  ********\n");
	printf("******  0.exit  *********\n");
	printf("*******************\n");
}
int main()
{
	int input = 0;
	do
	{
		menu();
		priintf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			void game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
	} while (input);
	return 0;
}

假设我们排查(2,5)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数是1
假设我们排查(8,6)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数时,最下⾯的三
个坐标就会越界,为了防⽌越界,我们在设计的时候,给数组扩⼤⼀圈,雷还是布置在中间的99的坐
标上,周围⼀圈不去布置雷就⾏,这样就解决了越界的问题。所以我们将存放数据的数组创建成11
11
是⽐较合适。
排雷的假设 周围加上⼀圈的棋盘比较合适

在这里插入图片描述
我们多谢几行的方面性比写代码限制效率高,存放数据的类型太多,容易产生歧义,在统计一个坐标周围的雷的个数的时候,可能会越界。

雷的隐秘,没初始化。

我们在棋盘上布置了雷,棋盘上雷的信息(1)和⾮雷的信息(0),假设我们排查了某
⼀个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录
存储,并打印出来,作为排雷的重要参考信息的。那这个雷的个数信息存放在哪⾥呢?如果存放在布
置雷的数组中,这样雷的信息和雷的个数信息就可能或产⽣混淆和打印上的困难。
这⾥我们肯定有办法解决,⽐如:雷和⾮雷的信息不要使⽤数字,使⽤某些字符就⾏,这样就避免冲
突了,但是这样做棋盘上有雷和⾮雷的信息,还有排查出的雷的个数信息,就⽐较混杂,不够⽅便。
这⾥我们采⽤另外⼀种⽅案,我们专⻔给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,再
给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息。这样就互不⼲扰了,把雷布置到
mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期
排查参考。
同时为了保持神秘,show数组开始时初始化为字符 ‘*’,为了保持两个数组的类型⼀致,可以使⽤同⼀
套函数处理,mine数组最开始也初始化为字符’0’,布置雷改成’1’。如下

在这里插入图片描述

char mine[11] [11]//雷用1表示非雷0表示

在这里插入图片描述


```c
char show[11] [11]//雷用1表示非雷0表示
```对应的数组应该是:
char mine[11][11] = {0};//⽤来存放布置好的雷的信息
char show[11][11] = {0};//⽤来存放排查出的雷的个数信息
大家想象,如果想玩大点的扫雷游戏,不要九乘九了,要20*20是不是要更改的很麻烦
所以说这里来头文件定义两个宏
game.H
#define ROW 9
#define COL 9//后面会使用
#define ROWS ROW+2
#define COLS 11
void game()
{
char mine[ROWS][COLS]
char show[ROWS][COLS]
}

这样方便了不少,我们修改上面的宏改变整个数组的大小,改变扫雷游戏的大小。

初始化棋盘

我们写一个自定义函数 来把这个扫雷的棋盘初始化,写出来,我们自定义一个InitBoard函数,给他传三个参数

InitBoard(mine,ROWS,COLS);

你要初始化布置雷的数组你也要初始化,隐藏数组show

InitBoard(show,ROWS,COLS);

game.h这里需要放一个函数的声明,如果以后后期改游戏配置会在game头文件中更改

void InitBoard(char arr[ROWS][COLS], int rows, int cols);

然后我们在game .c里实现

#include"game.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = 0;
		}
	}
}

那问题出来了,我们得初始化o,那么*就是遮住棋盘的符号怎么打印呢?再写一个,是可以的,但是有点挫,那我们如何用一个game点c的模板,完成两个数组的初始化呢?那我们再传入一个参数**或者0传进去
test。c

void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	InitBoard(mine, ROWS, COLS,'0');
	InitBoard(show, ROWS, COLS,'*');

}

game .c

#include"game.h"

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;
		}
	}
}

.game.h

```c
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set);

我们实现了扫雷棋盘的打印,通过循环的方式把扫雷的基本模型实现了,但是我们得打印出来呀?判断输赢呀?
由于篇幅的问题,我们只能下篇分析介绍

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小敖探花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值