summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-08-08 16:59:35 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-08-08 17:00:19 (EDT)
commit1af3d32d9c0e44c770de442be8dad7be05ae02d4 (patch)
treefb3dc4408559bc96086b7a685df624053e7ccadc
parentc234b317843200c5059c57c16621fb722f579fb0 (diff)
downloadmazefight-1af3d32d9c0e44c770de442be8dad7be05ae02d4.zip
mazefight-1af3d32d9c0e44c770de442be8dad7be05ae02d4.tar.gz
mazefight-1af3d32d9c0e44c770de442be8dad7be05ae02d4.tar.bz2
maze: Optionally hide unseen walls
-rw-r--r--src/game.c2
-rw-r--r--src/maze.c69
-rw-r--r--src/maze.h8
-rw-r--r--src/menu.c3
4 files changed, 74 insertions, 8 deletions
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;
}