版权声明:版权声明:本文章刊载的所有内容,包括文字、图片、音频、视频、软件、程序、以及网页版式设计等均归"江南、董少"所有! https://blog.csdn.net/qq_41453285/article/details/83276428
注:深度寻路用到的栈头文件以及.cpp文件
在我的资源中可下载或者Q:1286550014(免费)
深度寻路
原理:在地图中从一个点开始,从规定方向开始走,无障碍就继续走,数据压栈,如果有障碍就退一步,数据出栈,直至找到终点或无终点时,寻路结束。
一、头文件导入
#include "Stack.h"
//此头文件包含数据结构中的栈,栈用顺序表的形式实现,
//为自己实现的栈结构,里面包含各种函数方法
二、结构体、方向枚举、宏定义
#define ROW 8 //地图的行
#define COL 12 //地图的列
//一个枚举,存储寻路的四个方向,分别为上下左右
enum Dir {p_up,p_down,p_left,p_right};
//结构体,用于表示地图二维数组中的某一个点
typedef struct Node
{
int x;
int y;
}Node;
//一个辅助结构体,用于保存地图每一个点的信息
typedef struct PathNode
{
int value; //地点的值,0为可通路,1为不可通路
Dir dir; //地点的方向
bool isFind;//一个值,判断当前点是否已经走过
}PathNode;
三、主函数的进入
//主地图的定义,包含了地图的信息
int arr[ROW][COL] = {
{ 1,1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,0,0,1,0,1,1,1,1,1,1 },
{ 1,1,1,0,1,0,0,0,0,0,1,1 },
{ 1,1,1,0,1,0,1,1,1,0,1,1 },
{ 1,1,1,0,1,0,1,1,1,0,1,1 },
{ 1,1,1,0,1,0,1,1,1,0,1,1 },
{ 1,0,0,0,0,0,1,1,1,0,0,1 },
{ 1,1,1,1,1,1,1,1,1,1,1,1 },
};
//因为不能对主地图进行各种操作,所以定义一个辅助地图,
//用于后面进行各种操作,并通过for循环对辅助地图进行初始化
PathNode pathNode[ROW][COL];
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; ++j)
{
pathNode[i][j].value = arr[i][j];//将地图的每个点值放入辅助地图
pathNode[i][j].isFind = false;//每个地图点都设置为未访问过
pathNode[i][j].dir = p_up; //每个点的默认寻找方向向上
}
}
//定义地图的初始化起点与终点
Node beginNode = { 1,1 };
Node endNode = { 6,10 };
//定义一个栈,用于保存寻找到的地图信息点
Stack<Node>* st=new Stack<Node>(100);
//先将起点压入栈中
st->PushStack(beginNode);
//定义一个辅助点,用于在地图中进行各种寻路操作
Node tempNode = st->GetTop();
//定义一个死循环,进行寻路操作,操作通过点查找实现,当找到一个可行点的时候就入栈,
//路不通时就出栈,并分别从上下左右四个方向进行查找,我们规定查找的顺序为:上->下->左->右
//当一个点上下左右都找不到时就将此点出栈
while (true)
{
//通过方向进行查找
switch (pathNode[tempNode.x][tempNode.y].dir)
{
//先判断向上查找,下面的下和左亦同,但是向右需单独判断
case p_up:
//不论下一点是否可访问,先将此点的方向设置为向下,用于不能访问后重新进行寻路
pathNode[tempNode.x][tempNode.y].dir = p_down;
//如果上一点可访问
if (pathNode[tempNode.x - 1][tempNode.y].isFind == false &&
pathNode[tempNode.x - 1][tempNode.y].value == 0)
{
//将当前点设置为以访问过
pathNode[tempNode.x][tempNode.y].isFind = true;
//将新点入栈,并将辅助点设置为新点
Node temp = { tempNode.x - 1,tempNode.y };
st->PushStack(temp);
tempNode = temp;
}
break;
case p_down:
pathNode[tempNode.x][tempNode.y].dir = p_left;
if (pathNode[tempNode.x + 1][tempNode.y].isFind == false &&
pathNode[tempNode.x + 1][tempNode.y].value == 0)
{
pathNode[tempNode.x][tempNode.y].isFind = true;
Node temp = { tempNode.x + 1,tempNode.y };
st->PushStack(temp);
tempNode = temp;
}
break;
case p_left:
pathNode[tempNode.x][tempNode.y].dir = p_right;
if (pathNode[tempNode.x][tempNode.y - 1].isFind == false &&
pathNode[tempNode.x][tempNode.y - 1].value == 0)
{
pathNode[tempNode.x][tempNode.y].isFind = true;
Node temp = { tempNode.x,tempNode.y - 1 };
st->PushStack(temp);
tempNode = temp;
}
break;
case p_right:
if (pathNode[tempNode.x][tempNode.y + 1].isFind == false &&
pathNode[tempNode.x][tempNode.y + 1].value == 0)
{
pathNode[tempNode.x][tempNode.y].isFind = true;
Node temp = { tempNode.x,tempNode.y + 1 };
st->PushStack(temp);
tempNode = temp;
}
//如果上下左右都走不通,说明此点作废,需要将此点出栈,并进行重新寻路
else
{
//得到这个点,并将这个点设置为已访问过,并将其出栈
Node temp = st->GetTop();
pathNode[temp.x][temp.y].isFind = true;
st->PopStack();
if (!st->isEmpty())
{
//出栈后重新获得辅助点
tempNode = st->GetTop();
}
}
break;
}
//如果找到终点了,就退出while循环
if (tempNode.x == endNode.x
&&tempNode.y == endNode.y)
{
break;
}
//如果栈为空了,说明寻路失败,也退出while循环
if (st->isEmpty())
{
break;
}
}
四、打印寻路信息
当以上所有事务都完成,且寻路成功后,就可以从栈中获取我们所要的寻路信息
//循环打印
while (!st->isEmpty())
{
printf("row=%d,col=%d\n", st->GetTop().x, st->GetTop().y);
st->PopStack();
}