diff options
author | Paul Duncan <pabs@pablotron.org> | 2019-01-15 09:16:56 -0500 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2019-01-15 09:16:56 -0500 |
commit | 3e658ed87b5795b2be8f50d683dc19241aba0111 (patch) | |
tree | 0bc3b6e61e476e7ecdcb3c20429b159ea5465ae2 /src/core/sok-solve.c | |
parent | 914ca426630ccadcbb6f1ff02a599bdaf10b6cb2 (diff) | |
download | sok-3e658ed87b5795b2be8f50d683dc19241aba0111.tar.bz2 sok-3e658ed87b5795b2be8f50d683dc19241aba0111.zip |
s/libsok/core/g
Diffstat (limited to 'src/core/sok-solve.c')
-rw-r--r-- | src/core/sok-solve.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/core/sok-solve.c b/src/core/sok-solve.c new file mode 100644 index 0000000..34a8320 --- /dev/null +++ b/src/core/sok-solve.c @@ -0,0 +1,89 @@ +#include <stdbool.h> +#include "sok.h" + +#define UNUSED(a) ((void) (a)) + +static bool +sok_solve_step( + sok_ctx_t * const ctx, + sok_cache_t * const cache, + void (*on_error)(const char * const) +) { + // check for success + if (sok_ctx_is_done(ctx)) { + // return success + return true; + } + + if (sok_cache_has(cache, ctx)) { + // return failure + return false; + } + + // add to cache + if (!sok_cache_add(cache, ctx)) { + if (on_error) { + // log error + on_error("sok_cache_add() failed"); + } + + // return failure + return false; + } + +/* + * // make sure level is solvable + * if (sok_ctx_is_lost(ctx)) { + * // return failure + * return false; + * } + */ + + for (size_t dir = 0; dir < SOK_DIR_LAST; dir++) { + if (!sok_ctx_move(ctx, dir)) { + continue; + } + + // recurse, check for success + if (sok_solve_step(ctx, cache, on_error)) { + // return success + return true; + } + + // undo move + if (!sok_ctx_undo(ctx)) { + if (on_error) { + // log error + on_error("sok_ctx_undo() failed"); + } + + // return failure + return false; + } + } + + // return failure + return false; +} + +bool +sok_solve( + sok_ctx_t * const ctx, + void (*on_error)(const char * const) +) { + // init cache + sok_cache_t cache; + if (!sok_cache_init(&cache, SOK_CACHE_DEFAULT_CAPACITY)) { + on_error("sok_cache_init() failed"); + return false; + } + + // solve + const bool r = sok_solve_step(ctx, &cache, on_error); + + // finalize cache + sok_cache_fini(&cache); + + // return result + return r; +} |