【C语言】250来行代码实现的无页面扫雷

1 程序功能

  1. 大体还原windows原版扫雷玩法
  2. 用户用键盘入坐标来打开或(取消)标记一个格子
  3. 连锁打开格子的上下左右四个方位的非雷格子(递归实现)
  4. 失败后会显示雷的位置
    (ps:第一次点开格子也有可能会死,要的就是刺激)

2 程序思路

  1. 定义一个结构体用来存放一个格子的各种信息
  2. 用一个二维数组来构建棋盘,每一个元素都是格子结构体
  3. 显示棋盘时,根据格子的信息决定打印内容

3 开始编码

首先要定义前面说的“格子结构体”

typedef struct square_struct {
   
	int number;
	bool landmine; //0无雷,1有雷
	bool mark; //0没标记,1标记
	bool open; //0被打开,1没被打开
} square;

这里我用typedef定义了格子类型,方便后面使用

其次是要定义二维数组并“初始化”

int main(void){
   
    square land[MAX_WIDTH][MAX_LENGTH];
}

我定义了initalize函数用来初始化棋盘,它用一个二维数组(棋盘)作为参数land,包含以下功能:

  1. 给二维数组铺满格子
  2. 随机地给棋盘布雷
  3. 给非雷的格子写上数字

第一项:铺格子

/*填充方块*/
	for (int i = 0; i <= MAX_WIDTH - 1; ++i) {
   
		for (int j = 0; j <= MAX_LENGTH - 1; ++j) {
   
			land[i][j] = (square) {
   
				0, 0, 0, 0
			};
		}
	}

可以注意到,我给每个方块结构体赋值的时候做了强制转换
这是因为结构体内的每个数据都可以表示为int,赋值时直接写

land[i][j] = {
   0, 0, 0, 0};

会让编译器认为这是一个int类型的数组

第二项:布雷

/*雷区随机布雷*/
	srand((unsigned)time(0)); //设置随机数种子
	for (int i = 1; i <= MAX_LANDMINE;) {
   
		int rand_x = rand() % (MAX_WIDTH);
		int rand_y = rand() % (MAX_LENGTH);

		if (land[rand_x][rand_y].landmine == 0) {
   
			land[rand_x][rand_y].landmine = 1;
			++i; //只有成功布雷才会给i+1,保证雷数足够
		}
	}

这个就特别简单,随机生成几个坐标,把对应方块的信息改了就可以。但还是有几点需要注意:

srand((unsigned)time(0)); //设置随机数种子

我把设置种子的这一行代码写在for循环外,是因为for循环的执行速度太快了,从而使time(0)获得的时间都是“同一个时刻”获得的的相同值,随机数就不随机了。把这行代码写在for外面就可以解决这个问题。

第三项 给方块设置数字

	/*方块数字设置*/
	/*当遍历到雷时,把雷周围8个格子的数字都加1*/
	for (int i = 0; i <= MAX_WIDTH - 1; ++i) {
   
		for (int j = 0; j <= MAX_LENGTH - 1; ++j) {
   
			if (land[i][j].landmine == 1) {
   
				land[i][j].number = -10;
				if (i - 1 >= 0) {
   
					land[i - 1][j].number++;
					if (j - 1 >= 0) {
   
						land[i - 1][j - 1].number++;
					}
					if (j + 1 <= MAX_LENGTH - 1) {
   
						land[i - 1][j + 1].number++;
					}
				}
				if (i + 1 <= MAX_WIDTH - 1) {
   
					land[i + 1][j].number++;
					if (j - 1 >= 0) {
   
						land[i + 1][j - 1].number++;
					}
					if (j + 1 <= MAX_LENGTH - 1) {
   
						land[i + 1][j + 1].number++;
					}
				}
				if (j - 1 >= 0) {
   
					land[i][j - 1].number++;
				}
				if (j + 1 <= MAX_LENGTH - 1) {
   
					land[i][j + 1].number++;
				}
			}
		}
	}

我们可以遍历整个二维数组,遍历到雷的时候,给雷周围8个方块的数字加1就可以。
这里的代码也可以直接写进布雷的函数里,布一个雷,就给雷的周围8个方块数字加1,像这样:

	/*雷区随机布雷,方块数字设置*/
	srand((unsigned)time(0)); //设置随机数种子
	for (int n = 1; n <= MAX_LANDMINE;) {
   
		int i = rand() % (MAX_WIDTH);
		int j = rand() % (MAX_LENGTH);

		if (land[i][j].landmine == 0) {
   
			land[i][j].landmine = 1;

			if (i - 1 >= 0) {
   
				land[i - 1][j].number++;
				if (j - 1 >= 0) {
   
					land[i - 1][j - 1].number++;
				}
				if (j + 1 <= MAX_LENGTH - 1) {
   
					land[i - 1][j + 1].number++;
				}
			}
			if (i + 1 <= MAX_WIDTH - 1) {
   
				land[i + 1][j].number++;
				if (j - 1 >= 0) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值