迷宫深搜或广搜寻路问题详解,c++实现

自定义迷宫类以及相关结构体,直接上代码,有空我会把布线问题也更新一下
下面展示一些 maze.h

// An highlighted block
#include<iostream>
#include<time.h>
#include<stack>
#include<windows.h>
using namespace std;
class maze
{
public:
	maze():Maze(nullptr), size(0),isinit(false){};
	void ramdonint(int=10);
	void showmaze() const;
	int getSize() const{ return size; };
	int* operator[](int row){ return Maze[row]; };
	//虽然三五法则,但是这里好像真的不需要拷贝构造和等号重载?
	~maze();
private:
	int size;
	int** Maze;
	bool isinit;
};
struct position
{
	int row;
	int col;
	position(int Col=0, int Row=0) :row(Row), col(Col){};
	void operator=(position& p){ row = p.row; col = p.row; };
};

下面展示一些 maze.cpp

// An highlighted block
#include"maze.h"
void maze::ramdonint(int Size)
{
	size = Size;
	srand((int)time(NULL));
	if (!isinit)
	{
		Maze = new int*[Size + 2]{};

		for (int i = 0; i <= Size + 1; i++)
		{

			Maze[i] = new int[Size + 2]{};

			if (i == 0 || i == size + 1){ continue; }//第一行行为空
			for (int j = 1; j <= Size; j++)//第一列为空,最后一列为空
			{
				if (rand() % 10 > 7)
				{
					Maze[i][j] = 1;
				}
			}
		}
		isinit = true;
	}
	else
	{
		for (int i = 1; i < Size + 1; i++)
		{
			for (int j = 1; j < Size + 1; j++)//第一列为空,最后一列为空
			{
				if (rand() % 10 > 7)
				{
					Maze[i][j] = 1;
				}
				else
				{
					Maze[i][j] = 0;
				}
			}
		}
	}
	Maze[1][1] = 0;
	Maze[size][size]=0;
}
void maze::showmaze()const 
{
	for (int i = 0; i <= size+1; i++)
	{
		for (int j = 0; j <=size+1; j++)
		{
			cout << Maze[i][j] << " ";
		}
		cout << endl;
	}
}
maze::~maze()
{
	if (nullptr != Maze)
	{
		for (int i = 0; i < size; i++)
		{
			delete[] Maze[i];
		}
	}
	delete[] Maze;
	Maze = nullptr;
}

下面展示一些 main.cpp

// An highlighted block
#include"maze.h"
bool findpath(maze& m);
void main()
{
	int count = 1;
	maze m;
	m.ramdonint();
	do{
		m.ramdonint();
		Sleep(1000);
	} while (!findpath(m));
	system("cls");
	m.showmaze();
	m.~maze();
	system("pause");
}
bool findpath(maze& m)//深搜
{

	static const position* const offSet = new position[4]{{1, 0}, { 0, 1 }, { -1, 0 }, { 0, -1 }};//右下左上
	stack<position> *path;
	path = new stack<position>();
	int size = m.getSize();
	for (int i = 0; i <= size+1; i++)
	{
		m[0][i] = m[size + 1][i] = 1;
		m[i][0] = m[i][size + 1] = 1;
	}
	position here(1, 1);
	m[1][1] = 2;
	int option = 0;
	int maxoption = 3;
	while (here.row != size || here.col != size)
	{
		int r, c;
		while (option <= maxoption)
		{
			r = here.row + offSet[option].row;
			c = here.col + offSet[option].col;
			if (m[r][c] == 0 )
			{
				break;
			}
			option++;
		}
		if (option <= maxoption)
		{
			path->push(here);
			here.row = r;
			here.col = c;
			m[r][c] = 2;
			option = 0;//从头开始选
		}
		else
		{
			if (path->empty())
				return false;
			position next = path->top();
			path->pop();
			if (next.row == here.row)//如果上一步在同一排
			{
				option = 2 + next.col - here.col;//上一步在这一步左边为1,右边为3,对应还有3和1次搜寻机会
			}
			else
			{
				option = 3 + next.row - here.row;//同理,如果在同一列,上面为2,下面为4,对应2和0次搜索机会
			}
			m[here.row][here.col] = 2;
			m[next.row][next.col] = 2;
			here = next;
		}
	}
	m[size][size] = 2;
	delete path;
	delete[] offSet;
	return true;
}

运行结果
2为曾经走过的路径
在这里插入图片描述

下面展示一些 广搜实现寻路

// An highlighted block
bool findpath2(maze& m)//广搜
{
	static const position* const offSet = new position[4]{{1, 0}, { 0, 1 }, { -1, 0 }, { 0, -1 }};//右下左上
	queue<position> *path;
	path = new queue<position>();
	int size = m.getSize();
	for (int i = 0; i <= size + 1; i++)
	{
		m[0][i] = m[size + 1][i] = 1;
		m[i][0] = m[i][size + 1] = 1;
	}
	position here(1, 1);
	m[1][1] = 2;
	position nbr;
	int numofNbrs = 4;//同一方格能到达的方格数
	while (true)
	{
		for (int i = 0; i < numofNbrs; i++)
		{
			nbr.row = here.row + offSet[i].row;
			nbr.col = here.col + offSet[i].col;
			if (m[nbr.row][nbr.col]==0)
			{
				m[nbr.row][nbr.col] = m[here.col][here.col] + 1;
				if (nbr.col == size&&nbr.row == size)
				{
					here = position(size, size);
					break;
				}
				path->push(nbr);
			}
			if (path->empty())
			{
				return false;
			}
			here = path->front();//取下一个位置,可能一次push进去了很多个位置,但是都是右下左上顺序取
			path->pop();
		}
	}//把所有跟出发点联通的区域都标记好之后
	//构造路径,
	int length = m[size][size] - 2;
	position *way = new position[length];
	//从终点逆推
	for (int j = length - 1; j >= 0; j--)
	{
		way[j] = here;
		for (int i = 0; i < numofNbrs; i++)
		{
			nbr.row = here.row + offSet[i].row;
			nbr.col = here.col + offSet[i].col;
			if (m[nbr.row][nbr.col] == j + 2) break;//如果比目前的数小一个
		}
		here = nbr;//更新位置
	}
	delete path;
	delete [] way;
	delete [] offSet;
	return true;
}
  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

无情の学习机器

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

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

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

打赏作者

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

抵扣说明:

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

余额充值