@@ -107,13 +107,14 @@ namespace alg {
107
107
as->path = NULL ;
108
108
as->num_nodes = 0 ;
109
109
110
+ // the main A*algorithm
110
111
while (!m_openset.is_empty ()) {
111
112
uint32_t value = m_openset.min_value ();
112
113
int cx = value/ncol;
113
114
int cy = value%ncol;
114
115
115
- if (cx == (int )x2 && cy==(int )y2) { // we reached (x2,y2)
116
- // reconstruct path & return
116
+ if (cx == (int )x2 && cy==(int )y2) { // great! we've reached the target position (x2,y2)
117
+ // reconstruct path
117
118
as->num_nodes = 2 ;
118
119
uint32_t tmp = x2*ncol+y2;
119
120
while ((tmp=came_from[tmp]) != x1*ncol+y1) {
@@ -135,47 +136,55 @@ namespace alg {
135
136
return as;
136
137
}
137
138
139
+ // delete current positon from openset and move it into closed set.
138
140
m_openset.delete_min ();
139
141
m_closedset (cx, cy) = true ;
140
142
m_openset_grid (cx, cy) = false ;
141
143
142
- // for each neighbor
144
+ // for each valid neighbor of current position
143
145
int nx, ny;
144
146
for (nx=cx-1 ;nx<=cx+1 ;nx++) {
145
- if (nx<0 || nx>=(int )ncol) continue ;
146
147
for (ny=cy-1 ;ny<=cy+1 ;ny++) {
147
- if (ny<0 || ny>=(int )nrow) continue ;
148
-
149
- // except the wall;
150
- if (m_grid (nx,ny) == WALL) continue ;
148
+ // exclude invalid position
149
+ if (nx<0 || nx>=(int )ncol || ny<0 || ny>=(int )nrow) continue ;
151
150
// except the cur itself
152
151
if (nx == cx && ny==cy) continue ;
153
- // if neighbour in the closed set
152
+ // except the wall;
153
+ if (m_grid (nx,ny) == WALL) continue ;
154
+ // exclude the neighbour in the closed set
154
155
if (m_closedset (nx,ny)) continue ;
155
156
157
+ // ok, we got a valid neighbour
156
158
float tentative = g_score (cx,cy);
157
- if (nx == cx || ny == cy) {
158
- tentative += 1 + m_grid (nx,ny) ;
159
- } else {
160
- tentative += ( 1 + m_grid (nx,ny)) * SQRT2;
159
+ if (nx == cx || ny == cy) { // horizontal/vertical neighbour is near
160
+ tentative += 1 ;
161
+ } else { // diagonal neighbour is farther.
162
+ tentative += SQRT2;
161
163
}
162
164
163
165
// if neighbour not in the openset or dist < g_score[neighbour]
164
166
if (!m_openset_grid (nx,ny) || tentative < g_score (nx,ny)) {
165
- came_from[nx*ncol+ny] = cx*ncol+cy; // record path
166
- g_score (nx,ny) = tentative;
167
- f_score (nx,ny) = tentative + estimate (nx,ny,x2,y2);
168
- if (!m_openset_grid (nx,ny)) {
167
+ came_from[nx*ncol+ny] = cx*ncol+cy; // record the path
168
+ g_score (nx,ny) = tentative; // update path cost for current position
169
+ f_score (nx,ny) = tentative + estimate (nx,ny,x2,y2); // record path cost to this neighbour
170
+ if (!m_openset_grid (nx,ny)) { // only insert the neighbour if it hasn't been add to the openset.
169
171
m_openset.insert (f_score (nx,ny), nx*ncol+ny);
170
172
m_openset_grid (nx,ny) = true ;
171
173
}
172
174
}
173
175
}
174
176
}
175
177
}
178
+
179
+ // haven't reached target
176
180
return as;
177
181
}
178
182
private:
183
+ /* *
184
+ * Estimate the cost for going this way, such as:
185
+ * acrossing the swamp will be much slower than walking on the road.
186
+ * design for you game.
187
+ */
179
188
inline float estimate (int x1, int y1, int x2, int y2) const {
180
189
return sqrtf ((x2-x1) * (x2-x1) + (y2-y1)*(y2-y1));
181
190
}
0 commit comments