From 13717391b4469072c0cb8041666f0d50ae9996fd Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Tue, 8 Jan 2019 21:44:04 -0500 Subject: add draw.[hc] and util.h --- meson.build | 1 + src/text/draw.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/text/draw.h | 14 +++++++ src/text/main.c | 120 ++------------------------------------------------------ src/text/util.h | 17 ++++++++ 5 files changed, 146 insertions(+), 116 deletions(-) create mode 100644 src/text/draw.c create mode 100644 src/text/draw.h create mode 100644 src/text/util.h diff --git a/meson.build b/meson.build index e98133c..74af93a 100644 --- a/meson.build +++ b/meson.build @@ -13,6 +13,7 @@ executable('sok-text', sources + [ 'src/text/main.c', 'src/text/levels.c', 'src/text/action.c', + 'src/text/draw.c', ], dependencies: []) # text interface 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 // bool +#include // atoi() +#include // EXIT_{FAILURE,SUCCESS} +#include +#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!)" : "" + ); +} diff --git a/src/text/draw.h b/src/text/draw.h new file mode 100644 index 0000000..a4a2a18 --- /dev/null +++ b/src/text/draw.h @@ -0,0 +1,14 @@ +#ifndef DRAW_H +#define DRAW_H + +#include +#include "../libsok/sok.h" +#include "levels.h" + +void draw( + const sok_ctx_t * const, + const size_t, + const level_t * const +); + +#endif /* DRAW_H */ diff --git a/src/text/main.c b/src/text/main.c index 80b6440..db4a48c 100644 --- a/src/text/main.c +++ b/src/text/main.c @@ -3,122 +3,10 @@ #include // EXIT_{FAILURE,SUCCESS} #include #include "../libsok/sok.h" +#include "util.h" #include "levels.h" #include "action.h" - -#define UNUSED(a) ((void) (a)) - -#define warn(fmt, ...) do { \ - fprintf(stderr, "W: " fmt "\n", ##__VA_ARGS__); \ -} while (0) - -#define die(fmt, ...) do { \ - fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__); \ - exit(EXIT_FAILURE); \ -} while (0) - -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, -}; - -static 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!)" : "" - ); -} +#include "draw.h" static void solve_on_error( @@ -128,7 +16,7 @@ solve_on_error( } static void -print_moves( +draw_moves( const sok_ctx_t * const ctx, const size_t skip_moves ) { @@ -211,7 +99,7 @@ int main(int argc, char *argv[]) { if (sok_solve(&ctx, solve_on_error)) { // found solution, print it - print_moves(&ctx, old_num_moves); + draw_moves(&ctx, old_num_moves); } else { warn("Couldn't solve level"); } diff --git a/src/text/util.h b/src/text/util.h new file mode 100644 index 0000000..bb91383 --- /dev/null +++ b/src/text/util.h @@ -0,0 +1,17 @@ +#ifndef UTIL_H +#define UTIL_H + +#include // fprintf() + +#define warn(fmt, ...) do { \ + fprintf(stderr, "W: " fmt "\n", ##__VA_ARGS__); \ +} while (0) + +#define die(fmt, ...) do { \ + fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__); \ + exit(EXIT_FAILURE); \ +} while (0) + +#define UNUSED(a) ((void) (a)) + +#endif /* UTIL_H */ -- cgit v1.2.3