mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Net: fix assertion failure on insoluble puzzles.
The solver code still had an assumption, which must have dated before the Solve menu option was introduced, that all puzzles presented to it had at least one valid solution, and was enforcing that assumption by assert(). Now the solver returns a more sensible failure code which solve_game() can convert into a proper error message.
This commit is contained in:
29
net.c
29
net.c
@ -459,6 +459,11 @@ static int todo_get(struct todo *todo) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return values: -1 means puzzle was proved inconsistent, 0 means we
|
||||||
|
* failed to narrow down to a unique solution, +1 means we solved it
|
||||||
|
* fully.
|
||||||
|
*/
|
||||||
static int net_solver(int w, int h, unsigned char *tiles,
|
static int net_solver(int w, int h, unsigned char *tiles,
|
||||||
unsigned char *barriers, int wrapping)
|
unsigned char *barriers, int wrapping)
|
||||||
{
|
{
|
||||||
@ -733,7 +738,11 @@ static int net_solver(int w, int h, unsigned char *tiles,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(j > 0); /* we can't lose _all_ possibilities! */
|
if (j == 0) {
|
||||||
|
/* If we've ruled out all possible orientations for a
|
||||||
|
* tile, then our puzzle has no solution at all. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (j < i) {
|
if (j < i) {
|
||||||
done_something = TRUE;
|
done_something = TRUE;
|
||||||
@ -813,14 +822,14 @@ static int net_solver(int w, int h, unsigned char *tiles,
|
|||||||
/*
|
/*
|
||||||
* Mark all completely determined tiles as locked.
|
* Mark all completely determined tiles as locked.
|
||||||
*/
|
*/
|
||||||
j = TRUE;
|
j = +1;
|
||||||
for (i = 0; i < w*h; i++) {
|
for (i = 0; i < w*h; i++) {
|
||||||
if (tilestate[i * 4 + 1] == 255) {
|
if (tilestate[i * 4 + 1] == 255) {
|
||||||
assert(tilestate[i * 4 + 0] != 255);
|
assert(tilestate[i * 4 + 0] != 255);
|
||||||
tiles[i] = tilestate[i * 4] | LOCKED;
|
tiles[i] = tilestate[i * 4] | LOCKED;
|
||||||
} else {
|
} else {
|
||||||
tiles[i] &= ~LOCKED;
|
tiles[i] &= ~LOCKED;
|
||||||
j = FALSE;
|
j = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1334,7 +1343,7 @@ static char *new_game_desc(const game_params *params, random_state *rs,
|
|||||||
/*
|
/*
|
||||||
* Run the solver to check unique solubility.
|
* Run the solver to check unique solubility.
|
||||||
*/
|
*/
|
||||||
while (!net_solver(w, h, tiles, NULL, params->wrapping)) {
|
while (net_solver(w, h, tiles, NULL, params->wrapping) != 1) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1758,9 +1767,17 @@ static char *solve_game(const game_state *state, const game_state *currstate,
|
|||||||
* Run the internal solver on the provided grid. This might
|
* Run the internal solver on the provided grid. This might
|
||||||
* not yield a complete solution.
|
* not yield a complete solution.
|
||||||
*/
|
*/
|
||||||
|
int solver_result;
|
||||||
|
|
||||||
memcpy(tiles, state->tiles, state->width * state->height);
|
memcpy(tiles, state->tiles, state->width * state->height);
|
||||||
net_solver(state->width, state->height, tiles,
|
solver_result = net_solver(state->width, state->height, tiles,
|
||||||
state->barriers, state->wrapping);
|
state->barriers, state->wrapping);
|
||||||
|
|
||||||
|
if (solver_result < 0) {
|
||||||
|
*error = "No solution exists for this puzzle";
|
||||||
|
sfree(tiles);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < state->width * state->height; i++) {
|
for (i = 0; i < state->width * state->height; i++) {
|
||||||
int c = aux[i];
|
int c = aux[i];
|
||||||
|
Reference in New Issue
Block a user