From 1af3d32d9c0e44c770de442be8dad7be05ae02d4 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sun, 08 Aug 2021 16:59:35 -0400 Subject: maze: Optionally hide unseen walls --- (limited to 'src') diff --git a/src/game.c b/src/game.c index 433227f..8c3a8ff 100644 --- a/src/game.c +++ b/src/game.c @@ -149,7 +149,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) SDL_Event event; /* Create maze */ - maze = mf_maze_new(seed, size, size); + maze = mf_maze_new(seed, size, size, reveal); if (maze == NULL) { goto err; } diff --git a/src/maze.c b/src/maze.c index 028e940..d991328 100644 --- a/src/maze.c +++ b/src/maze.c @@ -24,7 +24,9 @@ struct mf_maze { int w; int h; + int show_all; unsigned int *walls; + unsigned int *show; unsigned int *visited; }; @@ -69,6 +71,47 @@ mf_maze_is_wall(struct mf_maze *m, int x, int y, int dx, int dy) & 1 << (i % (sizeof(*m->walls)*8))); } +void +mf_maze_reveal_wall(struct mf_maze *m, int x, int y, int dx, int dy) +{ + int i; + + if (x + dx < 0 || x + dx >= m->w || y + dy < 0 || y + dy >= m->h) { + return; + } + + if (dx < 0) --x; + if (dy < 0) --y; + i = y * m->w + x; + i *= 2; + if (dx == 0) ++i; /* Moving vertically */ + + m->show[i / (sizeof(*m->show)*8)] |= 1 << (i % (sizeof(*m->show)*8)); +} + +static int +_mf_maze_revealed_wall(struct mf_maze *m, int x, int y, int dx, int dy) +{ + int i; + + if (m->show_all) { + return 1; + } + + if (x + dx < 0 || x + dx >= m->w || y + dy < 0 || y + dy >= m->h) { + return 1; + } + + if (dx < 0) --x; + if (dy < 0) --y; + i = y * m->w + x; + i *= 2; + if (dx == 0) ++i; /* Moving vertically */ + + return m->show[i / (sizeof(*m->show)*8)] + & 1 << (i % (sizeof(*m->show)*8)); +} + static void _mf_maze_visit(struct mf_maze *m, int x, int y) { @@ -128,7 +171,7 @@ _mf_maze_carve(struct mf_maze *m, int x, int y) } struct mf_maze * -mf_maze_new(int s, int w, int h) +mf_maze_new(int s, int w, int h, int show_all) { struct mf_maze *m; int x; @@ -147,19 +190,30 @@ mf_maze_new(int s, int w, int h) free(m); return NULL; } + m->show = calloc( + (w * h * 2 + sizeof(*m->show)*8 - 1) / + (sizeof(*m->show)*8), + sizeof(*m->show)); + if (m->show == NULL) { + free(m->walls); + free(m); + return NULL; + } m->visited = calloc( ((w+2) * (h+2) + sizeof(*m->visited)*8 - 1) / (sizeof(*m->visited)*8), sizeof(*m->visited)); if (m->visited == NULL) { + free(m->show); free(m->walls); free(m); return NULL; } /* Initialize parameters */ - m->w = w; - m->h = h; + m->w = w; + m->h = h; + m->show_all = show_all; /* Mark edges as visited */ for (x = -1; x <= w; ++x) { @@ -198,7 +252,8 @@ mf_maze_render(struct mf_maze *m, SDL_Renderer *renderer, SDL_Color *color, } for (y = 0; y < m->h; ++y) { for (x = 0; x < m->w; ++x) { - if (y < m->h - 1 && mf_maze_is_wall(m, x, y, 0, 1)) { + if (y < m->h - 1 && mf_maze_is_wall(m, x, y, 0, 1) && + _mf_maze_revealed_wall(m, x, y, 0, 1)) { /* Draw h line */ if (SDL_RenderDrawLine(renderer, (x ) * cw, (y+1) * cw, @@ -211,7 +266,8 @@ mf_maze_render(struct mf_maze *m, SDL_Renderer *renderer, SDL_Color *color, e = -1; } } - if (x < m->w - 1 && mf_maze_is_wall(m, x, y, 1, 0)) { + if (x < m->w - 1 && mf_maze_is_wall(m, x, y, 1, 0) && + _mf_maze_revealed_wall(m, x, y, 1, 0)) { /* Draw v line */ if (SDL_RenderDrawLine(renderer, (x+1) * cw, (y ) * cw, @@ -243,6 +299,9 @@ mf_maze_destroy(struct mf_maze **m_p) if (m->walls != NULL) { free(m->walls); } + if (m->show != NULL) { + free(m->show); + } free(m); m = NULL; } diff --git a/src/maze.h b/src/maze.h index 895e94e..4482f67 100644 --- a/src/maze.h +++ b/src/maze.h @@ -31,8 +31,14 @@ int mf_maze_is_wall(struct mf_maze *m, int x, int y, int dx, int dy) __attribute__((__pure__)); +int +mf_maze_is_wall(struct mf_maze *m, int x, int y, int dx, int dy); + +void +mf_maze_reveal_wall(struct mf_maze *m, int x, int y, int dx, int dy); + struct mf_maze * -mf_maze_new(int s, int w, int h); +mf_maze_new(int s, int w, int h, int show_all); int mf_maze_render(struct mf_maze *m, SDL_Renderer *renderer, SDL_Color *color, diff --git a/src/menu.c b/src/menu.c index 5a9de35..1825886 100644 --- a/src/menu.c +++ b/src/menu.c @@ -204,7 +204,8 @@ mf_menu(SDL_Renderer *renderer) /* Create maze */ maze = mf_maze_new(time(NULL), MF_WINDOW_W / MF_MENU_MAZE_CELL_W, - MF_WINDOW_H / MF_MENU_MAZE_CELL_W); + MF_WINDOW_H / MF_MENU_MAZE_CELL_W, + SDL_TRUE); if (maze == NULL) { goto err; } -- cgit v0.9.1