Stop the analysis pass in Loopy's redraw routine from being
[sgt/puzzles] / tents.c
diff --git a/tents.c b/tents.c
index c0ea0eb..ef5debc 100644 (file)
--- a/tents.c
+++ b/tents.c
@@ -459,7 +459,7 @@ static int tents_solve(int w, int h, const char *grid, int *numbers,
                       char *soln, struct solver_scratch *sc, int diff)
 {
     int x, y, d, i, j;
-    char *mrow, *mrow1, *mrow2, *trow, *trow1, *trow2;
+    char *mrow, *trow, *trow1, *trow2;
 
     /*
      * Set up solver data.
@@ -746,8 +746,6 @@ static int tents_solve(int w, int h, const char *grid, int *numbers,
             * hasn't been set up yet.
             */
            mrow = sc->mrows;
-           mrow1 = sc->mrows + len;
-           mrow2 = sc->mrows + 2*len;
            trow = sc->trows;
            trow1 = sc->trows + len;
            trow2 = sc->trows + 2*len;
@@ -1210,6 +1208,10 @@ static char *validate_desc(game_params *params, char *desc)
 
        desc++;
     }
+    if (area < w * h + 1)
+       return "Not enough data to fill grid";
+    else if (area > w * h + 1)
+       return "Too much data to fill grid";
 
     for (i = 0; i < w+h; i++) {
        if (!*desc)
@@ -1465,6 +1467,7 @@ static int drag_xform(game_ui *ui, int x, int y, int v)
     ymin = min(ui->dsy, ui->dey);
     ymax = max(ui->dsy, ui->dey);
 
+#ifndef STYLUS_BASED
     /*
      * Left-dragging has no effect, so we treat a left-drag as a
      * single click on dsx,dsy.
@@ -1473,6 +1476,7 @@ static int drag_xform(game_ui *ui, int x, int y, int v)
         xmin = xmax = ui->dsx;
         ymin = ymax = ui->dsy;
     }
+#endif
 
     if (x < xmin || x > xmax || y < ymin || y > ymax)
         return v;                      /* no change outside drag area */
@@ -1485,11 +1489,18 @@ static int drag_xform(game_ui *ui, int x, int y, int v)
          * Results of a simple click. Left button sets blanks to
          * tents; right button sets blanks to non-tents; either
          * button clears a non-blank square.
+         * If stylus-based however, it loops instead.
          */
         if (ui->drag_button == LEFT_BUTTON)
+#ifdef STYLUS_BASED
+            v = (v == BLANK ? TENT : (v == TENT ? NONTENT : BLANK));
+        else
+            v = (v == BLANK ? NONTENT : (v == NONTENT ? TENT : BLANK));
+#else
             v = (v == BLANK ? TENT : BLANK);
         else
             v = (v == BLANK ? NONTENT : BLANK);
+#endif
     } else {
         /*
          * Results of a drag. Left-dragging has no effect.
@@ -1499,13 +1510,17 @@ static int drag_xform(game_ui *ui, int x, int y, int v)
         if (ui->drag_button == RIGHT_BUTTON)
             v = (v == BLANK ? NONTENT : v);
         else
+#ifdef STYLUS_BASED
+            v = (v == BLANK ? NONTENT : v);
+#else
             /* do nothing */;
+#endif
     }
 
     return v;
 }
 
-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)
 {
     int w = state->p.w, h = state->p.h;
@@ -1964,11 +1979,14 @@ static int *find_errors(game_state *state, char *grid)
      * Also, that approach fares badly when you introduce the
      * additional requirement that incomplete grids should have
      * errors highlighted only when they can be proved to be errors
-     * - so that a tree surrounded by BLANK squares should not be
-     * marked as erroneous (it would be patronising, since the
-     * overwhelming likelihood is not that the player has forgotten
-     * to put a tree there but that they have merely not put one
-     * there _yet), but one surrounded by NONTENTs should.
+     * - so that trees should not be marked as having too few tents
+     * if there are enough BLANK squares remaining around them that
+     * could be turned into the missing tents (to do so would be
+     * patronising, since the overwhelming likelihood is not that
+     * the player has forgotten to put a tree there but that they
+     * have merely not put one there _yet_). However, tents with too
+     * few trees can be marked immediately, since those are
+     * definitely player error.
      *
      * So I adopt an alternative approach, which is to consider the
      * bipartite adjacency graph between trees and tents
@@ -2392,7 +2410,7 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
      * currently active drag: we transform dsx,dsy but not anything
      * else. (This seems to strike a good compromise between having
      * the error highlights respond instantly to single clicks, but
-     * not give constant feedback during a right-drag.)
+     * not giving constant feedback during a right-drag.)
      */
     if (ui && ui->drag_button >= 0) {
        tmpgrid = snewn(w*h, char);
@@ -2445,7 +2463,7 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
      * changed) the numbers.
      */
     for (x = 0; x < w; x++) {
-       if (ds->numbersdrawn[x] != errors[w*h+x]) {
+       if (printing || ds->numbersdrawn[x] != errors[w*h+x]) {
            char buf[80];
            draw_rect(dr, COORD(x), COORD(h)+1, TILESIZE, BRBORDER-1,
                      COL_BACKGROUND);
@@ -2454,11 +2472,12 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
                      FONT_VARIABLE, TILESIZE/2, ALIGN_HCENTRE|ALIGN_VNORMAL,
                      (errors[w*h+x] ? COL_ERROR : COL_GRID), buf);
            draw_update(dr, COORD(x), COORD(h)+1, TILESIZE, BRBORDER-1);
-           ds->numbersdrawn[x] = errors[w*h+x];
+           if (!printing)
+                ds->numbersdrawn[x] = errors[w*h+x];
        }
     }
     for (y = 0; y < h; y++) {
-       if (ds->numbersdrawn[w+y] != errors[w*h+w+y]) {
+       if (printing || ds->numbersdrawn[w+y] != errors[w*h+w+y]) {
            char buf[80];
            draw_rect(dr, COORD(w)+1, COORD(y), BRBORDER-1, TILESIZE,
                      COL_BACKGROUND);
@@ -2467,7 +2486,8 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
                      FONT_VARIABLE, TILESIZE/2, ALIGN_HRIGHT|ALIGN_VCENTRE,
                      (errors[w*h+w+y] ? COL_ERROR : COL_GRID), buf);
            draw_update(dr, COORD(w)+1, COORD(y), BRBORDER-1, TILESIZE);
-           ds->numbersdrawn[w+y] = errors[w*h+w+y];
+           if (!printing)
+                ds->numbersdrawn[w+y] = errors[w*h+w+y];
        }
     }
 
@@ -2502,6 +2522,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;
@@ -2572,6 +2597,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,