• AStar寻路


    #include "pch.h"
    #include <iostream>
    #include <vector>
    #include <windows.h>
    using namespace std;
    //行 高
    #define ROW 12
    //列 宽
    #define COL 12
    
    #define ZXDJ 10
    #define XXDJ 14
    
    struct MyPoint
    {
        int row;
        int col;
        //g起点到当前点代价
        //w权重
        //h当前点到终点的预估代价 忽略障碍只看直线
        //f = g+h+w
        int g, h, f;
        void setF() { f = g + h; }
    };
    
    
    //八个方向
    enum direct {
        p_up,p_down,p_left,p_right,p_lup,p_ldown,p_rup,p_rdown
    };
    
    
    //辅助地图节点
    //记录走过没,代价值
    struct pathNode
    {
        int val;//
        bool isFind;//走过没,true走过
    
    };
    
    //判断pos点能不能走,能true
    bool canWalk(MyPoint pos, pathNode pathMap[ROW][COL]) {
        //不在地图内
        if (pos.row < 0||pos.row>=ROW||pos.col<0||pos.col>=COL) {
        return false;}
        //是障碍,不能走
        if (pathMap[pos.row][pos.col].val == 1)return false;
        //走过了
        if (pathMap[pos.row][pos.col].isFind == 1)return false;
        return true;
    }
    
    
    //树的节点类型,使用树存储走过路径
    struct treeNode {
        MyPoint pos;
        treeNode* pParent;//指向父节点指针
        vector<treeNode*> child;//保存所有孩子节点数组
    };
    
    
    
    //计算g值
    int getG(MyPoint pos,MyPoint endPos);
    
    
    int main()
    {
        //地图 0:路  1:障碍  2:大楼 3:井盖
        int map[ROW][COL] = {
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,1,0,0,0,0,0,0},
        };
        //2 起点和重点
        MyPoint begPos = {1,1};
        MyPoint endPos = { 5,10 };
        //3 记录,辅助地图,初始化
        pathNode pathMap[ROW][COL] = { 0 };
        for (int i = 0;i<ROW;i++)
            for (int j = 0; j < COL; j++)
            {
                pathMap[i][j].val = map[i][j];
            }
    
        //4 创建一棵树
        treeNode* pRoot = NULL;
    
        //5 标记起点点走过
        pathMap[begPos.row][begPos.col].isFind = true;
    
        //6 起点入数成为根节点
        pRoot = new treeNode;
        memset(pRoot, 0, sizeof treeNode);//清空
        pRoot->pos = begPos;
    
        //7 准备一个数组保存所有评估点
        vector<treeNode*> buff;
        //迭代器找最小点
        vector<treeNode*>::iterator itMin;
        vector<treeNode*>::iterator it;
        //8 寻路
        bool isFindEnd = false;
        //当前点
        MyPoint currentPos = begPos;
        //当前树节点
        treeNode* pTemp = pRoot;
        while (true)
        {
            //8.1 检查当前点哪些需要计算
            for (int i = 0; i < 8; i++) {
                treeNode* pChild = new treeNode;
                memset(pChild, 0, sizeof treeNode);
                pChild->pos = pTemp->pos;
                switch (i)
                {
                case p_up:
                    pChild->pos.row--;
                    pChild->pos.g = 10;
                    break;
                case p_down:
                    pChild->pos.row++;
                    pChild->pos.g = 10;
                    break;
                case p_left:
                    pChild->pos.col--;
                    pChild->pos.g = 10;
                    break;
                case p_right:
                    pChild->pos.col++;
                    pChild->pos.g = ZXDJ;
                    break;
                case p_lup:
                    pChild->pos.col--;
                    pChild->pos.row--;
                    pChild->pos.g = XXDJ;
                    break;
                case p_ldown:
                    pChild->pos.col--;
                    pChild->pos.row++;
                    pChild->pos.g = XXDJ;
                    break;
                case p_rup:
                    pChild->pos.col++;
                    pChild->pos.row--;
                    pChild->pos.g = XXDJ;
                    break;
                case p_rdown:
                    pChild->pos.col++;
                    pChild->pos.row++;
                    pChild->pos.g = XXDJ;
                    break;
                default:
                    break;
                }//8.2 计算所有点f
                //8.2.1 判断是否计算(能走不)
                if (canWalk(pChild->pos,pathMap)) {
                //8.2.2 jisuanf
                    pChild->pos.g = getG(pChild->pos, endPos);
                    pChild->pos.setF();
                    //8.2.3 判断能否入树buff
                    pTemp->child.push_back(pChild);
                    pChild->pParent = pTemp;
                    buff.push_back(pChild);
                    //printf("(%d,%d)", pChild->pos.row, pChild->pos.col);
                }
                
    
            }
            //cout << endl;
            //Sleep(2000);
            //8.3 找出f值最小的点,走,并从buff中删除该店
            itMin = buff.begin();
            for (it = buff.begin(); it != buff.end(); it++) {
                if ((*itMin)->pos.f > (*it)->pos.f) {
                    itMin = it;
                }
            }
    
            pathMap[pTemp->pos.row][pTemp->pos.col].isFind = true;
            pTemp = *itMin;//
            buff.erase(itMin);
            //8.4 判断是否找到重点,判断整个地图是否没有终点
            if (pTemp->pos.row == endPos.row&&
                pTemp->pos.col == endPos.col) {
                isFindEnd = true;
                break;
            }
            if (buff.empty()) { break; }
        }
        //9 打印路径
        if (isFindEnd) {
            printf("找到终点了!
    ");
            while (pTemp) {
                printf("(%d,%d)", pTemp->pos.row, pTemp->pos.col);
                pTemp = pTemp->pParent;
            }
            cout << "
    ";
        }
    
        cout << fun();
        system("pause");
    }
    
    
    
    int getG(MyPoint pos, MyPoint endPos) {
        int x = ((pos.col > endPos.col) ? (pos.col - endPos.col) : (endPos.col - pos.col));
        int y = ((pos.row > endPos.row) ? (pos.row - endPos.row) : (endPos.row - pos.row));
        return ZXDJ * (x + y);
    }
    // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
    // 调试程序: F5 或调试 >“开始调试”菜单
    
    // 入门提示: 
    //   1. 使用解决方案资源管理器窗口添加/管理文件
    //   2. 使用团队资源管理器窗口连接到源代码管理
    //   3. 使用输出窗口查看生成输出和其他消息
    //   4. 使用错误列表窗口查看错误
    //   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
    //   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

  • 相关阅读:
    消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!
    消息中间件——RabbitMQ(五)快速入门生产者与消费者,SpringBoot整合RabbitMQ!
    消息中间件——RabbitMQ(四)命令行与管控台的基本操作!
    消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!
    LayUI的基本使用
    Git报错:Your branch is up to date with 'origin/master'.
    Git报错:Please tell me who you are.
    Git报错:Permission denied (publickey)
    在 windows 上安装 git 2.22
    在 windows 上安装 git 2.15
  • 原文地址:https://www.cnblogs.com/Knight66666/p/13298812.html
Copyright © 2020-2023  润新知