7个寻路算法 Floyd.h

  1 #ifndef __FLOYD__H
  2 #define __FLOYD__H
  3 
  4 #include "AIDefine.h"
  5 
  6 class Floyd
  7 {
  8 private:
  9 #define MAXNUM 0x7FFFFFFF
 10 public:
 11     Floyd()
 12     {
 13         m_nodeArr = NULL;
 14         m_path = NULL;
 15         m_able = false;
 16     }
 17     ~Floyd()
 18     {
 19         if(NULL != m_nodeArr){delete[] m_nodeArr; m_nodeArr = NULL;}
 20         if(NULL != m_path){delete[] m_path; m_path = NULL;}
 21     }
 22 public:
 23     static bool find(const PointI &size, const PointI &start, const PointI &end, AI_VisitFun visitFun, Path **path = NULL,
 24         EFindType findType = EFIND_TYPE8, AI_DitanceFun fun = AI_Ditance1)
 25     {
 26         Floyd floyd;
 27         if(floyd.init(size, visitFun, findType, fun))
 28         {
 29             return floyd.findPath(start, end, path);
 30         }
 31         if(NULL != path){*path = new Path(false, 0.0f);}
 32         return false;
 33     }
 34     bool init(const PointI &size, AI_VisitFun visitFun, EFindType findType = EFIND_TYPE8, AI_DitanceFun fun = AI_Ditance1)
 35     {
 36         if(NULL != m_nodeArr){delete[] m_nodeArr; m_nodeArr = NULL;}
 37         if(NULL != m_path){delete[] m_path; m_path = NULL;}
 38         if(size.x <= 0 || size.y <= 0)
 39         {
 40             m_able = false;
 41             return false;
 42         }
 43         m_able = true;
 44         m_size.x = size.x; m_size.y = size.y;
 45         int count = size.x * size.y;
 46         m_nodeArr = new Info[count * count];
 47         m_path = new int[count * count];
 48         bool *visitArr = new bool[count];
 49 
 50         int i, j, k, index1, index2, index3;
 51         PointI pos;
 52         for(i = 0; i < size.y; ++i)
 53         {
 54             for(j = 0; j < size.x; ++j)
 55             {
 56                 index1 = i * size.x + j;
 57                 visitArr[index1] = visitFun(j, i);
 58                 if(visitArr[index1])
 59                 {
 60                     for(k = 0; k < findType; ++k)
 61                     {
 62                         pos.x = j + AI_FindHelpPoint[k].x;pos.y = i + AI_FindHelpPoint[k].y;
 63                         index2 = pos.y * size.x + pos.x;
 64                         if(AI_CheckRange(pos,size) && AI_CheckPass(j, i, pos.x, pos.y, visitFun))
 65                         {
 66                             index3 = index1 * count + index2;
 67                             m_nodeArr[index3].dis = fun(j,i,pos.x,pos.y);
 68                             m_nodeArr[index3].assign = true;
 69                             m_path[index3] = index2;
 70 
 71                             index3 = index2 * count + index1;
 72                             m_nodeArr[index3].dis = fun(j,i,pos.x,pos.y);
 73                             m_nodeArr[index3].assign = true;
 74                             m_path[index3] = index1;
 75                         }
 76                     }
 77                     index3 = index1 * count + index1;
 78                     m_nodeArr[index3].dis = 0;
 79                     m_nodeArr[index3].assign = true;
 80                     m_path[index3] = index1;
 81                 }
 82             }
 83         }
 84         for(k = 0; k < count; ++k)
 85         {
 86             if(!visitArr[k]){continue;}
 87             for(i = 0; i < count; ++i)
 88             {
 89                 if(!visitArr[i] || i == k){continue;}
 90                 for(j = 0; j < i; ++j)
 91                 {
 92                     if(!visitArr[j] || i == j || j == k){continue;}
 93 
 94                     if(m_nodeArr[i * count + k].assign && m_nodeArr[k * count + j].assign &&
 95                         m_nodeArr[i * count + j].dis > m_nodeArr[i * count + k].dis + m_nodeArr[k * count + j].dis)
 96                     {
 97                         m_nodeArr[i * count + j].dis = m_nodeArr[i * count + k].dis + m_nodeArr[k * count + j].dis;
 98                         m_nodeArr[i * count + j].assign = true;
 99                         m_path[i * count + j] = m_path[i * count + k];
100 
101 
102                         m_nodeArr[j * count + i].dis = m_nodeArr[i * count + j].dis;
103                         m_nodeArr[j * count + i].assign = true;
104                         m_path[j * count + i] = m_path[j * count + k];
105                     }
106                 }
107             }
108         }
109         delete[] visitArr;
110         return true;
111     }
112     bool findPath(const PointI &start, const PointI &end, Path **path = NULL)
113     {
114         if(!m_able)
115         {
116             if(NULL != path){*path = new Path(false, 0.0f);}
117             return false;
118         }
119         bool result = false;
120         if(start.x < 0 || start.y < 0 || start.x >= m_size.x || start.y >= m_size.y || 
121             end.x < 0 || end.y < 0 || end.x >= m_size.x || end.y >= m_size.y ||
122             (start.x == end.x && start.y == end.y))
123         {
124             if(NULL != path){*path = new Path(false, 0.0f);}
125             return false;
126         }else
127         {
128             int index1, index2, index3;
129             int count = m_size.x * m_size.y;
130             index1 = start.y * m_size.x + start.x;
131             index2 = end.y * m_size.x + end.x;
132             index3 = index1 * count + index2;
133             Path *_path = new Path(true, 0.0f);
134             if(m_nodeArr[index3].assign)
135             {
136                 result = true;
137                 _path->setDis(m_nodeArr[index3].dis);
138                 _path->push_back(PointI(start.x, start.y));
139                 int i, j;
140                 int cur = m_path[index3];
141                 while(true)
142                 {
143                     i = (int)(cur / m_size.x);
144                     j = cur % m_size.x;
145                     _path->push_back(PointI(j, i));
146                     if(i == end.y && j == end.x){break;}
147                     cur = m_path[cur * count + index2];
148                 }
149             }
150             if(!result){delete _path; _path = new Path(false, 0.0f);}
151             if(NULL != path){*path = _path;}
152         }
153         return result;
154     }
155 private:
156     struct Info
157     {
158         Info():dis(MAXNUM),assign(false){}
159         float dis;
160         bool assign;
161     };
162 private:
163     Info    *m_nodeArr;
164     int     *m_path;
165     PointI   m_size;
166     bool    m_able;
167 };
168 
169 #endif

 

posted @ 2013-11-23 01:39  liusijian  阅读(387)  评论(0编辑  收藏  举报