C语言实现低端扫雷

目录

前言

一、制作游戏菜单

二、棋盘初始化

三、打印棋盘

四、布置雷

五、排查雷

总结

        不足之处与完整代码



前言

         上图就是扫雷游戏了,在这个9*9的图形内有10个雷,图中方格内的数字表示它周围8个格子内有多少个雷,排查出所有的雷就能获得胜利

        我们在实现游戏的时候,需要新建三个文件,这样做具有诸多好处(作者才学浅疏,感兴趣的同学可以自行百度)
        test.c    —— 调用函数
        game.c —— 实现函数
        game.h —— 声明函数

在两个源文件(.c)里引用头文件(.h)就可以把三个文件联系在一起了


 一、制作游戏菜单

        首先我们需要制作一个游戏菜单,能够很好地满足玩家的需求,创建一个函数打印菜单能够提高代码的利用效率,使代码看上去更加简洁美观

test.c

#include "game.h"
//需要用到的头文件(如#include <stdio.h>)已经在game.h中引用

void menu()
{
	printf("{************************************}\n");
	printf("{************ 《 扫雷 》 ************}\n");
	printf("{************************************}\n");
	printf("{**** 0.exit ************ 1.play ****}\n");
	printf("{************************************}\n");
}



int main()
{
	int input;//接收玩家输入的内容
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:printf("退出游戏\n");
			break;
		case 1:printf("扫雷\n");
			game();
			break;
		default:printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

完成上述步骤后建议调试运行检查一下,当前代码运行结果如下:


二、棋盘初始化

        接下来我们要在test.c文件内的game函数中实现我们的游戏

构思:我们需要创建一个9*9的二维数组;布置10个雷,并且记录雷的位置信息;然后还需要能够计算一个方格的周围8格有多少个雷,并且把结果返回到数组中

1.临界方格周围8格与中间方格周围8格的计算雷的个数具有差异

2.对一个数组进行许多繁琐的操作比较困难

解决方案:创建两个11*11的二维数组,一个记录布置的雷的信息,一个记录玩家排查的信息

game.h

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2

#include <stdio.h>

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

game.c

#include "game.h"

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i, j;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}
test.c

void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//棋盘初始化
	InitBoard(mine, ROWS, COLS, '0');//->'0'
	InitBoard(show, ROWS, COLS, '*');//->'*'
}


三、打印棋盘

1.在(test.c中的)game函数中构思需要用到的函数

2.在game.h中声明函数

3.在game.c中实现函数

4.在test.c中调用函数

当前代码调试运行结果如下:

         但是,我们不容易一眼就看出来 ‘ * ’ 在第几行第几列,可以稍微优化一下,打印出行号和列号:

game.c

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i, j;
	//打印列号
	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 ", board[i][j]);
		}
		printf("\n");
	}
}


四、布置雷

构思:我们接下来要在存放布置雷的数组里布置10个雷,rand()%row生成一个0~8的随机数,再+1就可以生成一个1~9的随机数了,我们还需要考虑到即将布置雷的位置已被占用的情况

game.c

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//EASY_COUNT=10,便于调整雷的数量
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

当前代码调试运行结果如下:


五、排查雷

构思:在玩家排查雷输入坐标的时候,需要考虑4种情况

1.该坐标已被占用

2.该坐标是雷--游戏结束

3.该坐标不是雷,计算周围8格雷的个数

        在计算雷的数量时,利用布置雷的数组mine,将周围8格数组元素的值加起来就能得到雷的个数,但是数组的类型为char,所有还需要减去8个字符'0',就能得到我们需要的值了,然后赋给show数组坐标相同的元素即可

4.所有的雷都已被排查--游戏结束

game.c

int GetMineCount(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 FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int win = 0;
	while (win<row*col-EASY_COUNT)
	{
		printf("请输入要排查的坐标:>");
		scanf("%d %d", &x, &y);
		if (show[x][y] == '*')
		{
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了!\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else
				{
					//如果该坐标不是雷,就需要统计周围8格雷的个数
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("排查的坐标非法,请重新输入\n");
			}
		}
		else
			printf("该坐标已被排查!\n");
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你排雷成功!\n");
		DisplayBoard(mine, ROW, COL);
	}
}


总结

        以上就是本文的全部内容了,但是本文编写的扫雷游戏还存在需要改进的地方,比如:无法展开一片周围8格没有雷的区域,不能标记已知的雷的位置,我还会在接下来的努力改进的!

完整代码

game.h

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//棋盘初始化
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char board[ROWS][COLS], int row, int col);
game.c

#include "game.h"

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i, j;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i, j;
	//打印列号
	printf("#####《 扫雷 》#####\n");
	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 ", board[i][j]);
		}
		printf("\n");
	}
}

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//EASY_COUNT=10
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

int GetMineCount(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 FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int win = 0;
	while (win<row*col-EASY_COUNT)
	{
		printf("请输入要排查的坐标:>");
		scanf("%d %d", &x, &y);
		if (show[x][y] == '*')
		{
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了!\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else
				{
					//如果该坐标不是雷,就需要统计周围8格雷的个数
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("排查的坐标非法,请重新输入\n");
			}
		}
		else
			printf("该坐标已被排查!\n");
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你排雷成功!\n");
		DisplayBoard(mine, ROW, COL);
	}
}
test.c

#include "game.h"

void menu()
{
	printf("{************************************}\n");
	printf("{************ 《 扫雷 》 ************}\n");
	printf("{************************************}\n");
	printf("{**** 0.exit ************ 1.play ****}\n");
	printf("{************************************}\n");
}

void game()
{
	char mine[ROWS][COLS] = { 0 };//存放布置的雷的信息
	char show[ROWS][COLS] = { 0 };//存放玩家排查的信息
	//棋盘初始化
	InitBoard(mine, ROWS, COLS, '0');//->'0'
	InitBoard(show, ROWS, COLS, '*');//->'*'
	//打印棋盘(打印9*9的棋盘即可)
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);

	//布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, ROW, COL);

	//排查雷
	FindMine(mine, show, ROW, COL);
}

int main()
{
	int input;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:printf("退出游戏\n");
			break;
		case 1:printf("扫雷\n");
			game();
			break;
		default:printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

φ冰霰ξ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值