diff --git a/keen.c b/keen.c index baa1d81..4c6e330 100644 --- a/keen.c +++ b/keen.c @@ -591,6 +591,11 @@ static int solver_hard(struct latin_solver *solver, void *vctx) #define SOLVER(upper,title,func,lower) func, static usersolver_t const keen_solvers[] = { DIFFLIST(SOLVER) }; +static bool keen_valid(struct latin_solver *solver, void *ctx) +{ + return true; /* FIXME */ +} + static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff) { int a = w*w; @@ -638,7 +643,7 @@ static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff) ret = latin_solver(soln, w, maxdiff, DIFF_EASY, DIFF_HARD, DIFF_EXTREME, DIFF_EXTREME, DIFF_UNREASONABLE, - keen_solvers, &ctx, NULL, NULL); + keen_solvers, keen_valid, &ctx, NULL, NULL); sfree(ctx.dscratch); sfree(ctx.iscratch); diff --git a/latin.c b/latin.c index 9d06ccd..3993016 100644 --- a/latin.c +++ b/latin.c @@ -19,8 +19,8 @@ static int latin_solver_top(struct latin_solver *solver, int maxdiff, int diff_simple, int diff_set_0, int diff_set_1, int diff_forcing, int diff_recursive, - usersolver_t const *usersolvers, void *ctx, - ctxnew_t ctxnew, ctxfree_t ctxfree); + usersolver_t const *usersolvers, validator_t valid, + void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree); #ifdef STANDALONE_SOLVER int solver_show_working, solver_recurse_depth; @@ -711,7 +711,7 @@ int latin_solver_diff_set(struct latin_solver *solver, static int latin_solver_recurse (struct latin_solver *solver, int diff_simple, int diff_set_0, int diff_set_1, int diff_forcing, int diff_recursive, - usersolver_t const *usersolvers, void *ctx, + usersolver_t const *usersolvers, validator_t valid, void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree) { int best, bestcount; @@ -817,7 +817,8 @@ static int latin_solver_recurse ret = latin_solver_top(&subsolver, diff_recursive, diff_simple, diff_set_0, diff_set_1, diff_forcing, diff_recursive, - usersolvers, newctx, ctxnew, ctxfree); + usersolvers, valid, newctx, + ctxnew, ctxfree); latin_solver_free(&subsolver); if (ctxnew) ctxfree(newctx); @@ -879,8 +880,8 @@ static int latin_solver_recurse static int latin_solver_top(struct latin_solver *solver, int maxdiff, int diff_simple, int diff_set_0, int diff_set_1, int diff_forcing, int diff_recursive, - usersolver_t const *usersolvers, void *ctx, - ctxnew_t ctxnew, ctxfree_t ctxfree) + usersolver_t const *usersolvers, validator_t valid, + void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree) { struct latin_solver_scratch *scratch = latin_solver_new_scratch(solver); int ret, diff = diff_simple; @@ -941,7 +942,8 @@ static int latin_solver_top(struct latin_solver *solver, int maxdiff, int nsol = latin_solver_recurse(solver, diff_simple, diff_set_0, diff_set_1, diff_forcing, diff_recursive, - usersolvers, ctx, ctxnew, ctxfree); + usersolvers, valid, ctx, + ctxnew, ctxfree); if (nsol < 0) diff = diff_impossible; else if (nsol == 1) diff = diff_recursive; else if (nsol > 1) diff = diff_ambiguous; @@ -990,6 +992,17 @@ static int latin_solver_top(struct latin_solver *solver, int maxdiff, } #endif + if (diff != diff_impossible && diff != diff_unfinished && + diff != diff_ambiguous && valid && !valid(solver, ctx)) { +#ifdef STANDALONE_SOLVER + if (solver_show_working) { + printf("%*ssolution failed final validation!\n", + solver_recurse_depth*4, ""); + } +#endif + diff = diff_impossible; + } + latin_solver_free_scratch(scratch); return diff; @@ -998,8 +1011,8 @@ static int latin_solver_top(struct latin_solver *solver, int maxdiff, int latin_solver_main(struct latin_solver *solver, int maxdiff, int diff_simple, int diff_set_0, int diff_set_1, int diff_forcing, int diff_recursive, - usersolver_t const *usersolvers, void *ctx, - ctxnew_t ctxnew, ctxfree_t ctxfree) + usersolver_t const *usersolvers, validator_t valid, + void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree) { int diff; #ifdef STANDALONE_SOLVER @@ -1027,7 +1040,7 @@ int latin_solver_main(struct latin_solver *solver, int maxdiff, diff = latin_solver_top(solver, maxdiff, diff_simple, diff_set_0, diff_set_1, diff_forcing, diff_recursive, - usersolvers, ctx, ctxnew, ctxfree); + usersolvers, valid, ctx, ctxnew, ctxfree); #ifdef STANDALONE_SOLVER sfree(names); @@ -1040,8 +1053,8 @@ int latin_solver_main(struct latin_solver *solver, int maxdiff, int latin_solver(digit *grid, int o, int maxdiff, int diff_simple, int diff_set_0, int diff_set_1, int diff_forcing, int diff_recursive, - usersolver_t const *usersolvers, void *ctx, - ctxnew_t ctxnew, ctxfree_t ctxfree) + usersolver_t const *usersolvers, validator_t valid, + void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree) { struct latin_solver solver; int diff; @@ -1050,7 +1063,7 @@ int latin_solver(digit *grid, int o, int maxdiff, diff = latin_solver_main(&solver, maxdiff, diff_simple, diff_set_0, diff_set_1, diff_forcing, diff_recursive, - usersolvers, ctx, ctxnew, ctxfree); + usersolvers, valid, ctx, ctxnew, ctxfree); latin_solver_free(&solver); return diff; } diff --git a/latin.h b/latin.h index ff6f07c..bb172ec 100644 --- a/latin.h +++ b/latin.h @@ -85,6 +85,7 @@ int latin_solver_diff_set(struct latin_solver *solver, bool extreme); typedef int (*usersolver_t)(struct latin_solver *solver, void *ctx); +typedef bool (*validator_t)(struct latin_solver *solver, void *ctx); typedef void *(*ctxnew_t)(void *ctx); typedef void (*ctxfree_t)(void *ctx); @@ -96,15 +97,15 @@ enum { diff_impossible = 10, diff_ambiguous, diff_unfinished }; int latin_solver(digit *grid, int o, int maxdiff, int diff_simple, int diff_set_0, int diff_set_1, int diff_forcing, int diff_recursive, - usersolver_t const *usersolvers, void *ctx, - ctxnew_t ctxnew, ctxfree_t ctxfree); + usersolver_t const *usersolvers, validator_t valid, + void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree); /* Version you can call if you want to alloc and free latin_solver yourself */ int latin_solver_main(struct latin_solver *solver, int maxdiff, int diff_simple, int diff_set_0, int diff_set_1, int diff_forcing, int diff_recursive, - usersolver_t const *usersolvers, void *ctx, - ctxnew_t ctxnew, ctxfree_t ctxfree); + usersolver_t const *usersolvers, validator_t valid, + void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree); void latin_solver_debug(unsigned char *cube, int o); diff --git a/towers.c b/towers.c index a72cae6..27d8751 100644 --- a/towers.c +++ b/towers.c @@ -574,6 +574,11 @@ static int solver_hard(struct latin_solver *solver, void *vctx) #define SOLVER(upper,title,func,lower) func, static usersolver_t const towers_solvers[] = { DIFFLIST(SOLVER) }; +static bool towers_valid(struct latin_solver *solver, void *ctx) +{ + return true; /* FIXME */ +} + static int solver(int w, int *clues, digit *soln, int maxdiff) { int ret; @@ -589,7 +594,7 @@ static int solver(int w, int *clues, digit *soln, int maxdiff) ret = latin_solver(soln, w, maxdiff, DIFF_EASY, DIFF_HARD, DIFF_EXTREME, DIFF_EXTREME, DIFF_UNREASONABLE, - towers_solvers, &ctx, NULL, NULL); + towers_solvers, towers_valid, &ctx, NULL, NULL); sfree(ctx.iscratch); sfree(ctx.dscratch); diff --git a/unequal.c b/unequal.c index d5b2bb1..a1b01b8 100644 --- a/unequal.c +++ b/unequal.c @@ -816,6 +816,11 @@ static int solver_set(struct latin_solver *solver, void *vctx) #define SOLVER(upper,title,func,lower) func, static usersolver_t const unequal_solvers[] = { DIFFLIST(SOLVER) }; +static bool unequal_valid(struct latin_solver *solver, void *ctx) +{ + return true; /* FIXME */ +} + static int solver_state(game_state *state, int maxdiff) { struct solver_ctx *ctx = new_ctx(state); @@ -827,7 +832,8 @@ static int solver_state(game_state *state, int maxdiff) diff = latin_solver_main(&solver, maxdiff, DIFF_LATIN, DIFF_SET, DIFF_EXTREME, DIFF_EXTREME, DIFF_RECURSIVE, - unequal_solvers, ctx, clone_ctx, free_ctx); + unequal_solvers, unequal_valid, ctx, + clone_ctx, free_ctx); memcpy(state->hints, solver.cube, state->order*state->order*state->order); @@ -2155,7 +2161,8 @@ static int solve(game_params *p, char *desc, int debug) diff = latin_solver_main(&solver, DIFF_RECURSIVE, DIFF_LATIN, DIFF_SET, DIFF_EXTREME, DIFF_EXTREME, DIFF_RECURSIVE, - unequal_solvers, ctx, clone_ctx, free_ctx); + unequal_solvers, unequal_valid, ctx, + clone_ctx, free_ctx); free_ctx(ctx); diff --git a/unfinished/group.c b/unfinished/group.c index 3c565cb..3a44a67 100644 --- a/unfinished/group.c +++ b/unfinished/group.c @@ -448,6 +448,11 @@ static int solver_normal(struct latin_solver *solver, void *vctx) #define SOLVER(upper,title,func,lower) func, static usersolver_t const group_solvers[] = { DIFFLIST(SOLVER) }; +static bool group_valid(struct latin_solver *solver, void *ctx) +{ + return true; /* FIXME */ +} + static int solver(const game_params *params, digit *grid, int maxdiff) { int w = params->w; @@ -471,7 +476,7 @@ static int solver(const game_params *params, digit *grid, int maxdiff) ret = latin_solver_main(&solver, maxdiff, DIFF_TRIVIAL, DIFF_HARD, DIFF_EXTREME, DIFF_EXTREME, DIFF_UNREASONABLE, - group_solvers, NULL, NULL, NULL); + group_solvers, group_valid, NULL, NULL, NULL); latin_solver_free(&solver);