• Day8:寻路算法---深度寻路


    一、基础概念:

    寻路算法 --- 深度寻路算法_https://blog.csdn.net/weixin_60569662/article/details/123651939

    思路:

            1. 规定试探方向顺序
                顺时针(上 右 下 左)     逆时针(上 左 下 右)
            2. 实时记录每个点  当前试探方向
                实时记录每个点 是否走过
            3. 回退
                每走一步,栈结构存储当前位置
                需要回退的时候:
                    删除当前栈顶元素
                    跳到当前栈顶元素处
            4. 遇到终点  
                循环结束   栈结构存储起点到终点的路径
                整个地图都找不到终点   栈为空

     二、代码实现

    1.数据结构----栈的准备

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. template <class T>
    7. class MyStack
    8. {
    9. public:
    10. MyStack()
    11. {
    12. pBuffer = nullptr;
    13. len = maxLen = 0;
    14. }
    15. ~MyStack()
    16. {
    17. if (pBuffer)delete[]pBuffer;
    18. pBuffer = nullptr; len = maxLen = 0;
    19. }
    20. void pop() { if(len>0)len--; }
    21. T GetTop() { return pBuffer[len - 1]; }
    22. bool isEmpty() { return (len == 0); }
    23. void push(const T& data);
    24. private:
    25. T* pBuffer;
    26. int len;
    27. int maxLen;
    28. };
    29. template<class T>
    30. inline void MyStack::push(const T& data)
    31. {
    32. if (len >= maxLen)//此时需要另外开内存
    33. {
    34. maxLen +=(((maxLen >> 1>1)) ? maxLen >> 1 : 1);//若整除之后为0,至少得增加一个
    35. T* pNew = new T[maxLen];
    36. if (pBuffer)//之前存在的话,才需要进行memcpy
    37. {
    38. memcpy(pNew, pBuffer, len * sizeof(T));
    39. delete []pBuffer;
    40. }
    41. pBuffer = pNew;
    42. }
    43. pBuffer[len++] = data;
    44. //_ASSERTE(_CrtCheckMemory());
    45. }

    又遇到上次的bug了--->直接放上次写博客链接了。【BUG----优先级】7.9 被?:问号冒号表达式的优先级坑了icon-default.png?t=M666https://blog.csdn.net/zjjaibc/article/details/125694367?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22125694367%22%2C%22source%22%3A%22zjjaibc%22%7D&ctrtid=1RMiZ

    2.准备工作:

    辅助地图(是否走过、当前点的探索方向)、正式地图、描述坐标的类

    注:最好用0来初始化->0来代表第一个方向up&&用0来是否走过(一键初始化)

    1. #include"MyStack.h"
    2. #include
    3. #include
    4. #define ROWS 10
    5. #define COLS 10
    6. enum dir
    7. {
    8. UP, LEFT, DOWN, RIGHT
    9. };//默认值为0,1,2,3
    10. //辅助地图
    11. struct pathNode
    12. {
    13. int dir;//当前的探索方向
    14. bool isArrive;//是否走过了 0表示没走过
    15. };
    16. //人物or探索位置的坐标
    17. struct pos
    18. {
    19. int row;
    20. int col;
    21. bool operator==(const struct pos b)
    22. {
    23. return (row == b.row) && (col == b.col);
    24. }
    25. };
    26. int MAP[ROWS][COLS] =
    27. {{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
    28. { 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 },
    29. { 1, 0, 1, 0, 1, 1, 1, 1, 0, 1 },
    30. { 1, 0, 1, 0, 0, 0, 0, 1, 0, 1 },
    31. { 1, 0, 1, 0, 1, 1, 0, 0, 0, 1 },
    32. { 1, 0, 0, 0, 1, 1, 0, 1, 0, 1 },
    33. { 1, 0, 1, 1, 1, 0, 0, 1, 0, 1 },
    34. { 1, 0, 1, 0, 0, 0, 1, 1, 0, 1 },
    35. { 1, 0, 1, 0, 1, 1, 1, 0, 0, 1 },
    36. { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }};//0表示road
    37. struct pos beg_xy = { 1,1 };//起点
    38. struct pos pos_xy = { 8,7 };//终点
    39. struct pathNode pathmap[ROWS][COLS] = { 0 };//一键重置新地图(0->up&&没走过)
    40. IMAGE people, road, wall, pos,beg,ball;
    41. #define WIDTH 80 //单个贴图的大小
    42. void drawmap(int MAP[ROWS][COLS],struct pos pep, struct pos beg, struct pos end);
    43. void init();
    1. void init()
    2. {
    3. //1.创建窗口
    4. initgraph(COLS * WIDTH, ROWS * WIDTH, SHOWCONSOLE);
    5. //2.加载绑定图片(注意字符集兼容问题)
    6. loadimage(&people,"res/people.bmp", WIDTH, WIDTH, true);
    7. loadimage(&wall, "res/wall.bmp", WIDTH, WIDTH, true);
    8. loadimage(&road, "res/road.bmp", WIDTH, WIDTH, true);
    9. loadimage(&pos, "res/pos.bmp", WIDTH, WIDTH, true);
    10. loadimage(&beg, "res/beg.bmp", WIDTH, WIDTH, true);
    11. loadimage(&ball, "res/ball.bmp", WIDTH/2, WIDTH/2, true);
    12. }
    13. void drawmap(int MAP[ROWS][COLS],struct pos pep,struct pos begin,struct pos end)
    14. {
    15. for (int i = 0; i < COLS; i++)
    16. {
    17. for (int j = 0; j < ROWS; j++)
    18. {
    19. if (pep.row == i && pep.col == j)
    20. putimage(j * WIDTH, i * WIDTH, &people);
    21. else if (begin.row == i && begin.col == j)
    22. putimage(j * WIDTH, i * WIDTH, &beg);
    23. else if (end.row == i && end.col == j)
    24. putimage(j * WIDTH, i * WIDTH, &pos);
    25. else if (MAP[i][j] == 1)
    26. putimage(j * WIDTH, i * WIDTH, &wall);
    27. else if (MAP[i][j] == 0)
    28. putimage(j * WIDTH, i * WIDTH, &road);
    29. }
    30. }
    31. }

    3.核心逻辑(栈的回退->探索到最后一个方向right开始判断)

    1.已知当前点的坐标,找试探点-> 在辅助地图中记录了当前点的当前试探方向

    2.判断试探点是否能走, 如果能走,走的时候标记点已经走过了,要入栈 如果不能走:

            2.1.(前面三个方向中某一个能走)试探方向改变 

            2.2.(第四个方向还是不能走) 回退,删除栈顶元素,跳到当前栈顶元素处即可 

    3.判断是否结束循环

            3.1找到终点了

            3.2没有找到终点,但是栈空了-> 整个地图都找遍了

    1. int main()
    2. {
    3. init();
    4. struct pos people_xy=beg_xy;
    5. struct pos search_xy;
    6. MyStack<struct pos>trait;//存放路径
    7. trait.push(beg_xy);//起点入栈
    8. pathmap[beg_xy.row][beg_xy.col].isArrive = true;//起点标记走过
    9. bool isFind = false;
    10. while (!isFind)
    11. {
    12. search_xy = people_xy;//每次循环之前,都要重置searchNode的位置
    13. //cout << pathmap[people_xy.row][people_xy.col].dir << endl;
    14. switch (pathmap[people_xy.row][people_xy.col].dir)
    15. {
    16. case UP:
    17. pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
    18. search_xy.row--;
    19. if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
    20. pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
    21. {
    22. people_xy = search_xy;//走一步
    23. pathmap[search_xy.row][search_xy.col].isArrive = true;//标记走过!!
    24. trait.push(people_xy);//入栈
    25. }
    26. break;
    27. case LEFT:
    28. pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
    29. search_xy.col--;
    30. if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
    31. pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
    32. {
    33. people_xy = search_xy;//走一步
    34. pathmap[search_xy.row][search_xy.col].isArrive = true;
    35. trait.push(people_xy);//入栈
    36. }
    37. break;
    38. case DOWN:
    39. pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
    40. search_xy.row++;
    41. if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
    42. pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
    43. {
    44. people_xy = search_xy;//走一步
    45. pathmap[search_xy.row][search_xy.col].isArrive = true;
    46. trait.push(people_xy);//入栈
    47. }
    48. break;
    49. case RIGHT:
    50. //pathmap[people_xy.row][people_xy.col].dir++;//先改变当前点的dir!!!便于下次寻路
    51. search_xy.col++;
    52. if (MAP[search_xy.row][search_xy.col] == 0 &&//是路road 0
    53. pathmap[search_xy.row][search_xy.col].isArrive == 0)//且没走过
    54. {
    55. people_xy = search_xy;//走一步
    56. pathmap[search_xy.row][search_xy.col].isArrive = true;
    57. trait.push(people_xy);//入栈
    58. break;
    59. }//如果到这了,还没有break,那么说明此点不能走->需要回退
    60. trait.pop();
    61. people_xy = trait.GetTop();//别忘记改人物位置
    62. }
    63. Sleep(20);
    64. drawmap(MAP, people_xy, beg_xy, pos_xy);
    65. if (pos_xy == people_xy)isFind = true;
    66. if (trait.isEmpty())break;
    67. }//在栈上开辟的空间记得释放
    68. if (isFind)
    69. {
    70. cout << "找到了!" << endl;
    71. while (!trait.isEmpty())
    72. {
    73. cout << '[' << trait.GetTop().row << ',' << trait.GetTop().col << ']';
    74. putimage(trait.GetTop().col * WIDTH + WIDTH / 4, trait.GetTop().row * WIDTH + WIDTH / 4, &ball);
    75. trait.pop();
    76. }
    77. }
    78. while (1);
    79. return 0;
    80. }

  • 相关阅读:
    【毕业设计】基于SSM的OA办公管理系统的设计与实现 -java web
    VMware NSX 4.0 -- 网络安全虚拟化平台
    IDEA-插件开发踩坑记录-第四坑-Action介绍与工具栏、弹出菜单中运用
    SOLIDWORKS 2023新功能揭秘!升级版轻松找到材料明细表修改
    HTTP协议和HTTPServlet
    581. 最短无序连续子数组
    【开发利器】使用OpenCV算子工作流高效开发
    Win7安装Python + PyCharm
    Java编程学习-MySQL(数据库CRUD语句)
    UserloginMapper文件报错
  • 原文地址:https://blog.csdn.net/zjjaibc/article/details/125985318