mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-22 08:25:45 -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:
@ -580,13 +580,11 @@ static int solver(const game_params *params, digit *grid, int maxdiff)
|
||||
int w = params->w;
|
||||
int ret;
|
||||
struct latin_solver solver;
|
||||
|
||||
#ifdef STANDALONE_SOLVER
|
||||
char *p, text[100], *names[50];
|
||||
int i;
|
||||
#endif
|
||||
|
||||
latin_solver_alloc(&solver, grid, w);
|
||||
#ifdef STANDALONE_SOLVER
|
||||
for (i = 0, p = text; i < w; i++) {
|
||||
names[i] = p;
|
||||
*p++ = TOCHAR(i+1, params->id);
|
||||
@ -595,10 +593,13 @@ static int solver(const game_params *params, digit *grid, int maxdiff)
|
||||
solver.names = names;
|
||||
#endif
|
||||
|
||||
ret = latin_solver_main(&solver, maxdiff,
|
||||
DIFF_TRIVIAL, DIFF_HARD, DIFF_EXTREME,
|
||||
DIFF_EXTREME, DIFF_UNREASONABLE,
|
||||
group_solvers, group_valid, NULL, NULL, NULL);
|
||||
if (latin_solver_alloc(&solver, grid, w))
|
||||
ret = latin_solver_main(&solver, maxdiff,
|
||||
DIFF_TRIVIAL, DIFF_HARD, DIFF_EXTREME,
|
||||
DIFF_EXTREME, DIFF_UNREASONABLE,
|
||||
group_solvers, group_valid, NULL, NULL, NULL);
|
||||
else
|
||||
ret = diff_impossible;
|
||||
|
||||
latin_solver_free(&solver);
|
||||
|
||||
|
Reference in New Issue
Block a user