shithub: puzzles

Download patch

ref: 6567260eb0af75a3c82f4a8a8292c6446d94fd98
parent: 48e9767a206420294147f802a8a2cc5c9e77141c
author: Simon Tatham <anakin@pobox.com>
date: Sun Jun 10 03:20:18 EDT 2012

Vary the behaviour of Mines's solve function depending on whether the
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!)

[originally from svn r9561]

--- a/mines.c
+++ b/mines.c
@@ -2596,35 +2596,58 @@
     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->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;
+                    if (ret->layout->mines[yy*ret->w+xx]) {
+                        ret->grid[yy*ret->w+xx] = -1;
+                    } else {
+                        int dx, dy, v;
 
-		    v = 0;
+                        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++;
+                        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;
+                        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 {