A星算法(游戏寻路算法)的C++实现

A星算法的实现原理看这里:http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html

 

    实现部分:

    头文件:

 

[cpp] view plain copy

 

  1. /* 
  2.     A star 算法的基础处理 
  3. */  
  4. #ifndef _A_STAR_BASE_H_  
  5. #define _A_STAR_BASE_H_  
  6. #include "windows.h"  
  7.   
  8. typedef struct _APoint{  
  9.     int x; // x 坐标  
  10.     int y; // y 坐标  
  11.     int type; // 类型  
  12.     int f; // f = g + h  
  13.     int g;   
  14.     int h;  
  15. } APoint,*PAPoint;  
  16.   
  17. enum APointType{  
  18.     APT_UNKNOWN, // 未知状态  
  19.     APT_OPENED, // 开放列表中  
  20.     APT_CLOSED, // 关闭列表中  
  21.     APT_STARTPOINT, // 起始点  
  22.     APT_ENDPOINT // 结束点  
  23. };  
  24.   
  25.   
  26. class CAStarBase{  
  27. public:  
  28.     CAStarBase();  
  29.     ~CAStarBase();  
  30. private:  
  31.     PAPoint m_pAPointArr;  
  32.     int m_nAPointArrWidth;  
  33.     int m_nAPointArrHeight;  
  34.   
  35.     PAPoint m_pStartPoint,m_pEndPoint,m_pCurPoint;  
  36.     char* m_pOldArr;  
  37. public:  
  38.     BOOL Create(char* pDateArr,int nWidth,int nHeight);  
  39.     void SetStartPoint(int x,int y);  
  40.     void SetEndPoint(int x,int y);  
  41.     void SetOpened(int x,int y);  
  42.     void SetClosed(int x,int y);  
  43.     void SetCurrent( int x,int y );  
  44.     void PrintCharArr();  
  45.   
  46.     PAPoint CalcNextPoint(PAPoint ptCalc); // 应用迭代的办法进行查询  
  47. };  
  48.   
  49. #endif  


实现cpp文件:

 

 

