diff --git a/main.c b/main.c index 5205ea7..4c0602b 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,9 @@ typedef struct { int x, y; } vec2_t; +typedef bool (*coord_pred_t)(vec2_t c, vec2_t im); +typedef bool (*visit_fn_t)(vec2_t c, vec2_t im); + static const struct timespec pause = { .tv_nsec = 5000000 }; static const vec2_t steps[] = { @@ -83,10 +86,9 @@ static void draw_maze(void) XFlush(dpy); } -static void generate_maze(vec2_t p, vec2_t g) +static bool +random_walk(coord_pred_t should_visit, visit_fn_t visit_fn, vec2_t start) { - maze[p.x][p.y] = true; - draw_maze(); nanosleep(&pause, NULL); @@ -98,21 +100,36 @@ static void generate_maze(vec2_t p, vec2_t g) visit[i] = tmp; } - vec2_t n; + vec2_t next, im; for (int i = 0; i < 4; ++i) { - n.x = p.x + steps[visit[i]].x; - n.y = p.y + steps[visit[i]].y; + next.x = start.x + steps[visit[i]].x; + next.y = start.y + steps[visit[i]].y; + im.x = (start.x + next.x) / 2; + im.y = (start.y + next.y) / 2; - const bool x_in_bounds = n.x >= 0 && n.x < GRID_SIZE; - const bool y_in_bounds = n.y >= 0 && n.y < GRID_SIZE; - if (x_in_bounds && y_in_bounds && !maze[n.x][n.y]) { - const int xi = (p.x + n.x) / 2; - const int yi = (p.y + n.y) / 2; - maze[xi][yi] = true; - - generate_maze(n, g); + 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 && should_visit(next, im)) { + if (visit_fn(next, im) + || random_walk(should_visit, visit_fn, next)) + return true; } } + + return false; +} + +static bool is_wall(vec2_t c, vec2_t im) +{ + (void)im; + return !maze[c.x][c.y]; +} + +static bool generation_visit(vec2_t c, vec2_t im) +{ + maze[c.x][c.y] = true; + maze[im.x][im.y] = true; + return false; } int main(void) @@ -144,11 +161,13 @@ int main(void) XNextEvent(dpy, &evt); while (MapNotify != evt.type); - // Generate and draw maze - memset(&maze, 0, sizeof(maze)); draw_walls(); - const vec2_t start = { GOAL, GOAL }, end = { 0, 0 }; - generate_maze(start, end); + + // Generate + memset(&maze, 0, sizeof(maze)); + const vec2_t gen_start = { GOAL, GOAL }; + maze[GOAL][GOAL] = true; + random_walk(is_wall, generation_visit, gen_start); // Wait for window exit bool is_del = false;