chiark / gitweb /
Net: fix assertion failure on insoluble puzzles.
[sgt-puzzles.git] / net.c
diff --git a/net.c b/net.c
index de51f82fd7c0e176f6c9bbe2bff3f67cf272b3e9..57d91d3581c5af92029ad219e505fa7db3f3c22f 100644 (file)
--- 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];