aboutsummaryrefslogtreecommitdiff
path: root/src/text/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/text/main.c')
-rw-r--r--src/text/main.c166
1 files changed, 66 insertions, 100 deletions
diff --git a/src/text/main.c b/src/text/main.c
index eb8d9b2..80b6440 100644
--- a/src/text/main.c
+++ b/src/text/main.c
@@ -4,25 +4,23 @@
#include <stdio.h>
#include "../libsok/sok.h"
#include "levels.h"
+#include "action.h"
#define UNUSED(a) ((void) (a))
-#define CASE_DIGIT \
- case '0': \
- case '1': \
- case '2': \
- case '3': \
- case '4': \
- case '5': \
- case '6': \
- case '7': \
- case '8': \
- case '9':
+#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
-print_on_size(
+draw_on_size(
const sok_ctx_t * const ctx,
const sok_pos_t size,
void * const data
@@ -42,7 +40,7 @@ print_on_size(
}
static bool
-print_on_home(
+draw_on_home(
const sok_ctx_t * const ctx,
const sok_pos_t pos,
const bool has_goal,
@@ -54,7 +52,7 @@ print_on_home(
}
static bool
-print_on_wall(
+draw_on_wall(
const sok_ctx_t * const ctx,
const sok_pos_t pos,
void * const data
@@ -66,7 +64,7 @@ print_on_wall(
}
static bool
-print_on_goal(
+draw_on_goal(
const sok_ctx_t * const ctx,
const sok_pos_t pos,
const bool has_player,
@@ -80,7 +78,7 @@ print_on_goal(
}
static bool
-print_on_box(
+draw_on_box(
const sok_ctx_t * const ctx,
const sok_pos_t pos,
const bool has_goal,
@@ -92,34 +90,41 @@ print_on_box(
}
static sok_ctx_walk_cbs_t
-PRINT_CBS = {
- .on_size = print_on_size,
- .on_home = print_on_home,
- .on_wall = print_on_wall,
- .on_goal = print_on_goal,
- .on_box = print_on_box,
+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
-print_level(
- const sok_ctx_t * const ctx
+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, &PRINT_CBS, NULL)) {
- fprintf(stderr, "Couldn't print level\n");
- exit(EXIT_FAILURE);
+ if (!sok_ctx_walk(ctx, &DRAW_CBS, NULL)) {
+ die("Couldn't print level");
}
- // print level
- printf("%s\n", print_buf);
+ // 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!)" : ""
+ );
}
static void
solve_on_error(
const char * const err
) {
- fprintf(stderr, "Error solving level: %s\n", err);
- exit(EXIT_FAILURE);
+ die("Error solving level: %s", err);
}
static void
@@ -127,25 +132,13 @@ print_moves(
const sok_ctx_t * const ctx,
const size_t skip_moves
) {
- printf("Moves (%zu): ", ctx->num_moves - skip_moves);
+ printf("Solution (%zu moves): ", ctx->num_moves - skip_moves);
for (size_t i = skip_moves; i < ctx->num_moves; i++) {
- switch (ctx->moves[i].dir) {
- case SOK_DIR_UP:
- fputs("u", stdout);
- break;
- case SOK_DIR_DOWN:
- fputs("d", stdout);
- break;
- case SOK_DIR_LEFT:
- fputs("l", stdout);
- break;
- case SOK_DIR_RIGHT:
- fputs("r", stdout);
- break;
- default:
- fprintf(stderr, "Error: invalid move: %u", ctx->moves[i].dir);
- exit(EXIT_FAILURE);
+ if (ctx->moves[i].dir >= SOK_DIR_LAST) {
+ die("invalid move: %u", ctx->moves[i].dir);
}
+
+ fputs(SOK_DIR_TO_STR(ctx->moves[i].dir), stdout);
}
printf("\n");
}
@@ -159,58 +152,34 @@ int main(int argc, char *argv[]) {
sok_ctx_init(&ctx, NULL);
if (!sok_ctx_set_level(&ctx, level->data)) {
- fprintf(stderr, "Couldn't load level %zu\n", level_num);
- return EXIT_FAILURE;
+ die("Couldn't load level %zu", level_num);
}
- char buf[1024];
bool done = false;
while (!done) {
- printf("%s: %s (#%zu)\n", level->pack, level->name, level_num);
- print_level(&ctx);
- printf("%zu%s> ", ctx.num_moves, sok_ctx_is_done(&ctx) ? " (won!)" : "");
+ // draw screen
+ draw(&ctx, level_num, level);
- if (!fgets(buf, sizeof(buf), stdin)) {
- done = true;
- break;
- }
+ // read input, check for error
+ const action_t action = get_action();
- switch (buf[0]) {
- case EOF:
- case 'q':
+ switch (action.type) {
+ case ACTION_QUIT:
done = true;
break;
- case 'k':
- if (!sok_ctx_move(&ctx, SOK_DIR_UP)) {
- fprintf(stderr, "W: move up failed\n");
- }
-
- break;
- case 'h':
- if (!sok_ctx_move(&ctx, SOK_DIR_LEFT)) {
- fprintf(stderr, "W: move left failed\n");
- }
-
- break;
- case 'j':
- if (!sok_ctx_move(&ctx, SOK_DIR_DOWN)) {
- fprintf(stderr, "W: move down failed\n");
- }
-
- break;
- case 'l':
- if (!sok_ctx_move(&ctx, SOK_DIR_RIGHT)) {
- fprintf(stderr, "W: move right failed\n");
+ case ACTION_MOVE:
+ if (!sok_ctx_move(&ctx, (sok_dir_t) action.data)) {
+ warn("move %s failed", SOK_DIR_TO_STR((sok_dir_t) action.data));
}
break;
- case 'u':
+ case ACTION_UNDO:
if (!sok_ctx_undo(&ctx)) {
- fprintf(stderr, "W: undo failed\n");
+ warn("undo failed");
}
break;
- case 'n':
+ case ACTION_NEXT:
if (sok_ctx_is_done(&ctx)) {
// advance level
level_num++;
@@ -218,28 +187,24 @@ int main(int argc, char *argv[]) {
// load next level
if (!sok_ctx_set_level(&ctx, level->data)) {
- fprintf(stderr, "Couldn't load level %zu\n", level_num);
- return EXIT_FAILURE;
+ die("Couldn't load level %zu", level_num);
}
} else {
- fprintf(stderr, "W: cannot advance to next level\n");
+ warn("cannot advance to next level");
}
break;
- CASE_DIGIT
- {
- level_num = atoi(buf) % levels_get_num_levels();
- level = levels_get_level(level_num);
+ case ACTION_WARP:
+ level_num = action.data;
+ level = levels_get_level(level_num);
- // load level
- if (!sok_ctx_set_level(&ctx, level->data)) {
- fprintf(stderr, "Couldn't load level %zu\n", level_num);
- return EXIT_FAILURE;
- }
+ // load level
+ if (!sok_ctx_set_level(&ctx, level->data)) {
+ die("Couldn't load level %zu", level_num);
}
break;
- case 's':
+ case ACTION_SOLVE:
{
// get current number of moves
const size_t old_num_moves = ctx.num_moves;
@@ -248,7 +213,7 @@ int main(int argc, char *argv[]) {
// found solution, print it
print_moves(&ctx, old_num_moves);
} else {
- fprintf(stderr, "W: Couldn't solve level\n");
+ warn("Couldn't solve level");
}
}
@@ -259,5 +224,6 @@ int main(int argc, char *argv[]) {
}
}
- return 0;
+ // return success
+ return EXIT_SUCCESS;
}