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