扫雷大战(命令行版,可以连续扫除一片空白区域)

扫雷的基本思路

1.创建菜单,菜单中包含两个选项,


***** 1.开始游戏*****
***** 2.退出游戏*****


在这里插入图片描述
2.用switch语句实现,游戏的选择开始或者退出。
3.选择开始游戏就会打印出棋盘。
在这里插入图片描述
4.游戏部分创建两个二维数组,分别是mine和show数组。mine数组是有关炸弹的数组,有炸弹的位置是’1’,没有炸弹的位置是’0’;show数组是查找炸弹的数组,不知道的位置是‘’,查出来的位置的数字是周围的9宫格内炸弹个数
5、初始化这两个二维数组,mine数组初始化为‘0’,show数组初始化为‘

6、打印棋盘,每次输入坐标后都打印一次棋盘,以便观察
在这里插入图片描述
7、实现布置雷的操作:和三子棋一样需要rand(头文件:stdlib.h)和time(头文件:time.h),结合使用可以使电脑随机布置雷.
8、实现排查雷的操作:玩家输入一个坐标,若踩雷则会提醒游戏结束;若未踩雷,并且以该位置为中心的9宫格内没有雷,则在show数组中的相应位置中显示周围没有累的地方。(必须是与该坐标为中心)。
9、在游戏结束后,继续打印选择的菜单,由玩家决定是否继续进行游戏。

扫雷代码实现的详细步骤

1.首先创建3个文件:
在这里插入图片描述
2.game.h中主要用来包含test.c和game.c中所需要的头文件,然后,test.c和game.c包含game.h就可以达到代码的高复用性,也更加方便维护代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.在test.c中创建main()函数和test()函数,amin()函数调用test()函数完成,整个游戏的调用,test()函数中用switch创建一个简单的选择功能是实现游戏的开始和退出。
在这里插入图片描述
4.创建游戏选择的菜单
在这里插入图片描述
5.游戏棋盘的大小设置,这里我都设计为1111,也就是11行,11列,游戏区是99,这样的目的是方便判断边界地方的九宫格内雷的个数,我设置这个棋盘有10颗雷。
在这里插入图片描述
6.初始化棋盘
在这里插入图片描述
7.随机埋雷,我们这里设置了10颗雷。
在这里插入图片描述

8.打印棋盘
在这里插入图片描述

9.游戏棋盘的设置,这里我设计了两个棋盘,一个棋盘(mine)是用来存放地雷的位置,游戏开始的时候,初始化一次,布雷完成后这个数组就不会发生改变,另一个棋盘(show)是用来存放我们排雷的位置,初始化为全‘*’,我们输入坐标,然后计算机判断这个坐标在mine棋盘中是否是地雷,如果不是地雷则会在show棋盘中显示以该坐标为中心的九宫格内有多少个雷,如果是地雷,则游戏结束。

在这里插入图片描述

