【学习记录--迷宫实验】随机生成迷宫并寻找出路

学习到栈相关的内容,开始第一篇博客,记录学习。

附上结果图

PS为起始点 *为正确路径 #为走过回退的路径

以下为代码的实现-->

首先自定义一个Sport来存储位置

class Sport
{
public:
	Sport();
	Sport(int x , int y);
public:	
	int m_X;	// 位置所在行
	int m_Y;	//位置所在列
};

// 构造函数
Sport::Sport()
{
	this->m_X = 0;
	this->m_Y = 0;
}
Sport::Sport(int x, int y)
{
	this->m_X = x;
	this->m_Y = y;
}

定义地图相关元素

#include<iostream>
#include<stack>
#include<vector>
#include<time.h>
#include<Windows.h>
#include<iomanip>
#include"Sport.hpp"
using namespace std;

// 定义迷宫大小
// 实际大小为  ROW-2 * COL-2 其中四行四列作为迷宫边界 防止挖穿迷宫
#define ROW 44
#define COL 44

// 定义 0 墙 1 路
#define WALL 0
#define ROAD 1

// 定义 10 走过的位置 11 回退过的位置
#define WALK 10
#define WALKBACK 11

// 搭建初始迷宫
int MAZE[ROW][COL] = { 0 };

// 上下左右 四个方向
int direction[4][2] = { { 1,0 },{ -1,0 },{ 0,-1 },{ 0,1 } };

// 地图编号
int SELECT = 1;

// 起始位置坐标
int START_X = 0;
int START_Y = 0;

// 出口的坐标
int END_X = 0;
int END_Y = 0;

// 迷宫复杂度
// 数字越大 迷宫越简单
// 代表单次挖迷宫的格数-1
static int Rank = 0;

