#include #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; }