aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2019-01-15 21:10:27 -0500
committerPaul Duncan <pabs@pablotron.org>2019-01-15 21:10:27 -0500
commit19a5965400f9a252adf540050046d2dc3a026d13 (patch)
tree0fb29c1a0f61a38eae8f2aded462bf12e5a3d60e
parentedbbfd40714ba9adfd770b9ccb6a0eecdc43a736 (diff)
downloadsok-19a5965400f9a252adf540050046d2dc3a026d13.tar.bz2
sok-19a5965400f9a252adf540050046d2dc3a026d13.zip
add sok_solve_cbs_t and refactor code to use it
-rw-r--r--src/core/sok-solve.c30
-rw-r--r--src/core/sok.h8
-rw-r--r--src/sdl/main.c11
-rw-r--r--src/solve/main.c11
-rw-r--r--src/text/main.c11
5 files changed, 54 insertions, 17 deletions
diff --git a/src/core/sok-solve.c b/src/core/sok-solve.c
index 34a8320..45d227c 100644
--- a/src/core/sok-solve.c
+++ b/src/core/sok-solve.c
@@ -7,7 +7,8 @@ static bool
sok_solve_step(
sok_ctx_t * const ctx,
sok_cache_t * const cache,
- void (*on_error)(const char * const)
+ const sok_solve_cbs_t * const cbs,
+ void * const user_data
) {
// check for success
if (sok_ctx_is_done(ctx)) {
@@ -22,15 +23,19 @@ sok_solve_step(
// add to cache
if (!sok_cache_add(cache, ctx)) {
- if (on_error) {
+ if (cbs && cbs->on_error) {
// log error
- on_error("sok_cache_add() failed");
+ cbs->on_error("sok_cache_add() failed", user_data);
}
// return failure
return false;
}
+ if (cbs && cbs->on_step && !cbs->on_step(ctx, user_data)) {
+ // return failure
+ return false;
+ }
/*
* // make sure level is solvable
* if (sok_ctx_is_lost(ctx)) {
@@ -45,16 +50,16 @@ sok_solve_step(
}
// recurse, check for success
- if (sok_solve_step(ctx, cache, on_error)) {
+ if (sok_solve_step(ctx, cache, cbs, user_data)) {
// return success
return true;
}
// undo move
if (!sok_ctx_undo(ctx)) {
- if (on_error) {
+ if (cbs && cbs->on_error) {
// log error
- on_error("sok_ctx_undo() failed");
+ cbs->on_error("sok_ctx_undo() failed", user_data);
}
// return failure
@@ -66,20 +71,25 @@ sok_solve_step(
return false;
}
-bool
+bool
sok_solve(
sok_ctx_t * const ctx,
- void (*on_error)(const char * const)
+ const sok_solve_cbs_t * const cbs,
+ void *user_data
) {
// init cache
sok_cache_t cache;
if (!sok_cache_init(&cache, SOK_CACHE_DEFAULT_CAPACITY)) {
- on_error("sok_cache_init() failed");
+ if (cbs && cbs->on_error) {
+ cbs->on_error("sok_cache_init() failed", user_data);
+ }
+
+ // return failure
return false;
}
// solve
- const bool r = sok_solve_step(ctx, &cache, on_error);
+ const bool r = sok_solve_step(ctx, &cache, cbs, user_data);
// finalize cache
sok_cache_fini(&cache);
diff --git a/src/core/sok.h b/src/core/sok.h
index 1503b5f..92fb4e7 100644
--- a/src/core/sok.h
+++ b/src/core/sok.h
@@ -245,9 +245,15 @@ _Bool sok_cache_add(sok_cache_t * const, const sok_ctx_t * const);
/* solve */
/*********/
+typedef struct {
+ _Bool (*on_step)(const sok_ctx_t *, void *);
+ void (*on_error)(const char * const, void *);
+} sok_solve_cbs_t;
+
_Bool sok_solve(
sok_ctx_t * const,
- void (*on_error)(const char * const)
+ const sok_solve_cbs_t * const,
+ void * const
);
#ifdef __cplusplus
diff --git a/src/sdl/main.c b/src/sdl/main.c
index 46f30c3..c3a9abe 100644
--- a/src/sdl/main.c
+++ b/src/sdl/main.c
@@ -60,11 +60,18 @@ load_font(
static void
solve_on_error(
- const char * const err
+ const char * const err,
+ void *user_data
) {
+ UNUSED(user_data);
die("Error solving level: %s", err);
}
+static const sok_solve_cbs_t
+SOLVE_CBS = {
+ .on_error = solve_on_error,
+};
+
static void
set_level(
draw_ctx_t * const draw_ctx,
@@ -233,7 +240,7 @@ int main(int argc, char *argv[]) {
// get current number of moves
const size_t old_num_moves = ctx.num_moves;
- if (sok_solve(&ctx, solve_on_error)) {
+ if (sok_solve(&ctx, &SOLVE_CBS, NULL)) {
// found solution, print it
log_moves(&ctx, old_num_moves);
} else {
diff --git a/src/solve/main.c b/src/solve/main.c
index 140cfc5..b8b966f 100644
--- a/src/solve/main.c
+++ b/src/solve/main.c
@@ -7,11 +7,18 @@
static void
solve_on_error(
- const char * const err
+ const char * const err,
+ void *user_data
) {
+ UNUSED(user_data);
die("Error solving level: %s", err);
}
+static const sok_solve_cbs_t
+SOLVE_CBS = {
+ .on_error = solve_on_error,
+};
+
int main(int argc, char *argv[]) {
// init context
sok_ctx_t ctx;
@@ -30,7 +37,7 @@ int main(int argc, char *argv[]) {
}
// solve level
- if (!sok_solve(&ctx, solve_on_error)) {
+ if (!sok_solve(&ctx, &SOLVE_CBS, NULL)) {
die("Couldn't solve level: %d", (int) level_num);
}
}
diff --git a/src/text/main.c b/src/text/main.c
index 204da0f..6b7513c 100644
--- a/src/text/main.c
+++ b/src/text/main.c
@@ -10,11 +10,18 @@
static void
solve_on_error(
- const char * const err
+ const char * const err,
+ void *data
) {
+ UNUSED(data);
die("Error solving level: %s", err);
}
+static const sok_solve_cbs_t
+SOLVE_CBS = {
+ .on_error = solve_on_error,
+};
+
static void
draw_moves(
const sok_ctx_t * const ctx,
@@ -104,7 +111,7 @@ int main(int argc, char *argv[]) {
// get current number of moves
const size_t old_num_moves = ctx.num_moves;
- if (sok_solve(&ctx, solve_on_error)) {
+ if (sok_solve(&ctx, &SOLVE_CBS, NULL)) {
// found solution, print it
draw_moves(&ctx, old_num_moves);
} else {