#include "stdafx.h"
#include <vector>
using namespace std;
//深度优先搜索(深度寻路)
//规则:沿着一个固定的方向来进行行走,到了岔路口又一次重新选择方向,如果碰上了死胡同退回到上一个岔路口重新选择方向
// 走过的路不会重复走,一次走一个岔路口
//注意:深度如果因为方向设定顺序不一致,可能导致找到的路径不一样
//深度最简单
//1、需要一张地图 (二维数组来表示地图)
//在二维数组中用一个固定的数值表示可通行(一般为0),其它的非0数值都理解不可通行
#define MAP_ROW 10
#define MAP_COL 10
//2、准备方向 帮助进行辅助寻路
enum Path_Dir {p_up,p_left,p_down,p_right};
//3、准备一个结构,用来保存每一个路径点的行列值
struct MyPoint
{
int row, col;
};
//4、准备一个数据结构来保存寻路最终所找到的所有岔路口的坐标(准备一个栈来做为数据结构)
//5、为地图准备一个辅助的寻路地图(这个辅助地图不仅仅是一个变量能解决的,需要一个结构)
struct PathNode
{
int val;//保存资源地图的岔路口信息
Path_Dir dir;//为当前岔路口准备一个最初的寻路方向
bool isFind;//当前岔路口是否被访问
};
//准备一个函数,用来判断当前坐标表示的位置是否可以通行
bool isCheckMove(PathNode p[][MAP_COL],int row,int col)
{
if (row < 0 || row >= MAP_ROW || col < 0 || col >= MAP_COL)//越界判断
return false;
if (p[row][col].isFind == true || p[row][col].val != 0)//判断当前行列表示的坐标已经访问过,或者当前坐标上的值为表示障碍
return false;
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
int mapArr[MAP_ROW][MAP_COL] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 1, 0, 0, 0, 0, 1 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
PathNode pathArr[MAP_ROW][MAP_COL];
for (int i = 0; i < MAP_ROW; ++i)
{
for (int j = 0; j < MAP_COL; ++j)
{
pathArr[i][j].val = mapArr[i][j];//把资源数组的岔路口的值赋值到辅助数组中
pathArr[i][j].isFind = false;//地图中的每一个岔路口都没有被访问过
pathArr[i][j].dir = p_up;//为每一个岔路口初始一个初始寻路方向
}
}
//第6步:准备起点和终点
MyPoint beginPoint = { 1, 2 };
MyPoint endPoint = { 8, 8 };
//第7步:准备一个栈容器来保存所有的路径点
vector<MyPoint> ms;
ms.push_back(beginPoint);//把起点压入容器
//第8步:准备一个辅助的坐标变量。1、用来表示当前正在寻路的坐标值
MyPoint currPoint = beginPoint;//最开始的辅助点就是起点,通过起点找第二个点,这个辅助点才会变成第二点的坐标
//第9步:开始寻路
while (true)//无法确定循环次数
{
switch (pathArr[currPoint.row][currPoint.col].dir)//判断一个初始方向
{
case p_up:
pathArr[currPoint.row][currPoint.col].dir = p_left;//当前点的上方向不可通行,改当前点的下一次搜索方向
if (isCheckMove(pathArr, currPoint.row - 1, currPoint.col))
{
//如果进入条件,表示该坐标是可通行的
pathArr[currPoint.row][currPoint.col].isFind = true;//当前点改为已访问
MyPoint tempPoint = { currPoint.row - 1, currPoint.col };
ms.push_back(tempPoint);//把当前点的上方向可通行坐标压入容器
currPoint = tempPoint;//把当前点的上方向可通行坐标赋值给当前坐标,以便于下一次从新的当前坐标开始查找
}
break;
case p_left:
pathArr[currPoint.row][currPoint.col].dir = p_down;//当前点的左方向不可通行,改当前点的下一次搜索方向
if (isCheckMove(pathArr, currPoint.row, currPoint.col - 1))
{
//如果进入条件,表示该坐标是可通行的
pathArr[currPoint.row][currPoint.col].isFind = true;//当前点改为已访问
MyPoint tempPoint = { currPoint.row, currPoint.col - 1 };
ms.push_back(tempPoint);//把当前点的左方向可通行坐标压入容器
currPoint = tempPoint;//把当前点的左方向可通行坐标赋值给当前坐标,以便于下一次从新的当前坐标开始查找
}
break;
case p_down:
pathArr[currPoint.row][currPoint.col].dir = p_right;//当前点的下方向不可通行,改当前点的下一次搜索方向
if (isCheckMove(pathArr, currPoint.row + 1, currPoint.col))
{
//如果进入条件,表示该坐标是可通行的
pathArr[currPoint.row][currPoint.col].isFind = true;//当前点改为已访问
MyPoint tempPoint = { currPoint.row + 1, currPoint.col };
ms.push_back(tempPoint);//把当前点的下方向可通行坐标压入容器
currPoint = tempPoint;//把当前点的下方向可通行坐标赋值给当前坐标,以便于下一次从新的当前坐标开始查找
}
break;
case p_right:
//注意:最后一个方向了,不需要再记录下一个方向,因为4方向搜索完成
if (isCheckMove(pathArr, currPoint.row, currPoint.col + 1))
{
//如果进入条件,表示该坐标是可通行的
pathArr[currPoint.row][currPoint.col].isFind = true;//当前点改为已访问
MyPoint tempPoint = { currPoint.row, currPoint.col + 1 };
ms.push_back(tempPoint);//把当前点的右方向可通行坐标压入容器
currPoint = tempPoint;//把当前点的右方向可通行坐标赋值给当前坐标,以便于下一次从新的当前坐标开始查找
}
else
{
//证明当前点的4方向已经都不可通行,是死胡同
//入栈的坐标是没有标记已经被访问的
//MyPoint tempPoint = ms.getTop();
pathArr[currPoint.row][currPoint.col].isFind = true;//在退栈之前,当前这个搜索的坐标标记为已经访问
ms.pop_back();//当前点退栈,把当前这个表示死胡同的坐标退掉
if (!ms.empty())//判断如果栈不为空
currPoint = ms[ms.size()-1];//得到新的栈点元素
}
break;
}
//找到出口,没有出口 结束循环
if (ms.empty())//没有路径,结束循环
break;
if (currPoint.row == endPoint.row && currPoint.col == endPoint.col)//当前点就是终点
break;
}
//寻路终止,打印路径
while (!ms.empty())
{
MyPoint tempPoint = ms[ms.size() - 1];
//printf("row = %d\t col = %d\n",tempPoint.row,tempPoint.col);
pathArr[tempPoint.row][tempPoint.col].val = 5;
ms.pop_back();
}
for (int i = 0; i < MAP_ROW; ++i)
{
for (int j = 0; j < MAP_COL; ++j)
{
switch (pathArr[i][j].val)
{
case 5:
printf("* ");
break;
default:
printf("^ ");
}
}
printf("\n");
}
return 0;
}
C++ 深度寻路简单实现
最新推荐文章于 2020-11-02 21:20:46 发布