Vary the behaviour of Mines's solve function depending on whether the
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 10 Jun 2012 07:20:18 +0000 (07:20 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 10 Jun 2012 07:20:18 +0000 (07:20 +0000)
user is already in the 'dead' state when they press it. If so, we
reveal the rest of the mines in the grid as if it were the Windows
Minesweeper 'you lose' display, which provides information showing
what the user got wrong. (Otherwise they have to repeatedly flick back
and forth between Solve and Undo if they want to work out which flag
they placed wrongly.)

If you press Solve while alive, however, the existing behaviour
remains unchanged.

(This feature was suggested by Clive Jones a couple of weeks after I
first wrote Mines, and I've finally got round to doing it!)

git-svn-id: svn://svn.tartarus.org/sgt/puzzles@9561 cda61777-01e9-0310-a592-d414129be87e

mines.c

diff --git a/mines.c b/mines.c
index 13cdc0c..7801ab4 100644 (file)
--- a/mines.c
+++ b/mines.c
@@ -2596,35 +2596,58 @@ static game_state *execute_move(game_state *from, char *move)
     game_state *ret;
 
     if (!strcmp(move, "S")) {
-       /*
-        * Simply expose the entire grid as if it were a completed
-        * solution.
-        */
        int yy, xx;
 
        ret = dup_game(from);
-       for (yy = 0; yy < ret->h; yy++)
-           for (xx = 0; xx < ret->w; xx++) {
-
-               if (ret->layout->mines[yy*ret->w+xx]) {
-                   ret->grid[yy*ret->w+xx] = -1;
-               } else {
-                   int dx, dy, v;
-
-                   v = 0;
-
-                   for (dx = -1; dx <= +1; dx++)
-                       for (dy = -1; dy <= +1; dy++)
-                           if (xx+dx >= 0 && xx+dx < ret->w &&
-                               yy+dy >= 0 && yy+dy < ret->h &&
-                               ret->layout->mines[(yy+dy)*ret->w+(xx+dx)])
-                               v++;
-
-                   ret->grid[yy*ret->w+xx] = v;
-               }
-           }
-       ret->used_solve = TRUE;
-       ret->won = TRUE;
+        if (!ret->dead) {
+            /*
+             * If the player is still alive at the moment of pressing
+             * Solve, expose the entire grid as if it were a completed
+             * solution.
+             */
+            for (yy = 0; yy < ret->h; yy++)
+                for (xx = 0; xx < ret->w; xx++) {
+
+                    if (ret->layout->mines[yy*ret->w+xx]) {
+                        ret->grid[yy*ret->w+xx] = -1;
+                    } else {
+                        int dx, dy, v;
+
+                        v = 0;
+
+                        for (dx = -1; dx <= +1; dx++)
+                            for (dy = -1; dy <= +1; dy++)
+                                if (xx+dx >= 0 && xx+dx < ret->w &&
+                                    yy+dy >= 0 && yy+dy < ret->h &&
+                                    ret->layout->mines[(yy+dy)*ret->w+(xx+dx)])
+                                    v++;
+
+                        ret->grid[yy*ret->w+xx] = v;
+                    }
+                }
+        } else {
+            /*
+             * If the player pressed Solve _after dying_, show a full
+             * corrections grid in the style of standard Minesweeper.
+             * Players who don't like Mines's behaviour on death of
+             * only showing the mine that killed you (so that in case
+             * of a typo you can undo and carry on without the rest of
+             * the grid being spoiled) can use this to get the display
+             * that ordinary Minesweeper would have given them.
+             */
+            for (yy = 0; yy < ret->h; yy++)
+                for (xx = 0; xx < ret->w; xx++) {
+                    int pos = yy*ret->w+xx;
+                    if ((ret->grid[pos] == -2 || ret->grid[pos] == -3) &&
+                        ret->layout->mines[pos]) {
+                        ret->grid[pos] = 64;
+                    } else if (ret->grid[pos] == -1 &&
+                               !ret->layout->mines[pos]) {
+                        ret->grid[pos] = 66;
+                    }
+                }
+        }
+        ret->used_solve = TRUE;
 
        return ret;
     } else {