//游戏引擎
void game()
 {

	//记录排掉多少个是雷的地方
	int count = 0;
	
	//存放地雷的数组
	char mine[ROWS][COLS];
	//存放展示排雷的数组
	char show[ROWS][COLS];
	
	//初始化
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');

	//随机埋雷
	setMine(mine, ROWS, COLS);

	while (count != EASY_COUNT)
	{
		int x = -1, y = -1;
		
		//打印棋盘
		PrintBoard(show, ROWS, COLS);
		//PrintBoard(mine, ROWS, COLS);
		printf("请输入:>");
		scanf("%d %d", &x, &y);

		// 判断x和y的合法性   返回1表示合法   返回0表示不合法
		if (is_true(show, x, y) == 0)
		{
			printf("坐标不合法请重新输入\n");
			continue;
		}

		//判断该坐标是否是 地雷   1表示是雷  0表示不是雷
		if (is_mine(mine, x, y))
		{
			printf("很遗憾,踩到雷了,游戏结束\n按任意键继续游戏\n");
			system("pause");
			break;
		}
		
		//扫除雷
		space(show, mine, x, y);
		//show[x][y] = (char)(FindMine(mine, x, y) + '0');
		/*if (((char)(FindMine(mine, x, y) + '0')) == '0')
		{
			space(show, mine, x, y);
		}
		else
		{
			show[x][y] = (char)(FindMine(mine, x, y) + '0');
		}*/

		count = show_count(show, ROWS, COLS);

		system("cls");
	}
	
	if (count == EASY_COUNT)
	{
		printf("恭喜你,排雷成功!\n按任意键继续游戏\n");
		system("pause");
	}

}`

10.排雷算法,这里用到了递归,是为了展>开旁边不是雷的地方,增强游戏的可玩性,
该算法首先判断以该位置为中心的九宫格内是否有雷,如果有雷就直接改变该位置的内容,不会展开其他的地方,如果没有雷,会进行展开,直到有雷,递归才会结束。
该递归算法结束的条件是:以x,y为中心的九宫格内有雷;
递归结束的另外一个条件是,判断的位置到了棋盘的边界。
防止重复检测同一个位置,将该位置赋值为‘ ’空格。
在这里插入图片描述

完整代码

1、game.h部分(运行游戏需要的头文件和函数的声明)

#pragma once

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

#define ROW 9
#define COL 9

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

//表示棋盘中有10个雷
#define EASY_COUNT 10

//游戏引擎
void game();

//游戏菜单
void menu();


2、game.c部分(游戏引擎)

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"



//游戏菜单
void menu()
{
	printf("------ 扫雷游戏 -------\n");
	printf("**********************\n");
	printf("****** 1.开始游戏 *****\n");
	printf("****** 0.退出游戏 *****\n");
	printf("**********************\n");
	printf("------ 扫雷游戏 -------\n");
}


//初始化
InitBoard(char board[ROWS][COLS], int row, int col, char ret)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = ret;
		}
	}
}

//打印棋盘
PrintBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 1;
	printf("------ 扫雷游戏 -------\n");
	printf("    ");
	for (i = 1; i < row - 1; i++)
	{
		printf("%d ", i);
	}
	printf("\n  ");

	for (i = 0; i < row - 1; i++)
	{
		printf("--");
	}
	printf("\n");

	for (i = 1; i < row - 1; i++)
	{
		int j = 1;
		printf("%d | ", i);
		for (j = 1; j < col - 1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("------ 扫雷游戏 -------\n");
}

//随机埋雷   '1'表示有雷    '0'表示无雷
setMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;

	while (count)
	{
		int x = (rand() % 9) + 1;
		int y = (rand() % 9) + 1;
		if (mine[x][y] != '1')
		{
			mine[x][y] = '1';
			count--;
		}
	}

}

//判断坐标的合法性
int is_true(char show[ROWS][COLS], int x, int y)
{
	if (x >= 1 && x <= ROWS - 1 && y >= 1 && y <= ROWS - 1 && show[x][y] == '*')
	{
		return 1;
	}
	return 0;
}

//判断该坐标是否是雷   1表示是雷  0表示不是雷
int is_mine(char mine[ROWS][COLS], int x, int y)
{
	return ((int)(mine[x][y] - '0'));
}

//扫除雷
int FindMine(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
		mine[x][y - 1] + mine[x][y + 1] +
		mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0');
	/*int count = 0;
	int i, j;
	for (i = x - 1; i <= x + 1; i++)
	{
		for (j = y - 1; y <= y + 1; y++)
		{
			if (mine[i][j] == '1')
			{
				count++;
			}
		}
	}

	return count;*/
}


//展示0周围的一片
void space(char board[ROWS][COLS], char mine[ROWS][COLS], int x, int y)
{
	int i;
	if (FindMine(mine, x, y) == 0)
	{
		board[x][y] = ' ';
		for (i = x - 1; i <= x + 1; i++)
		{
			int j;
			for (j = y - 1; j <= y + 1; j++)
			{
				if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1' && board[i][j] == '*')
				{
					space(board, mine, i, j);
				}
			}
		}
	}
	else
		board[x][y] = '0' + FindMine(mine, x, y);

}

//计算show中*的个数
int show_count(char show[ROWS][COLS], int row, int col)
{
	int count = 0;
	int i;
	for (i = 1; i < row - 1; i++)
	{
		int j;
		for (j = 1; j < col - 1; j++)
		{
			if (show[i][j] == '*')
			{
				count++;
			}
		}
	}
	return count;
}



//游戏引擎
void game()
{
	//记录排掉多少个是雷的地方
	int count = 0;
	//存放地雷的数组
	char mine[ROWS][COLS];
	//存放展示排雷的数组
	char show[ROWS][COLS];

	//初始化
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');

	//随机埋雷
	setMine(mine, ROWS, COLS);

	while (count != EASY_COUNT)
	{
		int x = -1, y = -1;
		
		//打印棋盘
		PrintBoard(show, ROWS, COLS);
		//PrintBoard(mine, ROWS, COLS);
		printf("请输入:>");
		scanf("%d %d", &x, &y);

		// 判断x和y的合法性   返回1表示合法   返回0表示不合法
		if (is_true(show, x, y) == 0)
		{
			printf("坐标不合法请重新输入\n");
			continue;
		}

		//判断该坐标是否是 地雷   1表示是雷  0表示不是雷
		if (is_mine(mine, x, y))
		{
			printf("很遗憾,踩到雷了,游戏结束\n按任意键继续游戏\n");
			system("pause");
			break;
		}
		
		//扫除雷
		space(show, mine, x, y);
		//show[x][y] = (char)(FindMine(mine, x, y) + '0');
		/*if (((char)(FindMine(mine, x, y) + '0')) == '0')
		{
			space(show, mine, x, y);
		}
		else
		{
			show[x][y] = (char)(FindMine(mine, x, y) + '0');
		}*/

		count = show_count(show, ROWS, COLS);

		system("cls");
	}
	
	if (count == EASY_COUNT)
	{
		printf("恭喜你,排雷成功!\n按任意键继续游戏\n");
		system("pause");
	}

}


3、test.c部分(测试游戏)

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void test()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do
	{
		//游戏菜单
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			system("cls");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (input);

}


int main()
{
	//扫雷游戏测试函数
	test();
	return 0;
}

这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值