aboutsummaryrefslogtreecommitdiff
path: root/src/text/draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/text/draw.c')
-rw-r--r--src/text/draw.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/text/draw.c b/src/text/draw.c
new file mode 100644
index 0000000..e6584bb
--- /dev/null
+++ b/src/text/draw.c
@@ -0,0 +1,110 @@
+#include <stdbool.h> // bool
+#include <string.h> // atoi()
+#include <stdlib.h> // EXIT_{FAILURE,SUCCESS}
+#include <stdio.h>
+#include "../libsok/sok.h"
+#include "util.h"
+#include "draw.h"
+
+static char print_buf[(SOK_LEVEL_MAX_WIDTH + 1) * SOK_LEVEL_MAX_HEIGHT + 1];
+
+static bool
+draw_on_size(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t size,
+ void * const data
+) {
+ UNUSED(ctx);
+ UNUSED(data);
+
+ // fprintf(stderr, "size: x = %u, y = %u\n", size.x, size.y);
+
+ memset(print_buf, ' ', sizeof(print_buf));
+ print_buf[(size.x + 1) * size.y + 1] = '\0';
+ for (size_t i = 0; i < size.y; i++) {
+ print_buf[(i + 1) * (size.x + 1) - 1] = '\n';
+ }
+
+ return true;
+}
+
+static bool
+draw_on_home(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ const bool has_goal,
+ void * const data
+) {
+ UNUSED(data);
+ print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = has_goal ? '+' : '@';
+ return true;
+}
+
+static bool
+draw_on_wall(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ void * const data
+) {
+ // fprintf(stderr, "wall: x = %u, y = %u\n", pos.x, pos.y);
+ UNUSED(data);
+ print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = '#';
+ return true;
+}
+
+static bool
+draw_on_goal(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ const bool has_player,
+ const bool has_box,
+ void * const data
+) {
+ UNUSED(data);
+ const char c = has_player ? '+' : (has_box ? '*' : '.');
+ print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = c;
+ return true;
+}
+
+static bool
+draw_on_box(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ const bool has_goal,
+ void * const data
+) {
+ UNUSED(data);
+ print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = has_goal ? '*' : '$';
+ return true;
+}
+
+static sok_ctx_walk_cbs_t
+DRAW_CBS = {
+ .on_size = draw_on_size,
+ .on_home = draw_on_home,
+ .on_wall = draw_on_wall,
+ .on_goal = draw_on_goal,
+ .on_box = draw_on_box,
+};
+
+void
+draw(
+ const sok_ctx_t * const ctx,
+ const size_t level_num,
+ const level_t * const level
+) {
+ // fill print buffer
+ if (!sok_ctx_walk(ctx, &DRAW_CBS, NULL)) {
+ die("Couldn't print level");
+ }
+
+ // print title, level, and console
+ printf(
+ "%s: %s (#%zu)\n" // set name, level name, and level number
+ "%s\n" // level
+ "%zu%s> ", // console
+ level->pack, level->name, level_num,
+ print_buf,
+ ctx->num_moves, sok_ctx_is_done(ctx) ? " (won!)" : ""
+ );
+}