a星寻路

来源:互联网 发布:淘宝装修神器 编辑:程序博客网 时间:2024/06/05 09:56

关于A星寻路的介绍我就不多说了,网上到处都有,具体实现也各有写法,但大致还是一样的,下面是使用C++实现的源码,不足之处还望指出以便共同学习!

////  CAstar.h//  Astar////  Created by xujw on 15/4/9.//  Copyright (c) 2015年 xujw. All rights reserved.///*    F:路径评分 = g+h    G:走一格格子的花销    H:当前格子到目标格子的估算花销    上下左右走一格花销为10,斜着走一格花销为14,以方便计算    即格子宽高为10 对角线为14 */#ifndef __Astar__CAstar__#define __Astar__CAstar__#include <stdio.h>#include <vector>#include <iostream>using namespace std;//地图最大值#define MAX_X 10#define MAX_Y 10enum class AType{    ATYPE_UNKNOWN,    ATYPE_CLOSED,    ATYPE_OPENED,    ATYPE_BARRIER   //障碍};class APoint{public:    APoint();    ~APoint();    int x;    int y;    AType type;   //类型:障碍、开放列表、关闭列表    int f;  //f = g+h    int g;    int h;    APoint *parent;    bool operator == (const APoint& po)    {        if (x == po.x && y == po.y)        {            return true;        }        return false;    }};class CAstar{    vector<APoint*> _openList;      //开放列表    vector<APoint*> _closeList;     //关闭列表    vector<APoint*> _neighbourList; //周边节点    APoint* _endPoint;    APoint* _curPoint;    vector< vector<APoint*> > _allPoints;public:    CAstar();    ~CAstar();    APoint* findWay(APoint* beginPoint,APoint* endPoint,vector< vector<APoint*> >& allPoints);//    APoint* findWay(int beginX,int beginY,int endX,int endY);private:    int getF(APoint *point);    int getH(APoint *point);    vector<APoint*> getNeighboringPoint(APoint* point);};#endif /* defined(__Astar__CAstar__) */
////  CAstar.cpp//  Astar////  Created by xujw on 15/4/9.//  Copyright (c) 2015年 xujw. All rights reserved.////  上下左右走一格花销为10,斜着走一格花销为14,以方便计算//  即格子宽高为10 对角线为14#include "CAstar.h"//自定义排序函数bool mySort(const APoint* p1,const APoint* p2){    return p1->f < p2->f;}APoint::APoint():x(0)                ,y(0)                ,h(0)                ,f(0)                ,g(0)                ,parent(nullptr)                ,type(AType::ATYPE_UNKNOWN){}APoint::~APoint(){}#pragma mark------CAstar-------CAstar::CAstar():_endPoint(nullptr)                ,_curPoint(nullptr){}CAstar::~CAstar(){    _openList.clear();    _closeList.clear();    _neighbourList.clear();    _allPoints.clear();}APoint* CAstar::findWay(APoint *beginPoint, APoint *endPoint,vector< vector<APoint*> >& allPoints){    //传递地图    _allPoints = allPoints;    _endPoint = endPoint;    if (_endPoint->type == AType::ATYPE_BARRIER)    {        cout<<"终点是障碍"<<endl;        return nullptr;    }    if (*_endPoint == *beginPoint)    {        cout<<"起始点相同"<<endl;        return nullptr;    }    _openList.push_back(beginPoint);    beginPoint->type = AType::ATYPE_OPENED;    beginPoint->f = getF(beginPoint);    //---------    do    {        //获取最小值的节点        _curPoint = _openList[0];        _openList.erase(_openList.begin());        _curPoint->type = AType::ATYPE_CLOSED;        _closeList.push_back(_curPoint);        if (*_curPoint == *_endPoint)        {            cout<<"have find way"<<endl;            return _curPoint;        }        //获取相邻的节点        vector<APoint*> neVec = getNeighboringPoint(_curPoint);        for (int i = 0; i<neVec.size(); i++)        {            auto tmpoint = neVec[i];            if (tmpoint->type == AType::ATYPE_CLOSED)            {                continue;            }            //是否在开放列表里            if (tmpoint->type != AType::ATYPE_OPENED)            {                tmpoint->parent = _curPoint;                tmpoint->g = _curPoint->g + 10;                //计算H值                tmpoint->h = getH(tmpoint);                //添加到开放列表里                _openList.push_back(tmpoint);                tmpoint->type = AType::ATYPE_OPENED;            }            else            {                //已经在开放列表里                if (tmpoint->h < _curPoint->h)                {                    tmpoint->parent = _curPoint;                    tmpoint->g = _curPoint->g + 10;                }            }        }        //排序 F值最小的排在前面        sort(_openList.begin(), _openList.end(), mySort);    } while (_openList.size()>0);    cout<<"---can not find way---"<<endl;    return nullptr;}//APoint* CAstar::findWay(int beginX, int beginY, int endX, int endY)//{//    //    //    return nullptr;//}int CAstar::getF(APoint *point){    return (point->g + getH(point));}int CAstar::getH(APoint *point){    //曼哈顿城市街区估算法    return (abs(_endPoint->y - point->y) + abs(_endPoint->x - point->x))*10;}vector<APoint*> CAstar::getNeighboringPoint(APoint *point){    _neighbourList.clear();//    cout<<"nei size:"<<_neighbourList.size()<<endl;    if (point->x < MAX_X-1)    {        if (_allPoints[point->x+1][point->y]->type != AType::ATYPE_BARRIER)        {            _neighbourList.push_back(_allPoints[point->x+1][point->y]);        }    }    if (point->x >0)    {        if (_allPoints[point->x-1][point->y]->type != AType::ATYPE_BARRIER)        {            _neighbourList.push_back(_allPoints[point->x-1][point->y]);        }    }    if (point->y < MAX_Y-1)    {        if (_allPoints[point->x][point->y+1]->type != AType::ATYPE_BARRIER)        {            _neighbourList.push_back(_allPoints[point->x][point->y+1]);        }    }    if (point->y >0)    {        if (_allPoints[point->x][point->y-1]->type != AType::ATYPE_BARRIER)        {            _neighbourList.push_back(_allPoints[point->x][point->y-1]);        }    }    return _neighbourList;}

