mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-20 23:51:29 -07:00
latin_solver_alloc: handle clashing numbers in input grid.
In the setup phase of the centralised latin.c solver, we start by going over the input grid containing already-placed clue numbers, and calling latin_solver_place to enter each on into the solver's data structure. This has the side effect of ruling out each number from the rest of the row and column, and _also_ checking by assertion that the number being placed is not ruled out. Those are a bad combination, because it means that if you give an obviously inconsistent input grid to latin_solver_alloc (e.g. with two identical numbers in a row already), it will fail an assertion. In that situation, you want the solver run as a whole to return diff_impossible so that the error is reported cleanly. This assertion failure could be provoked by giving either Towers or Group a manually-constructed game description inconsistent in that way, and hitting Solve. Worse, it could be provoked during live play in Unequal, by filling in a number clashing with a clue and then pressing 'h' to get hints.
This commit is contained in:
30
unequal.c
30
unequal.c
@ -890,13 +890,14 @@ static int solver_state(game_state *state, int maxdiff)
|
||||
struct latin_solver solver;
|
||||
int diff;
|
||||
|
||||
latin_solver_alloc(&solver, state->nums, state->order);
|
||||
|
||||
diff = latin_solver_main(&solver, maxdiff,
|
||||
DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
|
||||
DIFF_EXTREME, DIFF_RECURSIVE,
|
||||
unequal_solvers, unequal_valid, ctx,
|
||||
clone_ctx, free_ctx);
|
||||
if (!latin_solver_alloc(&solver, state->nums, state->order))
|
||||
diff = latin_solver_main(&solver, maxdiff,
|
||||
DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
|
||||
DIFF_EXTREME, DIFF_RECURSIVE,
|
||||
unequal_solvers, unequal_valid, ctx,
|
||||
clone_ctx, free_ctx);
|
||||
else
|
||||
diff = DIFF_IMPOSSIBLE;
|
||||
|
||||
memcpy(state->hints, solver.cube, state->order*state->order*state->order);
|
||||
|
||||
@ -2256,13 +2257,14 @@ static int solve(game_params *p, char *desc, int debug)
|
||||
solver_show_working = debug;
|
||||
game_debug(state);
|
||||
|
||||
latin_solver_alloc(&solver, state->nums, state->order);
|
||||
|
||||
diff = latin_solver_main(&solver, DIFF_RECURSIVE,
|
||||
DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
|
||||
DIFF_EXTREME, DIFF_RECURSIVE,
|
||||
unequal_solvers, unequal_valid, ctx,
|
||||
clone_ctx, free_ctx);
|
||||
if (latin_solver_alloc(&solver, state->nums, state->order))
|
||||
diff = latin_solver_main(&solver, DIFF_RECURSIVE,
|
||||
DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
|
||||
DIFF_EXTREME, DIFF_RECURSIVE,
|
||||
unequal_solvers, unequal_valid, ctx,
|
||||
clone_ctx, free_ctx);
|
||||
else
|
||||
diff = DIFF_IMPOSSIBLE;
|
||||
|
||||
free_ctx(ctx);
|
||||
|
||||
|
Reference in New Issue
Block a user