Rewrite solve procedure to be iterative instead of recursive

This commit is contained in:
Camden Dixie O'Brien 2024-11-04 22:30:33 +00:00
parent 0720b2c0c2
commit 048bfd2169

64
main.c
View File

@ -127,41 +127,42 @@ static void generate(vec2_t p)
} while (sp != stack); } while (sp != stack);
} }
static bool solve(vec2_t start, vec2_t *path, vec2_t **end) static void solve(vec2_t p, vec2_t *sp, vec2_t **end)
{ {
*path++ = start; *sp++ = p;
while (1) {
if (GOAL == p.x && GOAL == p.y) {
*sp++ = p;
*end = sp;
return;
}
for (int i = 0; i < 4; ++i) { vec2_t n, im;
const vec2_t next = { bool got_n = false;
.x = start.x + steps[i].x, for (int i = 0; i < 4; ++i) {
.y = start.y + steps[i].y, n.x = p.x + steps[i].x;
}; n.y = p.y + steps[i].y;
const vec2_t im = { if (!in_bounds(n))
.x = (start.x + next.x) / 2, continue;
.y = (start.y + next.y) / 2,
};
const bool x_in_bounds = next.x >= 0 && next.x < GRID_SIZE;
const bool y_in_bounds = next.y >= 0 && next.y < GRID_SIZE;
if (x_in_bounds && y_in_bounds) { im.x = (p.x + n.x) / 2;
const bool accessible = maze[im.x][im.y].is_path; im.y = (p.y + n.y) / 2;
const bool unvisited = !maze[next.x][next.y].visited; if (maze[im.x][im.y].is_path && !maze[n.x][n.y].visited) {
if (accessible && unvisited) { got_n = true;
maze[next.x][next.y].visited = true; break;
maze[im.x][im.y].visited = true;
if (GOAL == next.x && GOAL == next.y) {
*path++ = next;
*end = path;
return true;
}
if (solve(next, path, end))
return true;
} }
} }
}
--path; if (!got_n) {
return false; p = *(--sp);
continue;
}
maze[im.x][im.y].visited = maze[n.x][n.y].visited = true;
*sp++ = p;
p = n;
}
} }
int main(void) int main(void)
@ -221,11 +222,12 @@ int main(void)
const vec2_t solve_start = { 0, 0 }; const vec2_t solve_start = { 0, 0 };
vec2_t path[MAX_PATH_LENGTH], *path_end; vec2_t path[MAX_PATH_LENGTH], *path_end;
maze[0][0].visited = true; maze[0][0].visited = true;
XSetForeground(dpy, ctx, visited_col);
draw_visited(solve_start);
solve(solve_start, path, &path_end); solve(solve_start, path, &path_end);
sleep(1);
// Draw solution path // Draw solution path
XSetForeground(dpy, ctx, visited_col);
const vec2_t *prev = &solve_start; const vec2_t *prev = &solve_start;
for (const vec2_t *p = path; p < path_end; ++p) { for (const vec2_t *p = path; p < path_end; ++p) {
const vec2_t im = { const vec2_t im = {