// 路线坐标栈
stack<Sport> MOUSE;
int main()
{
	// 主功能菜单
	Menu();

	// 设置起始位置
	setStart();

	// 迷宫构建
	Maze(START_X, START_Y);

	// 把小鼠放置起始位置
	MOUSE.push(Sport(START_X, START_Y));
	MAZE[START_X][START_Y] = WALK;

	// 派小鼠走迷宫
	mouseWalk(MOUSE.top().m_X, MOUSE.top().m_Y);

	// 输出路线
	printMaze();

	// 初始化迷宫
	initMaze();

	system("pause");
	return 0;
}
// 设置起始位置
void setStart()
{
	cout << "当前迷宫规模:" << ROW-4 << "×" << COL-4 << endl << endl;
	cout << "输入迷宫的初始位置" << endl;
	while (1)
	{
		cin >> START_X >> START_Y;
		START_X++;
		START_Y++;
		// 位置合法
		if (START_X >= 1 && START_X < ROW - 2 && START_Y >= 2 && START_Y < COL - 2)
		{
			break;
		}
		cout << "起始位置不合法,重新输入" << endl;
	}

}
// 迷宫
void Maze(int x ,int y)
{
	// 最外围围墙设为 ROAD 限制挖穿
	for (int i = 0;i < ROW;++i)
	{
		MAZE[i][0] = ROAD;
		MAZE[0][i] = ROAD;
		MAZE[ROW - 1][i] = ROAD;
		MAZE[i][COL - 1] = ROAD;
	}

	cout << "选择迷宫编号>" << endl;
	cout << "1--100" << endl;
	cin >> SELECT;
	SELECT %= 100;
	system("cls");
	
	// 递归构建迷宫
	creatMaze(x, y);
	// 设置出口
	setExit();
	// 打印迷宫
	printMaze();
}
// 深度算法生成迷宫
void creatMaze(int x,int y)
{
	//srand((unsigned)time(NULL));
	// 起始位置
	MAZE[x][y] = ROAD;

	 //随机四个方向顺序
	for (int i = 0; i < SELECT; i++) 
	{
		
		int r = rand() % 4;
		int temp = direction[1][0];
		direction[1][0] = direction[r][0];
		direction[r][0] = temp;

		temp = direction[1][1];
		direction[1][1] = direction[r][1];
		direction[r][1] = temp;
	}

	// 四个方向挖迷宫墙
	for (int i = 0;i < 4;++i)
	{
		int dx = x;
		int dy = y;
		int range = 1 + (Rank == 0 ? 0 : rand() % Rank);

		while (range > 0)
		{
			dx += direction[i][0];
			dy += direction[i][1];

			// 当下一个方向已经为ROAD时 该方向不在重新挖
			if (ROAD == MAZE[dx][dy])
			{
				break;
			}
			// 查看四个方向
			// 排除 挖到四个角的出路
			int result = 0;

			for (int j = -1;j < 2;++j)
			{
				for (int k = -1;k < 2;++k)
				{
					// 判断上下左右四个方向是否挖穿
					// 
					if (ROAD == MAZE[dx + j][dy + k] && 1 == abs(j) + abs(k))
					{
						result++;
					}
				}
			}
			if (result>1)
			{
				break;
			}
			--range;
			MAZE[dx][dy] = ROAD;
		}
		// 迷宫还没挖穿
		// 递归循环 直到迷宫穿
		if (range <= 0)
		{
			creatMaze(dx, dy);
		}
	}
}
// 设置出口
void setExit()
{
	// 希望设置一个出口在右边切靠近下方
	for (int i = ROW - 3;i >= 0;--i)
	{
			if (ROAD == MAZE[i][COL-3])
			{
				END_X = i;
				END_Y = COL - 2;
				MAZE[i][COL-2] = ROAD;
				break;
			}
	}
}
// 初始化迷宫
void initMaze()
{
	for (int i = 0;i < ROW;++i)
	{
		for (int j = 0;j < COL;++j)
		{
			MAZE[i][j] = 0;
		}
	}
}
// 小鼠寻访路线
void mouseWalk(int x ,int y)
{
	int dx = x;
	int dy = y;
	int result = 0;

	// 四个方向寻路
	for (int i = 0;i < 4;++i)
	{
		// 走到出口退出
		if (WALK == MAZE[END_X][END_Y])
		{
			return;
		}

		dx = x + direction[i][0];
		dy = y + direction[i][1];

		// 下一方向可行
		if (ROAD == MAZE[dx][dy])
		{
			result++;
			MAZE[dx][dy] = WALK;
			MOUSE.push(Sport(dx,dy));
			break;
		}

		// 下一方向为墙 或 是回退过的位置
		else if (WALL == MAZE[dx][dy] || WALK == MAZE[dx][dy] || WALKBACK == MAZE[dx][dy])
		{
			continue;
		}

	}

	// 四个方向都不可行,小鼠位置回退
	if (0 == result)
	{
		
		MAZE[x][y] = WALKBACK;
		MOUSE.pop();
		mouseWalk(MOUSE.top().m_X, MOUSE.top().m_Y);
	}
	// 有可行方向小鼠前进
	else
	{
		mouseWalk(MOUSE.top().m_X, MOUSE.top().m_Y);
	}
}

 

// 打印迷宫
void printMaze()
{
	cout << "\t\t\t\t" << "迷宫编号 " <<SELECT<< endl << endl;

	// 30--37  黑 红 绿 黄 蓝 紫 青 白 
	for (int i = 0;i < ROW;++i)
	{
		for (int j = 0;j < COL;++j)
		{
			if (WALL == MAZE[i][j])
			{
				// 输出黑色
				cout << "\033[30;1m■\033[0m";
			}
			else if(ROAD==MAZE[i][j])
			{
				// 起始位置 黄色输出
				if (START_X == i && START_Y == j)
				{
					cout << "\033[33;1m★\033[0m";
					continue;
				}
				cout << "  ";
			}
			else if (WALK == MAZE[i][j])
			{

				// 起始位置 黄色输出
				if (START_X == i && START_Y == j )
				{
					cout << "\033[33;1m★\033[0m";
					continue;
				}
				// 红色输出
				cout << "\033[31;1m* \033[0m";
			}
			else if (WALKBACK == MAZE[i][j])
			{
				//
				cout << "\033[35;1m# \033[0m";
			}
		}
		cout << endl;
	}
}

至此,迷宫生成及寻找出路全部完成。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值