寻路算法 --- 深度寻路算法_https://blog.csdn.net/weixin_60569662/article/details/123651939
思路:
1. 规定试探方向顺序
顺时针(上 右 下 左) 逆时针(上 左 下 右)
2. 实时记录每个点 当前试探方向
实时记录每个点 是否走过
3. 回退
每走一步,栈结构存储当前位置
需要回退的时候:
删除当前栈顶元素
跳到当前栈顶元素处
4. 遇到终点
循环结束 栈结构存储起点到终点的路径
整个地图都找不到终点 栈为空
- #pragma once
- #include
- #include
- #include
- using namespace std;
-
- template <class T>
- class MyStack
- {
- public:
- MyStack()
- {
- pBuffer = nullptr;
- len = maxLen = 0;
- }
- ~MyStack()
- {
- if (pBuffer)delete[]pBuffer;
- pBuffer = nullptr; len = maxLen = 0;
- }
- void pop() { if(len>0)len--; }
- T GetTop() { return pBuffer[len - 1]; }
- bool isEmpty() { return (len == 0); }
- void push(const T& data);
- private:
- T* pBuffer;
- int len;
- int maxLen;
- };
-
- template<class T>
- inline void MyStack
::push(const T& data) - {
- if (len >= maxLen)//此时需要另外开内存
- {
- maxLen +=(((maxLen >> 1>1)) ? maxLen >> 1 : 1);//若整除之后为0,至少得增加一个
- T* pNew = new T[maxLen];
- if (pBuffer)//之前存在的话,才需要进行memcpy
- {
- memcpy(pNew, pBuffer, len * sizeof(T));
- delete []pBuffer;
- }
- pBuffer = pNew;
- }
- pBuffer[len++] = data;
- //_ASSERTE(_CrtCheckMemory());
- }
辅助地图(是否走过、当前点的探索方向)、正式地图、描述坐标的类
注:最好用0来初始化->0来代表第一个方向up&&用0来是否走过(一键初始化)
- #include"MyStack.h"
- #include
- #include
-
- #define ROWS 10
- #define COLS 10
-
- enum dir
- {
- UP, LEFT, DOWN, RIGHT
- };//默认值为0,1,2,3
-
- //辅助地图
- struct pathNode
- {
- int dir;//当前的探索方向
- bool isArrive;//是否走过了 0表示没走过
- };
- //人物or探索位置的坐标
- struct pos
- {
- int row;
- int col;
- bool operator==(const struct pos b)
- {
- return (row == b.row) && (col == b.col);
- }
- };
- int MAP[ROWS][COLS] =
- {{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- { 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 },
- { 1, 0, 1, 0, 1, 1, 1, 1, 0, 1 },
- { 1, 0, 1, 0, 0, 0, 0, 1, 0, 1 },
- { 1, 0, 1, 0, 1, 1, 0, 0, 0, 1 },
- { 1, 0, 0, 0, 1, 1, 0, 1, 0, 1 },
- { 1, 0, 1, 1, 1, 0, 0, 1, 0, 1 },
- { 1, 0, 1, 0, 0, 0, 1, 1, 0, 1 },
- { 1, 0, 1, 0, 1, 1, 1, 0, 0, 1 },
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }};//0表示road
- struct pos beg_xy = { 1,1 };//起点
- struct pos pos_xy = { 8,7 };//终点
-
- struct pathNode pathmap[ROWS][COLS] = { 0 };//一键重置新地图(0->up&&没走过)
-
- IMAGE people, road, wall, pos,beg,ball;
-
- #define WIDTH 80 //单个贴图的大小
- void drawmap(int MAP[ROWS][COLS],struct pos pep, struct pos beg, struct pos end);
- void init();
- void init()
- {
- //1.创建窗口
- initgraph(COLS * WIDTH, ROWS * WIDTH, SHOWCONSOLE);
- //2.加载绑定图片(注意字符集兼容问题)
- loadimage(&people,"res/people.bmp", WIDTH, WIDTH, true);
- loadimage(&wall, "res/wall.bmp", WIDTH, WIDTH, true);
- loadimage(&road, "res/road.bmp", WIDTH, WIDTH, true);
- loadimage(&pos, "res/pos.bmp", WIDTH, WIDTH, true);
- loadimage(&beg, "res/beg.bmp", WIDTH, WIDTH, true);
- loadimage(&ball, "res/ball.bmp", WIDTH/2, WIDTH/2, true);
- }
-
- void drawmap(int MAP[ROWS][COLS],struct pos pep,struct pos begin,struct pos end)
- {
- for (int i = 0; i < COLS; i++)
- {
- for (int j = 0; j < ROWS; j++)
- {
- if (pep.row == i && pep.col == j)
- putimage(j * WIDTH, i * WIDTH, &people);
- else if (begin.row == i && begin.col == j)
- putimage(j * WIDTH, i * WIDTH, &beg);
- else if (end.row == i && end.col == j)
- putimage(j * WIDTH, i * WIDTH, &pos);
- else if (MAP[i][j] == 1)
- putimage(j * WIDTH, i * WIDTH, &wall);
- else if (MAP[i][j] == 0)
- putimage(j * WIDTH, i * WIDTH, &road);
- }
- }
- }
1.已知当前点的坐标,找试探点-> 在辅助地图中记录了当前点的当前试探方向
2.判断试探点是否能走, 如果能走,走的时候标记点已经走过了,要入栈 如果不能走:
2.1.(前面三个方向中某一个能走)试探方向改变
2.2.(第四个方向还是不能走) 回退,删除栈顶元素,跳到当前栈顶元素处即可
3.判断是否结束循环
3.1找到终点了
3.2没有找到终点,但是栈空了-> 整个地图都找遍了
-
- int main()
- {
- init();
- struct pos people_xy=beg_xy;
- struct pos search_xy;
-
- MyStack<struct pos>trait;//存放路径
- trait.push(beg_xy);//起点入栈
- pathmap[beg_xy.row][beg_xy.col].isArrive = true;//起点标记走过
-
- bool isFind = false;
- while (!isFind)
- {
- search_xy = people_xy;//每次循环之前,都要重置searchNode的位置
- //cout << pathmap[people_xy.row][people_xy.col].dir << endl;
- switch (pathmap[people_xy.row][people_xy.col].dir)
- {
- case UP:
- pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
- search_xy.row--;
- if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
- pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
- {
- people_xy = search_xy;//走一步
- pathmap[search_xy.row][search_xy.col].isArrive = true;//标记走过!!
- trait.push(people_xy);//入栈
- }
- break;
- case LEFT:
- pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
- search_xy.col--;
- if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
- pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
- {
- people_xy = search_xy;//走一步
- pathmap[search_xy.row][search_xy.col].isArrive = true;
- trait.push(people_xy);//入栈
- }
- break;
- case DOWN:
- pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
- search_xy.row++;
- if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
- pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
- {
- people_xy = search_xy;//走一步
- pathmap[search_xy.row][search_xy.col].isArrive = true;
- trait.push(people_xy);//入栈
- }
- break;
- case RIGHT:
- //pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
- search_xy.col++;
- if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
- pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
- {
- people_xy = search_xy;//走一步
- pathmap[search_xy.row][search_xy.col].isArrive = true;
- trait.push(people_xy);//入栈
- break;
- }//如果到这了,还没有break,那么说明此点不能走->需要回退
-
- trait.pop();
- people_xy = trait.GetTop();//别忘记改人物位置
- }
- Sleep(20);
- drawmap(MAP, people_xy, beg_xy, pos_xy);
- if (pos_xy == people_xy)isFind = true;
- if (trait.isEmpty())break;
- }//在栈上开辟的空间记得释放
- if (isFind)
- {
- cout << "找到了!" << endl;
- while (!trait.isEmpty())
- {
- cout << '[' << trait.GetTop().row << ',' << trait.GetTop().col << ']';
- putimage(trait.GetTop().col * WIDTH + WIDTH / 4, trait.GetTop().row * WIDTH + WIDTH / 4, &ball);
- trait.pop();
- }
- }
- while (1);
- return 0;
- }