数据结构学习第十八课(寻路算法之深度寻路)
程序员文章站
2022-03-08 11:54:20
...
寻路算法
/*
寻路算法:
找路径
1 深度寻路:不一定能找到最短路径,回退,循环较少,步骤简单,适用于空旷地图;只能走直线
2 广度寻路:一定能找到最短路径,不需要回退,循环较多,步骤复杂,适用于较小的复杂地图;只能走直线
3 A星寻路:一定能找到最短路径,不需要回退,循环较少,但需要提前设计好代价;只能走斜线
*/
1,深度寻路
1.1头文件
#pragma once
#include<string.h>
template<typename T>
class MyStack
{
private:
T* pRoot;
int len;
int maxLen;
public:
MyStack()
{
pRoot = NULL;
len = 0;
maxLen = 0;
}
~MyStack()
{
if (pRoot)
{
delete[] pRoot;
}
pRoot = NULL;
len = 0;
maxLen = 0;
}
//入栈
void push(const T& data);
//判空
bool isEmpty()const
{
return (len == 0);
}
//出栈
void pop() { len--; };
//获取栈顶元素
T GetTop()const
{
return pRoot[len - 1];
}
};
template<typename T>
void MyStack<T>::push(const T& data)
{
if (len <= maxLen)
{
maxLen = maxLen + (((maxLen >> 1) > 1) ? (maxLen >> 1) : 1);
T* pTemp = new T[maxLen];
memcpy(pTemp, pRoot, sizeof(T) * len);
delete[] pRoot;
pRoot = pTemp;
}
pRoot[len++] = data;
}
2.2源文件
/*
深度寻路思想:
1 记录当前点当前试探方向
试探方向顺序:一般:逆时针(上左下右) / 顺时针(上右下左);
2 记录当前点是否走过
2.1 每走过一步,入栈
2.2 需要回退的时候 死胡同时 回退
2.2.1 删除栈顶元素
2.2.2 跳到当前栈顶元素的位置
*/
#include<stdio.h>
#include<stack>
#include<graphics.h>
#include"Mystack.h"
#define SPACE 50
using namespace std;
#define ROW 12
#define COL 12
//地图中元素类型
enum type{p_road,p_wall};
//方向
enum dirc{p_up,p_down,p_left,p_right};
//描述一个点
struct Point
{
int row;
int col;
bool operator==(const Point& p)
{
if (this->row == p.row && this->col == p.col)
{
return true;
}
return false;
}
};
//辅助地图结点类型
struct pathNode
{
int dir;//当前试探方向
bool isFind;//是否走过
};
IMAGE wall, ren, road, pos;
void printMap(Point pos, int map[ROW][COL]);
void showMap(Point pos, int map[ROW][COL]);
int main()
{
initgraph(COL * SPACE, ROW * SPACE, SHOWCONSOLE);
loadimage(&wall, "wall.bmp", SPACE, SPACE, true);
loadimage(&ren, "ren.bmp", SPACE, SPACE, true);
loadimage(&road, "road.bmp", SPACE, SPACE, true);
loadimage(&pos, "pos.bmp", SPACE/2, SPACE/2, true);
//1 描述地图
int map[ROW][COL] =
{
{1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,0,1,1,1,1,0,0,1},
{1,0,1,1,0,0,0,1,1,0,1,1},
{1,0,1,1,0,1,0,1,1,0,1,1},
{1,0,1,1,0,1,0,1,1,0,1,1},
{1,0,1,1,0,1,0,1,1,0,1,1},
{1,0,1,1,0,1,0,0,1,0,1,1},
{1,0,1,1,0,1,1,0,1,0,1,1},
{1,0,0,0,0,1,1,0,1,0,1,1},
{1,0,1,1,0,1,1,0,1,0,1,1},
{1,0,1,1,0,1,1,0,0,0,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1}
};
//2 记录当前点当前试探方向,是否走过
pathNode pathMap[ROW][COL] = { 0 };
//3 起点 终点
bool isFindEnd = false;
Point begPos = { 1,1 };
Point endPos = { 1,10 };
//4 栈
MyStack<Point> stack;
//5 标记起点走过的,起点入栈
stack.push(begPos);
pathMap[begPos.row][begPos.col].isFind = true;
//6 寻路
Point curPos = begPos;
Point serPos;
while (1)
{
//6.1确定试探点
serPos = curPos;//先将试探点设置为当前点
switch (pathMap[curPos.row][curPos.col].dir)
{
case p_up:
serPos.row--;//根据当前点当前试探方向,确定试探点
//当前点当前试探方向改变
pathMap[curPos.row][curPos.col].dir = p_down;
if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
map[serPos.row][serPos.col] == p_road)//有路
{
//能走
//走
curPos = serPos;
//标记走过
pathMap[curPos.row][curPos.col].isFind = true;
//入栈
stack.push(curPos);
}
break;
case p_down:
serPos.row++;//根据当前点当前试探方向,确定试探点
//当前点当前试探方向改变
pathMap[curPos.row][curPos.col].dir = p_left;
if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
map[serPos.row][serPos.col] == p_road)//有路
{
//能走
//走
curPos = serPos;
//标记走过
pathMap[curPos.row][curPos.col].isFind = true;
//入栈
stack.push(curPos);
}
break;
case p_left:
serPos.col--;//根据当前点当前试探方向,确定试探点
//当前点当前试探方向改变
pathMap[curPos.row][curPos.col].dir = p_right;
if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
map[serPos.row][serPos.col] == p_road)//有路
{
//能走
//走
curPos = serPos;
//标记走过
pathMap[curPos.row][curPos.col].isFind = true;
//入栈
stack.push(curPos);
}
break;
case p_right:
serPos.col++;//根据当前点当前试探方向,确定试探点
if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
map[serPos.row][serPos.col] == p_road)//有路
{
//能走
//走
curPos = serPos;
//标记走过
pathMap[curPos.row][curPos.col].isFind = true;
//入栈
stack.push(curPos);
}
else
{
//死胡同
//删除栈顶元素
stack.pop();
//跳到当前栈顶元素
curPos = stack.GetTop();
}
break;
}
printMap(curPos, map);
showMap(curPos, map);
//判断到没到终点
if (curPos == endPos)
{
isFindEnd = true;
break;
}
//判断是否回到起点
if (stack.isEmpty())
break;
}
if (isFindEnd)
{
printf("找到了终点!!!\n");
while (!stack.isEmpty())
{
printf("(%d %d)", stack.GetTop().row,
stack.GetTop().col);
putimage(stack.GetTop().col * SPACE
+SPACE/3,
stack.GetTop().row * SPACE + SPACE / 3,
&pos);
stack.pop();
}
printf("\n");
}
else
{
printf("没找到终点!!!\n");
}
while (1);
return 0;
}
void printMap(Point pos, int map[ROW][COL])
{
system("cls");
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
if (pos.row == i && pos.col == j)
{
printf("人");
}
else if(p_road==map[i][j])
{
printf(" ");
}
else
{
printf("墙");
}
}
printf("\n");
}
}
void showMap(Point pos, int map[ROW][COL])
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
if (pos.row == i && pos.col == j)
{
putimage(j * SPACE, i * SPACE, &ren);
}
else if (p_road == map[i][j])
{
putimage(j * SPACE, i * SPACE, &road);
}
else
{
putimage(j * SPACE, i * SPACE, &wall);
}
}
printf("\n");
}
}