diff --git a/main.c b/main.c index 1ef9eeb..cfba17c 100644 --- a/main.c +++ b/main.c @@ -38,7 +38,7 @@ typedef struct { bool visited : 1; } cell_t; -static const struct timespec pause = { .tv_nsec = 5000000 }; +static const struct timespec wait = { .tv_nsec = 5000000 }; static const vec2_t steps[] = { [LEFT] = { .x = -2, .y = 0 }, @@ -53,57 +53,28 @@ static GC ctx; static cell_t maze[GRID_SIZE][GRID_SIZE]; static int bg_col, wall_col, visited_col; -static void draw_walls(void) +static void clear_path(vec2_t p) { - XSetForeground(dpy, ctx, wall_col); - - XFillRectangle( - dpy, window, ctx, PX(MARGIN), PX(MARGIN), PX(GRID_SIZE + 2), - PX(WALL_THICKNESS)); - XFillRectangle( - dpy, window, ctx, PX(MARGIN), - PX(MARGIN + WALL_THICKNESS + GRID_SIZE), PX(GRID_SIZE + 2), - PX(WALL_THICKNESS)); - XFillRectangle( - dpy, window, ctx, PX(MARGIN), PX(MARGIN + WALL_THICKNESS), - PX(WALL_THICKNESS), PX(GRID_SIZE)); - XFillRectangle( - dpy, window, ctx, PX(MARGIN + WALL_THICKNESS + GRID_SIZE), - PX(MARGIN + WALL_THICKNESS), PX(WALL_THICKNESS), PX(GRID_SIZE - 1)); - + const int margin_px = PX(MARGIN + WALL_THICKNESS); + const int left = margin_px + PX(p.x); + const int top = margin_px + PX(p.y); + XFillRectangle(dpy, window, ctx, left, top, PX(1), PX(1)); + XClearArea(dpy, window, left, top, PX(1), PX(1), false); XFlush(dpy); } -static void draw_maze(void) +static void draw_visited(vec2_t p) { const int margin_px = PX(MARGIN + WALL_THICKNESS); - XClearArea( - dpy, window, margin_px, margin_px, PX(GRID_SIZE), PX(GRID_SIZE), - false); - - for (int x = 0; x < GRID_SIZE; ++x) { - for (int y = 0; y < GRID_SIZE; ++y) { - if (!maze[x][y].is_path) - XSetForeground(dpy, ctx, wall_col); - else if (maze[x][y].visited) - XSetForeground(dpy, ctx, visited_col); - else - continue; - const int left = margin_px + PX(x); - const int top = margin_px + PX(y); - XFillRectangle(dpy, window, ctx, left, top, PX(1), PX(1)); - } - } - + const int left = margin_px + PX(p.x); + const int top = margin_px + PX(p.y); + XFillRectangle(dpy, window, ctx, left, top, PX(1), PX(1)); XFlush(dpy); } static bool random_walk(coord_pred_t should_visit, visit_fn_t visit_fn, vec2_t start) { - draw_maze(); - nanosleep(&pause, NULL); - dir_t visit[] = { LEFT, RIGHT, UP, DOWN }; for (int i = 3; i > 0; --i) { const int r = rand() % (i + 1); @@ -141,6 +112,9 @@ static bool generation_visit(vec2_t c, vec2_t im) { maze[c.x][c.y].is_path = true; maze[im.x][im.y].is_path = true; + clear_path(im); + clear_path(c); + nanosleep(&wait, NULL); return false; } @@ -153,6 +127,9 @@ static bool solve_visit(vec2_t c, vec2_t im) { maze[c.x][c.y].visited = true; maze[im.x][im.y].visited = true; + draw_visited(im); + draw_visited(c); + nanosleep(&wait, NULL); return GOAL == c.x && GOAL == c.y; } @@ -191,23 +168,32 @@ int main(void) XNextEvent(dpy, &evt); while (MapNotify != evt.type); - draw_walls(); + // Draw black box for walls + XClearWindow(dpy, window); + XSetForeground(dpy, ctx, wall_col); + XFillRectangle( + dpy, window, ctx, PX(MARGIN), PX(MARGIN), PX(GRID_SIZE + 2), + PX(GRID_SIZE + 2)); + const vec2_t exit = { GOAL + 1, GOAL }; + clear_path(exit); + XFlush(dpy); // Generate memset(&maze, 0, sizeof(maze)); const vec2_t gen_start = { GOAL, GOAL }; maze[GOAL][GOAL].is_path = true; + clear_path(gen_start); random_walk(is_wall, generation_visit, gen_start); // Solve const vec2_t solve_start = { 0, 0 }; maze[0][0].visited = true; + XSetForeground(dpy, ctx, visited_col); + draw_visited(solve_start); random_walk(accessible_and_unvisited, solve_visit, solve_start); // Draw exit path - draw_maze(); const int x = PX(MARGIN + GRID_SIZE + 1), y = PX(MARGIN + GRID_SIZE); - XSetForeground(dpy, ctx, visited_col); XFillRectangle(dpy, window, ctx, x, y, PX(1), PX(1)); XFlush(dpy);