下面是测试代码:

////  main.cpp//  Astar////  Created by xujw on 15/4/9.//  Copyright (c) 2015年 xujw. All rights reserved.//#include <iostream>#include "CAstar.h"void printMap(char map[MAX_X][MAX_Y],int width,int height){    for (int i = 0; i<width; i++)    {        for (int j = 0; j<height; j++)        {            printf("%c\t",map[i][j]);        }        printf("\n");    }}int main(int argc, const char * argv[]) {    cout<<"---map---"<<endl;    //初始化地图矩阵 0代表障碍    char mapdata[MAX_X][MAX_Y] =    {        {'1','0','0','1','0','1','1','1','1','1'},        {'1','1','1','1','0','1','1','1','1','1'},        {'0','0','0','1','0','1','1','1','1','1'},        {'1','0','0','1','0','1','1','1','1','0'},        {'1','1','1','1','0','1','1','1','1','1'},        {'1','1','0','0','1','1','1','1','1','1'},        {'1','1','1','1','1','1','1','1','1','1'},        {'1','0','0','1','1','1','1','1','1','1'},        {'1','1','0','0','1','1','1','1','1','1'},        {'1','0','1','1','1','1','1','1','1','1'},    };    printMap(mapdata, MAX_X, MAX_Y);    //创建地图    vector< vector<APoint*> > map;    for (int i = 0; i<MAX_X; i++)    {        vector<APoint*> tmp;        for (int j = 0; j<MAX_Y; j++)        {            APoint *point = new APoint();            point->x = i;            point->y = j;            if (mapdata[i][j]=='0')            {                point->type = AType::ATYPE_BARRIER;            }            tmp.push_back(point);        }        map.push_back(tmp);    }    //开始寻路    auto star = new CAstar();    auto point = star->findWay(map[0][0], map[9][9], map);    if (!point)    {        return 0;    }    cout<<"---下面是路径点(倒序)---"<<endl;    while (point)    {        mapdata[point->x][point->y] = '*';        cout<<point->x<<","<<point->y<<endl;        point = point->parent;    }    cout<<"---打印路径---"<<endl;    printMap(mapdata, MAX_X, MAX_Y);    //-------------释放内存----------    delete star;    for (int i = 0; i<MAX_X; i++)    {        for (int j = 10; j<MAX_Y; j++)        {            delete map[i][j];            map[i][j] = nullptr;        }    }    return 0;}

运行截图:
地图

路径

源码下载(使用Xcode可以直接运行):https://github.com/sky068/AStarSearch

0 0
原创粉丝点击