[cpp] view plain copy

 

 

  1. #include "stdafx.h"  
  2. #include "AStarBase.h"  
  3.   
  4.   
  5. CAStarBase::CAStarBase()  
  6. {  
  7.     m_pAPointArr = NULL;  
  8.     m_nAPointArrWidth = 0;  
  9.     m_nAPointArrHeight = 0;  
  10.   
  11.     m_pStartPoint = NULL;  
  12.     m_pEndPoint = NULL;  
  13.     m_pCurPoint = NULL;  
  14.   
  15. }  
  16.   
  17. CAStarBase::~CAStarBase()  
  18. {  
  19.   
  20. }  
  21.   
  22. BOOL CAStarBase::Create( char* pDateArr,int nWidth,int nHeight )  
  23. {  
  24.     if(!pDateArr) return FALSE;  
  25.     if(nWidth<1 || nHeight<1) return FALSE;  
  26.     m_pAPointArr = new APoint[nWidth*nHeight];  
  27.     if(!m_pAPointArr) return FALSE;  
  28.     m_pOldArr = pDateArr;  
  29.     m_nAPointArrWidth = nWidth;  
  30.     m_nAPointArrHeight = nHeight;  
  31.     // 初始化数组内容  
  32.     for ( int y = 0;y
  33.     {  
  34.         for ( int x=0;x
  35.         {  
  36.             m_pAPointArr[y*m_nAPointArrWidth+x].x = x;  
  37.             m_pAPointArr[y*m_nAPointArrWidth+x].y = y;  
  38.             m_pAPointArr[y*m_nAPointArrWidth+x].g = 0;  
  39.             m_pAPointArr[y*m_nAPointArrWidth+x].f = 0;  
  40.             m_pAPointArr[y*m_nAPointArrWidth+x].h = 0;  
  41.   
  42.             if ( pDateArr[y*m_nAPointArrWidth+x] == '0')  
  43.             {  
  44.                 m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_OPENED;  
  45.             }else if ( pDateArr[y*m_nAPointArrWidth+x] == '1')  
  46.             {  
  47.                 m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_CLOSED;  
  48.             }else if ( pDateArr[y*m_nAPointArrWidth+x] == 'S')  
  49.             {  
  50.                 m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_STARTPOINT;  
  51.                 m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x;  
  52.                 m_pCurPoint = m_pStartPoint;  
  53.             }else if ( pDateArr[y*m_nAPointArrWidth+x] == 'E')  
  54.             {  
  55.                 m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_ENDPOINT;  
  56.                 m_pEndPoint = m_pAPointArr + y*m_nAPointArrWidth+x;  
  57.             }else{  
  58.                 m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_UNKNOWN;  
  59.             }  
  60.   
  61.         }  
  62.     }  
  63.     return TRUE;  
  64. }  
  65.   
  66. void CAStarBase::SetStartPoint( int x,int y )  
  67. {  
  68.     if ( m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED )  
  69.     {  
  70.         m_pStartPoint->type = APT_OPENED;  
  71.         // 设置新的值  
  72.         m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x;  
  73.         m_pStartPoint->type = APT_STARTPOINT;  
  74.         m_pCurPoint = m_pStartPoint;  
  75.     }  
  76. }  
  77.   
  78. void CAStarBase::SetEndPoint( int x,int y )  
  79. {  
  80.     if ( m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED )  
  81.     {  
  82.         m_pStartPoint->type = APT_OPENED;  
  83.         // 设置新的值  
  84.         m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x;  
  85.         m_pStartPoint->type = APT_ENDPOINT;  
  86.     }  
  87. }  
  88.   
  89. void CAStarBase::SetCurrent( int x,int y )  
  90. {  
  91. //  if ( m_pAPointArr[y*m_nAPointArrWidth+x].type==APT_OPENED )  
  92.     {  
  93.         m_pCurPoint = m_pAPointArr+y*m_nAPointArrWidth+x;  
  94.     }  
  95. }  
  96.   
  97. void CAStarBase::SetOpened( int x,int y )  
  98. {  
  99.     if ( m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_OPENED )  
  100.     {  
  101.         m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_OPENED;  
  102.     }  
  103. }  
  104.   
  105. void CAStarBase::SetClosed( int x,int y )  
  106. {  
  107.     if ( m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED )  
  108.     {  
  109.         m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_CLOSED;  
  110.     }  
  111. }  
  112.   
  113. void CAStarBase::PrintCharArr()  
  114. {  
  115.     if ( m_pOldArr )  
  116.     {  
  117.         for ( int y=0; y
  118.         {  
  119.             for ( int x=0;x
  120.             {  
  121.                 printf("%c ",m_pOldArr[x+m_nAPointArrWidth*y]);  
  122.             }  
  123.             printf("\r\n");  
  124.         }  
  125.         printf("\r\n");  
  126.     }  
  127. }  
  128.   
  129. PAPoint CAStarBase::CalcNextPoint( PAPoint ptCalc )  
  130. {  
  131.     if ( ptCalc == NULL )  
  132.     {  
  133.         ptCalc = m_pStartPoint;  
  134.     }  
  135.     int x = ptCalc->x;  
  136.     int y = ptCalc->y;  
  137.     int dx = m_pEndPoint->x;  
  138.     int dy = m_pEndPoint->y;  
  139.     int xmin = x,ymin = y,vmin = 0; // 最优步骤的坐标和值  
  140.     // 判断是否已经到了最终的位置  
  141.     if ( (x==dx && abs(y-dy)==1) || (y==dy && abs(x-dx)==1) )  
  142.     {  
  143.         return m_pEndPoint;  
  144.     }  
  145.     // 上  
  146.     if ( m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].type == APT_OPENED && y>0)  
  147.     {  
  148.         m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].g = 10;  
  149.         m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].h =   
  150.             10*(abs(x - dx) + abs(y-1 - dy));  
  151.         m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f =   
  152.             m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].g + m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].h;  
  153.         if ( vmin==0 )  
  154.         {  
  155.             xmin = x;  
  156.             ymin = y-1;  
  157.             vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f;  
  158.         }else{  
  159.             if ( vmin > m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f )  
  160.             {  
  161.                 xmin = x;  
  162.                 ymin = y-1;  
  163.                 vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f;  
  164.             }  
  165.         }  
  166.     }  
  167.     // 下  
  168.     if ( m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].type == APT_OPENED && y
  169.     {  
  170.         m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].g = 10;  
  171.         m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].h =   
  172.             10*(abs(x - dx) + abs(y+1 - dy));  
  173.         m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f =   
  174.             m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].g + m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].h;  
  175.         if ( vmin==0 )  
  176.         {  
  177.             xmin = x;  
  178.             ymin = y+1;  
  179.             vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f;  
  180.         }else{  
  181.             if ( vmin > m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f )  
  182.             {  
  183.                 xmin = x;  
  184.                 ymin = y+1;  
  185.                 vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f;  
  186.             }  
  187.         }  
  188.     }  
  189.     // 左  
  190.     if ( m_pAPointArr[(x-1)+m_nAPointArrWidth*y].type == APT_OPENED && x>0)  
  191.     {  
  192.         m_pAPointArr[(x-1)+m_nAPointArrWidth*y].g = 10;  
  193.         m_pAPointArr[(x-1)+m_nAPointArrWidth*y].h =   
  194.             10*(abs(x-1 - dx) + abs(y - dy));  
  195.         m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f =   
  196.             m_pAPointArr[(x-1)+m_nAPointArrWidth*y].g + m_pAPointArr[(x-1)+m_nAPointArrWidth*y].h;  
  197.         if ( vmin==0 )  
  198.         {  
  199.             xmin = x-1;  
  200.             ymin = y;  
  201.             vmin = m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f;  
  202.         }else{  
  203.             if ( vmin > m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f )  
  204.             {  
  205.                 xmin = x-1;  
  206.                 ymin = y;  
  207.                 vmin = m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f;  
  208.             }  
  209.         }  
  210.     }  
  211.     // 右  
  212.     if ( m_pAPointArr[(x+1)+m_nAPointArrWidth*y].type == APT_OPENED && x
  213.     {  
  214.         m_pAPointArr[(x+1)+m_nAPointArrWidth*y].g = 10;  
  215.         m_pAPointArr[(x+1)+m_nAPointArrWidth*y].h =   
  216.             10*(abs(x+1 - dx) + abs(y - dy));  
  217.         m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f =   
  218.             m_pAPointArr[(x+1)+m_nAPointArrWidth*y].g + m_pAPointArr[(x+1)+m_nAPointArrWidth*y].h;  
  219.         if ( vmin==0 )  
  220.         {  
  221.             xmin = x+1;  
  222.             ymin = y;  
  223.             vmin = m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f;  
  224.         }else{  
  225.             if ( vmin > m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f )  
  226.             {  
  227.                 xmin = x+1;  
  228.                 ymin = y;  
  229.                 vmin = m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f;  
  230.             }  
  231.         }  
  232.     }  
  233.   
  234.     // 如果有最优点则迭代,则否就返回NULL  
  235.     if ( vmin )  
  236.     {  
  237.         SetCurrent(xmin,ymin);  
  238.         SetClosed(xmin,ymin);  
  239.         *(m_pOldArr+xmin+m_nAPointArrWidth*ymin) = '-';  
  240.         PrintCharArr();  
  241.         PAPoint pApoint = CalcNextPoint(m_pCurPoint);  
  242.         if ( pApoint == NULL )  
  243.         {  
  244.             SetCurrent(x,y);  
  245.             SetClosed(xmin,ymin);  
  246.             *(m_pOldArr+xmin+m_nAPointArrWidth*ymin) = '0';  
  247.             return CalcNextPoint(m_pCurPoint);  
  248.         }  
  249.         return pApoint;  
  250.     }else{  
  251.         return NULL;  
  252.     }  
  253.   
  254. }  


测试文件:

 

 

[cpp] view plain copy

 

 

  1. // AStarMath.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "AStarBase.h"  
  6.   
  7. CAStarBase Astarbase;  
  8.   
  9. int _tmain(int argc, _TCHAR* argv[])  
  10. {  
  11.     char pBuff[5][7] = {  
  12.         '0','0','0','1','0','0','0',  
  13.         '0','1','1','0','0','1','1',  
  14.         '0','S','1','0','1','E','0',  
  15.         '0','1','0','0','0','1','0',  
  16.         '0','0','0','1','0','0','0'  
  17.     };  
  18.     Astarbase.Create(&pBuff[0][0],7,5);  
  19.     Astarbase.PrintCharArr();  
  20.     PAPoint pPoint = Astarbase.CalcNextPoint(NULL);  
  21.     if ( pPoint == NULL )  
  22.     {  
  23.         printf("no path can arrive!\r\n");  
  24.     }else{  
  25.         printf("success arrived!\r\n");  
  26.     }  
  27.     getchar();  
  28.     return 0;  
  29. }  

你可能感兴趣的:(Path,Planning)