Stop the analysis pass in Loopy's redraw routine from being
[sgt/puzzles] / filling.c
index 0209062..a0c9fc4 100644 (file)
--- a/filling.c
+++ b/filling.c
@@ -1036,7 +1036,7 @@ struct game_drawstate {
     int *dsf_scratch, *border_scratch;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
                             int x, int y, int button)
 {
     const int w = state->shared->params.w;
@@ -1097,11 +1097,10 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
       case '\r':
       case '\n':
       case '\b':
-      case '\177':
         button = 0;
         break;
       default:
-        if (!isdigit(button)) return NULL;
+        if (button < '0' || button > '9') return NULL;
         button -= '0';
         if (button > (w == 2 && h == 2? 3: max(w, h))) return NULL;
     }
@@ -1138,7 +1137,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
 
 static game_state *execute_move(game_state *state, char *move)
 {
-    game_state *new_state;
+    game_state *new_state = NULL;
     const int sz = state->shared->params.w * state->shared->params.h;
 
     if (*move == 's') {
@@ -1149,18 +1148,18 @@ static game_state *execute_move(game_state *state, char *move)
     } else {
         int value;
         char *endptr, *delim = strchr(move, '_');
-        if (!delim) return NULL;
+        if (!delim) goto err;
         value = strtol(delim+1, &endptr, 0);
-        if (*endptr || endptr == delim+1) return NULL;
-        if (value < 0 || value > 9) return NULL;
+        if (*endptr || endptr == delim+1) goto err;
+        if (value < 0 || value > 9) goto err;
         new_state = dup_game(state);
         while (*move) {
             const int i = strtol(move, &endptr, 0);
-            if (endptr == move) return NULL;
-            if (i < 0 || i >= sz) return NULL;
+            if (endptr == move) goto err;
+            if (i < 0 || i >= sz) goto err;
             new_state->board[i] = value;
             if (*endptr == '_') break;
-            if (*endptr != ',') return NULL;
+            if (*endptr != ',') goto err;
             move = endptr + 1;
         }
     }
@@ -1181,6 +1180,10 @@ static game_state *execute_move(game_state *state, char *move)
     }
 
     return new_state;
+
+err:
+    if (new_state) free_game(new_state);
+    return NULL;
 }
 
 /* ----------------------------------------------------------------------
@@ -1491,21 +1494,37 @@ static void draw_grid(drawing *dr, game_drawstate *ds, game_state *state,
             /*
              * Determine what we need to draw in this square.
              */
-            int v = state->board[y*w+x];
+            int i = y*w+x, v = state->board[i];
             int flags = 0;
 
             if (flashy || !shading) {
                 /* clear all background flags */
-            } else if (ui->sel && ui->sel[y*w+x]) {
+            } else if (ui && ui->sel && ui->sel[i]) {
                 flags |= HIGH_BG;
             } else if (v) {
-                int size = dsf_size(ds->dsf_scratch, y*w+x);
+                int size = dsf_size(ds->dsf_scratch, i);
                 if (size == v)
                     flags |= CORRECT_BG;
                 else if (size > v)
                     flags |= ERROR_BG;
+               else {
+                   int rt = dsf_canonify(ds->dsf_scratch, i), j;
+                   for (j = 0; j < w*h; ++j) {
+                       int k;
+                       if (dsf_canonify(ds->dsf_scratch, j) != rt) continue;
+                       for (k = 0; k < 4; ++k) {
+                           const int xx = j % w + dx[k], yy = j / w + dy[k];
+                           if (xx >= 0 && xx < w && yy >= 0 && yy < h &&
+                               state->board[yy*w + xx] == EMPTY)
+                               goto noflag;
+                       }
+                   }
+                   flags |= ERROR_BG;
+                 noflag:
+                   ;
+               }
             }
-            if (ui->cur_visible && x == ui->cur_x && y == ui->cur_y)
+            if (ui && ui->cur_visible && x == ui->cur_x && y == ui->cur_y)
               flags |= CURSOR_SQ;
 
             /*
@@ -1614,6 +1633,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_status(game_state *state)
+{
+    return state->completed ? +1 : 0;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1712,6 +1736,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                                /* wants_statusbar */
     FALSE, game_timing_state,