Generalise solve procedure to random walk

This commit is contained in:
Camden Dixie O'Brien 2024-11-03 23:08:59 +00:00
parent a741490c4c
commit ce8195f3e8

55
main.c
View File

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