C语言实现扫雷

C语言实现扫雷,第1张

C语言扫雷小游戏
  • 一、游戏介绍
  • 二、游戏功能逻辑及代码实现
    • (一)游戏大体步骤
    • (二)功能实现及代码
      • 1 、初始化雷盘
      • 2、布雷
      • 3、展示雷盘
      • 4、获取输入坐标周围雷的个数
      • 5、玩家排雷
      • 6、递归展开一片区域
      • 7、标记雷区
      • 8、取消标记
  • 三、运行展示

一、游戏介绍

  • 游戏初始化会自动翻开一片区域,每个位置上的数字代表着周围一圈存在的雷的数目;
  • 玩家可以对自己认为是雷的地方进行标记,也可以对取消自己之前错误的标记;
  • 玩家可以翻开认为是雷的地方,但是如果踩中地雷则游戏结束;
  • 当玩家排除了所有的雷,则游戏胜利;
二、游戏功能逻辑及代码实现 (一)游戏大体步骤
  • 首先用户根据游戏菜单输入选项,输入1则进入游戏,输入其他则提示错误并让用户重新输入选项:

    输入0则退出游戏。

  • 进入游戏后,用户根据菜单再选择是排雷、标记雷、还是取消标记的雷:

    如果输入错误仍然会提示信息,并重新输入:

  • 当排查出所有的雷就提示游戏胜利!(方便测试逻辑我们测试时将雷的数量布置到总格数 - 1)

(二)功能实现及代码 1 、初始化雷盘

初试化雷盘就是讲数组内赋值上相应的字符:定义两个数组,mine数组存放的是布置雷的数据(玩家不可见),show数组存放的是展示给玩家看的数据。mine数组初始化全为’0‘,show数组初始化全为’*‘。(为了防止数组越界以及代码实现在初始化时行列各自增加了2)

void init_board(char board[ROWS][COLS], int row, int col, char key) {
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++) {
		  //初始化mine 传入的就是’0’ 初始化show 传入的就是‘*’
			board[i][j] = key;
		}
	}
}
2、布雷

在mine数组中,用字符‘0’表示无雷区域,用字符‘1’表示有雷区域,在没有雷的地方随机生成坐标并放入即可。

void set_mine(char board[ROWS][COLS], int row, int col, int count) {
	while (count) {
		int i = (rand() % 9) + 1;
		int j = (rand() % 9) + 1;
		if (board[i][j] == '0') {
			board[i][j] = '1';//'1'代表是地雷
			count--;
		}
	}
}
3、展示雷盘

展示雷盘只需要打印行号、列号,并且对数组进行遍历即可。

void showboard(char board[ROWS][COLS], int row, int col) {
	printf("******扫雷游戏*******\n");
	//打印列号 方便对照查看
	for (int i = 0; i <= col; i++) {
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; i++) {
		printf("%d ", i);//打印行号
		//打印数据
		for (int j = 1; j <= col; j++) {
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("******扫雷游戏*******\n");
}
4、获取输入坐标周围雷的个数

将mine数组中mine[x][y]周围的成员与‘0’做差,然后累加到一起得到的就是(x,y)周围的雷的个数。

int get_mine(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y] - '0' +
		mine[x - 1][y - 1] - '0' +
		mine[x][y - 1] - '0' +
		mine[x + 1][y - 1] - '0' +
		mine[x + 1][y] - '0' +
		mine[x + 1][y + 1] - '0' +
		mine[x][y + 1] - '0' +
		mine[x - 1][y + 1] - '0';
}
5、玩家排雷

玩家输入认为不是雷的坐标进行排雷,如果坐标不合法则提示信息并且从新输入;坐标合法则进一步判断输入的坐标是否是雷,如果是雷则提示踩到雷,如果没有雷进一步判断是否排查过,排查过则提示信息并重新输入,没有排查则调用get_mine计算坐标周围的雷的个数,并放入mine[x][y]中。

int find_mine(char mine[ROWS][COLS], int row, int col,char show[ROWS][COLS]) {
	int x, y;
	while (1) {
		printf("请输入你要排除的坐标:");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col) {
			if (mine[x][y] != '1') {
				//此时没有cai到雷 统计周围雷的数量
				int num = get_mine(mine, x, y);
				if (show[x][y] == '*') {
					show[x][y] = num + '0';
					broad(mine, show, x, y);
					break;
				}
				else {
					printf("此坐标已经被排查过:\n");
				}
				
			}
			else {
				//此时踩到雷了
				printf("很遗憾,你踩到雷了\n");
				break;
			}
			
		}
		else {
			printf("坐标不合法请重新输入:");
		}
	}
	if (mine[x][y] != '1') {
	  //最终返回1 表示此时排雷无误
		return 1;
	}
	else {
	  //最终返回-1 便于接收 表示踩到雷了
		return -1;
	}
}
6、递归展开一片区域
void broad(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	//判断坐标是否越界
	if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)
		return;
	//判断是否已经被排除
	if (show[x][y] != '*')
	{
		return;
	}
	int count = get_mine(mine, x, y);
	if (count > 0)
	{
		show[x][y] = count + '0';
		return;
	}
	//递归展开雷盘
	else if (count == 0)
	{
		show[x][y] = '0';
		broad(mine, show, x - 1, y);
		broad(mine, show, x - 1, y - 1);
		broad(mine, show, x, y - 1);
		broad(mine, show, x + 1, y - 1);
		broad(mine, show, x + 1, y);
		broad(mine, show, x + 1, y + 1);
		broad(mine, show, x, y + 1);
		broad(mine, show, x - 1, y + 1);
	}
}
7、标记雷区
  • 首先判断标记的坐标是否合法
  • 不合法的话提示信息,并且重新输入
  • 合法的话进一步判断标记的坐标是否排查过(是否是‘*’)
void sign_mine(char show[ROWS][COLS], int row, int col) {
	int x, y;
	while (1) {
		printf("请输入你要标记(@)的雷的坐标:");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col) {
			if (show[x][y] == '*') {
				show[x][y] = '@';
			}
			else {
				printf("此坐标已经排查过不是雷....\n");
			}
			break;
		}
		else {
			printf("你输入的坐标不合法,请重新输入:");
		}
	}
}
8、取消标记
void cancel_sign(char show[ROWS][COLS], int row, int col) {
	int x, y;
	
	printf("请输入你要取消标记的坐标:");
	scanf("%d %d", &x, &y);
	if (show[x][y] == '@') {
		show[x][y] = '*';
	}
	else {
		printf("此坐标没有被标记,请重新选择!");
	}
	
}
三、运行展示
  • 递归展开

  • 玩家排雷

    当重复排雷时:

  • 标记雷区

  • 取消标记

    想要全部代码可以点击这里获取完整代码。
    如有错误的地方欢迎大家指出!!!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/914881.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-16
下一篇2022-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存