Skip to content

Commit 91282a9

Browse files
committed
optimize astar alg, added verbose comments
1 parent a3fb48c commit 91282a9

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

include/astar.h

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,14 @@ namespace alg {
107107
as->path = NULL;
108108
as->num_nodes = 0;
109109

110+
// the main A*algorithm
110111
while(!m_openset.is_empty()) {
111112
uint32_t value = m_openset.min_value();
112113
int cx = value/ncol;
113114
int cy = value%ncol;
114115

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
117118
as->num_nodes = 2;
118119
uint32_t tmp = x2*ncol+y2;
119120
while((tmp=came_from[tmp]) != x1*ncol+y1) {
@@ -135,47 +136,55 @@ namespace alg {
135136
return as;
136137
}
137138

139+
// delete current positon from openset and move it into closed set.
138140
m_openset.delete_min();
139141
m_closedset(cx, cy) = true;
140142
m_openset_grid(cx, cy) = false;
141143

142-
// for each neighbor
144+
// for each valid neighbor of current position
143145
int nx, ny;
144146
for(nx=cx-1;nx<=cx+1;nx++) {
145-
if (nx<0 || nx>=(int)ncol) continue;
146147
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;
151150
// except the cur itself
152151
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
154155
if(m_closedset(nx,ny)) continue;
155156

157+
// ok, we got a valid neighbour
156158
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;
161163
}
162164

163165
// if neighbour not in the openset or dist < g_score[neighbour]
164166
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.
169171
m_openset.insert(f_score(nx,ny), nx*ncol+ny);
170172
m_openset_grid(nx,ny) = true;
171173
}
172174
}
173175
}
174176
}
175177
}
178+
179+
// haven't reached target
176180
return as;
177181
}
178182
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+
*/
179188
inline float estimate(int x1, int y1, int x2, int y2) const {
180189
return sqrtf((x2-x1) * (x2-x1) + (y2-y1)*(y2-y1));
181190
}

0 commit comments

Comments
 (0)