diff --git a/net.c b/net.c index de51f82..57d91d3 100644 --- a/net.c +++ b/net.c @@ -459,6 +459,11 @@ static int todo_get(struct todo *todo) { 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, unsigned char *barriers, int wrapping) { @@ -733,7 +738,11 @@ static int net_solver(int w, int h, unsigned char *tiles, #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) { 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. */ - j = TRUE; + j = +1; for (i = 0; i < w*h; i++) { if (tilestate[i * 4 + 1] == 255) { assert(tilestate[i * 4 + 0] != 255); tiles[i] = tilestate[i * 4] | LOCKED; } else { 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. */ - while (!net_solver(w, h, tiles, NULL, params->wrapping)) { + while (net_solver(w, h, tiles, NULL, params->wrapping) != 1) { 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 * not yield a complete solution. */ + int solver_result; + memcpy(tiles, state->tiles, state->width * state->height); - net_solver(state->width, state->height, tiles, - state->barriers, state->wrapping); + solver_result = net_solver(state->width, state->height, tiles, + state->barriers, state->wrapping); + + if (solver_result < 0) { + *error = "No solution exists for this puzzle"; + sfree(tiles); + return NULL; + } } else { for (i = 0; i < state->width * state->height; i++) { int c = aux[i];