Changed my mind about midend_is_solved: I've now reprototyped it as
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 19 Jun 2011 13:43:35 +0000 (13:43 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 19 Jun 2011 13:43:35 +0000 (13:43 +0000)
midend_status(), and given it three return codes for win, (permanent)
loss and game-still-in-play. Depending on what the front end wants to
use it for, it may find any or all of these three states worth
distinguishing from each other.

(I suppose a further enhancement might be to add _non_-permanent loss
as a fourth distinct status, to describe situations in which you can't
play further without pressing Undo but doing so is not completely
pointless. That might reasonably include dead-end situations in Same
Game and Pegs, and blown-self-up situations in Mines and Inertia.
However, I haven't done this at present.)

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

42 files changed:
blackbox.c
bridges.c
cube.c
devel.but
dominosa.c
fifteen.c
filling.c
flip.c
galaxies.c
guess.c
inertia.c
keen.c
lightup.c
loopy.c
magnets.c
map.c
midend.c
mines.c
net.c
netslide.c
nullgame.c
pattern.c
pegs.c
puzzles.h
range.c
rect.c
samegame.c
signpost.c
singles.c
sixteen.c
slant.c
solo.c
tents.c
towers.c
twiddle.c
unequal.c
unfinished/group.c
unfinished/pearl.c
unfinished/separate.c
unfinished/slide.c
unfinished/sokoban.c
untangle.c

index 305feac..be79634 100644 (file)
@@ -1462,13 +1462,21 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    /*
-     * We return true whenever the solution has been revealed, even
-     * (on spoiler grounds) if it wasn't guessed correctly.
-     */
-    return state->reveal;
+    if (state->reveal) {
+        /*
+         * We return nonzero whenever the solution has been revealed,
+         * even (on spoiler grounds) if it wasn't guessed correctly.
+         */
+        if (state->nwrong == 0 &&
+            state->nmissed == 0 &&
+            state->nright >= state->minballs)
+            return +1;
+        else
+            return -1;
+    }
+    return 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1519,7 +1527,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 8e61400..5860e0c 100644 (file)
--- a/bridges.c
+++ b/bridges.c
@@ -2713,9 +2713,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2821,7 +2821,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/cube.c b/cube.c
index 9b70487..cac4640 100644 (file)
--- a/cube.c
+++ b/cube.c
@@ -1708,9 +1708,9 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1761,7 +1761,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 9438e0e..806ac63 100644 (file)
--- a/devel.but
+++ b/devel.but
@@ -1224,27 +1224,33 @@ a mine from the colour it uses when you complete the game. In order
 to achieve this, its \cw{flash_length()} function has to store a
 flag in the \c{game_ui} to indicate which flash type is required.)
 
-\S{backend-is-solved} \cw{is_solved()}
+\S{backend-status} \cw{status()}
 
-\c int (*is_solved)(game_state *state);
+\c int (*status)(game_state *state);
 
-This function returns \cw{TRUE} if the game represented by \cw{state}
-is currently in a solved state. The mid-end uses this to implement
-\cw{midend_is_solved()} (\k{midend-is-solved}).
+This function returns a status value indicating whether the current
+game is still in play, or has been won, or has been conclusively lost.
+The mid-end uses this to implement \cw{midend_status()}
+(\k{midend-status}).
 
-Front ends may wish to use this as a cue to proactively offer the
-option of starting a new game. Therefore, back ends should consider
-returning \cw{TRUE} in situations where the game is \e{lost} as well
-as won, if losing makes it unlikely that the player would play on.
+The return value should be +1 if the game has been successfully
+solved. If the game has been lost in a situation where further play is
+unlikely, the return value should be -1. If neither is true (so play
+is still ongoing), return zero.
+
+Front ends may wish to use a non-zero status as a cue to proactively
+offer the option of starting a new game. Therefore, back ends should
+not return -1 if the game has been \e{technically} lost but undoing
+and continuing is still a realistic possibility.
 
 (For instance, games with hidden information such as Guess or Mines
-might well set this flag whenever they reveal the solution, whether or
-not the player guessed it correctly, on the grounds that a player
-would be unlikely to hide the solution and continue playing after the
-answer was spoiled. On the other hand, games where you can merely get
-into a dead end such as Same Game or Inertia might choose not to, on
-the grounds that the player would quite likely press Undo and carry on
-playing.)
+might well return a non-zero status whenever they reveal the solution,
+whether or not the player guessed it correctly, on the grounds that a
+player would be unlikely to hide the solution and continue playing
+after the answer was spoiled. On the other hand, games where you can
+merely get into a dead end such as Same Game or Inertia might choose
+to return 0 in that situation, on the grounds that the player would
+quite likely press Undo and carry on playing.)
 
 \S{backend-redraw} \cw{redraw()}
 
@@ -3118,18 +3124,19 @@ The front end can expect its drawing API and/or
 \cw{activate_timer()} to be called from within a call to this
 function.
 
-\H{midend-is-solved} \cw{midend_is_solved()}
+\H{midend-status} \cw{midend_status()}
 
-\c int midend_is_solved(midend *me);
+\c int midend_status(midend *me);
 
-This function returns \cw{TRUE} if the midend is currently displaying
-a game in a solved state, according to the back end's \cw{is_solved()}
+This function returns +1 if the midend is currently displaying a game
+in a solved state, -1 if the game is in a permanently lost state, or 0
+otherwise. This function just calls the back end's \cw{status()}
 function. Front ends may wish to use this as a cue to proactively
 offer the option of starting a new game.
 
-(See \k{backend-is-solved} for more detail about the back end's
-\cw{is_solved()} function and discussion of what should count as
-\q{solved} anyway).
+(See \k{backend-status} for more detail about the back end's
+\cw{status()} function and discussion of what should count as which
+status code.)
 
 \H{midend-can-undo} \cw{midend_can_undo()}
 
index 21d4b67..02e276c 100644 (file)
@@ -1535,9 +1535,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1628,7 +1628,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 338a993..5419f41 100644 (file)
--- a/fifteen.c
+++ b/fifteen.c
@@ -830,9 +830,9 @@ static float game_flash_length(game_state *oldstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -883,7 +883,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 8b4a7c3..6a0abe9 100644 (file)
--- a/filling.c
+++ b/filling.c
@@ -1617,9 +1617,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1720,7 +1720,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                                /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/flip.c b/flip.c
index f8b96ae..6ba683b 100644 (file)
--- a/flip.c
+++ b/flip.c
@@ -1251,9 +1251,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1304,7 +1304,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 77ef597..d8906b6 100644 (file)
@@ -3348,9 +3348,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -3573,7 +3573,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
 #ifdef EDITOR
     FALSE, FALSE, NULL, NULL,
     TRUE,                              /* wants_statusbar */
diff --git a/guess.c b/guess.c
index 8cab1a4..a9fc134 100644 (file)
--- a/guess.c
+++ b/guess.c
@@ -43,7 +43,7 @@ struct game_state {
     pegrow solution;
     int next_go; /* from 0 to nguesses-1;
                     if next_go == nguesses then they've lost. */
-    int solved;
+    int solved;   /* +1 = win, -1 = lose, 0 = still playing */
 };
 
 static game_params *default_params(void)
@@ -790,7 +790,7 @@ static game_state *execute_move(game_state *from, char *move)
 
     if (!strcmp(move, "S")) {
        ret = dup_game(from);
-       ret->solved = 1;
+       ret->solved = -1;
        return ret;
     } else if (move[0] == 'G') {
        p = move+1;
@@ -817,11 +817,11 @@ static game_state *execute_move(game_state *from, char *move)
        nc_place = mark_pegs(ret->guesses[from->next_go], ret->solution, ret->params.ncolours);
 
        if (nc_place == ret->solution->npegs) {
-           ret->solved = 1; /* win! */
+           ret->solved = +1; /* win! */
        } else {
            ret->next_go = from->next_go + 1;
            if (ret->next_go >= ret->params.nguesses)
-               ret->solved = 1; /* 'lose' so we show the pegs. */
+               ret->solved = -1; /* lose, meaning we show the pegs. */
        }
 
        return ret;
@@ -1273,7 +1273,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
         currmove_redraw(dr, ds, state->next_go, COL_HOLD);
 
     /* draw the solution (or the big rectangle) */
-    if ((state->solved != ds->solved) || !ds->started) {
+    if ((!state->solved ^ !ds->solved) || !ds->started) {
         draw_rect(dr, SOLN_OX, SOLN_OY, SOLN_W, SOLN_H,
                   state->solved ? COL_BACKGROUND : COL_EMPTY);
         draw_update(dr, SOLN_OX, SOLN_OY, SOLN_W, SOLN_H);
@@ -1313,14 +1313,13 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
     /*
-     * We return true whenever the solution has been revealed, even
-     * (on spoiler grounds) if it wasn't guessed correctly.
-     *
-     * However, in that situation, 'solved' is still true, so we don't
-     * have to make any effort to arrange this.
+     * We return nonzero whenever the solution has been revealed, even
+     * (on spoiler grounds) if it wasn't guessed correctly. The
+     * correct return value from this function is already in
+     * state->solved.
      */
     return state->solved;
 }
@@ -1373,7 +1372,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index d29a676..74fc3c1 100644 (file)
--- a/inertia.c
+++ b/inertia.c
@@ -2135,14 +2135,14 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
     /*
-     * If the player has died, we don't list the game as solved,
-     * because they're more likely to undo and carry on than to give
-     * up and start a new game.
+     * We never report the game as lost, on the grounds that if the
+     * player has died they're quite likely to want to undo and carry
+     * on.
      */
-    return !state->gems;
+    return state->gems == 0 ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2193,7 +2193,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/keen.c b/keen.c
index 7984475..3776283 100644 (file)
--- a/keen.c
+++ b/keen.c
@@ -2005,9 +2005,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2286,7 +2286,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 5d27fde..5fe95b0 100644 (file)
--- a/lightup.c
+++ b/lightup.c
@@ -2160,9 +2160,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2267,7 +2267,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/loopy.c b/loopy.c
index b84ca82..1f95f41 100644 (file)
--- a/loopy.c
+++ b/loopy.c
@@ -3780,9 +3780,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->solved;
+    return state->solved ? +1 : 0;
 }
 
 static void game_print_size(game_params *params, float *x, float *y)
@@ -3918,7 +3918,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE /* wants_statusbar */,
     FALSE, game_timing_state,
index d932232..e49b7a5 100644 (file)
--- a/magnets.c
+++ b/magnets.c
@@ -2233,9 +2233,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2373,7 +2373,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/map.c b/map.c
index 556a9ec..5d170d1 100644 (file)
--- a/map.c
+++ b/map.c
@@ -3025,9 +3025,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
        return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -3223,7 +3223,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, TRUE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 0c8b3c0..8f4e4c9 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -1336,7 +1336,7 @@ char *midend_solve(midend *me)
     return NULL;
 }
 
-int midend_is_solved(midend *me)
+int midend_status(midend *me)
 {
     /*
      * We should probably never be called when the state stack has no
@@ -1347,8 +1347,10 @@ int midend_is_solved(midend *me)
      * practically, a user whose midend has been left in that state
      * probably _does_ want the 'new game' option to be prominent.
      */
-    return (me->statepos == 0 ||
-            me->ourgame->is_solved(me->states[me->statepos-1].state));
+    if (me->statepos == 0)
+        return +1;
+
+    return me->ourgame->status(me->states[me->statepos-1].state);
 }
 
 char *midend_rewrite_statusbar(midend *me, char *text)
diff --git a/mines.c b/mines.c
index 80d2337..13cdc0c 100644 (file)
--- a/mines.c
+++ b/mines.c
@@ -3084,9 +3084,14 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->won;
+    /*
+     * We report the game as lost only if the player has used the
+     * Solve function to reveal all the mines. Otherwise, we assume
+     * they'll undo and continue play.
+     */
+    return state->won ? (state->used_solve ? -1 : +1) : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -3139,7 +3144,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     TRUE, game_timing_state,
diff --git a/net.c b/net.c
index b8fd7e6..667f939 100644 (file)
--- a/net.c
+++ b/net.c
@@ -2864,9 +2864,9 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -3044,7 +3044,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 27a3934..076cad4 100644 (file)
@@ -1826,9 +1826,9 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1879,7 +1879,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 1484587..9e99109 100644 (file)
@@ -238,9 +238,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return FALSE;
+    return 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -291,7 +291,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 4a72acf..043c1de 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -1282,9 +1282,9 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1391,7 +1391,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/pegs.c b/pegs.c
index 195bca1..4daa55f 100644 (file)
--- a/pegs.c
+++ b/pegs.c
@@ -1269,9 +1269,13 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    /*
+     * Dead-end situations are assumed to be rescuable by Undo, so we
+     * don't bother to identify them and return -1.
+     */
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1322,7 +1326,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 1561f4a..593fd38 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -253,7 +253,7 @@ char *midend_get_game_id(midend *me);
 int midend_can_format_as_text_now(midend *me);
 char *midend_text_format(midend *me);
 char *midend_solve(midend *me);
-int midend_is_solved(midend *me);
+int midend_status(midend *me);
 int midend_can_undo(midend *me);
 int midend_can_redo(midend *me);
 void midend_supersede_game_desc(midend *me, char *desc, char *privdesc);
@@ -479,7 +479,7 @@ struct game {
                         game_ui *ui);
     float (*flash_length)(game_state *oldstate, game_state *newstate, int dir,
                          game_ui *ui);
-    int (*is_solved)(game_state *state);
+    int (*status)(game_state *state);
     int can_print, can_print_in_colour;
     void (*print_size)(game_params *params, float *x, float *y);
     void (*print)(drawing *dr, game_state *state, int tilesize);
diff --git a/range.c b/range.c
index 6bdba76..afb2de6 100644 (file)
--- a/range.c
+++ b/range.c
@@ -1485,9 +1485,9 @@ static float game_flash_length(game_state *from, game_state *to,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->was_solved;
+    return state->was_solved ? +1 : 0;
 }
 
 /* ----------------------------------------------------------------------
@@ -1737,7 +1737,7 @@ struct game const thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE, /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/rect.c b/rect.c
index f9ab508..0a93638 100644 (file)
--- a/rect.c
+++ b/rect.c
@@ -2855,9 +2855,9 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2965,7 +2965,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index dc1f380..49dd64e 100644 (file)
@@ -1611,14 +1611,13 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
        return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
     /*
-     * If the player has run out of moves without winning, we don't
-     * list the game as solved, because they're more likely to undo
-     * and carry on than to give up and start a new game.
+     * Dead-end situations are assumed to be rescuable by Undo, so we
+     * don't bother to identify them and return -1.
      */
-    return state->complete;
+    return state->complete ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1669,7 +1668,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index fdeadba..3f2a645 100644 (file)
@@ -2122,9 +2122,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2208,7 +2208,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 2c33337..ff75cfb 100644 (file)
--- a/singles.c
+++ b/singles.c
@@ -1735,9 +1735,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1826,7 +1826,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 6f061cd..8079fac 100644 (file)
--- a/sixteen.c
+++ b/sixteen.c
@@ -1073,9 +1073,9 @@ static float game_flash_length(game_state *oldstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1126,7 +1126,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/slant.c b/slant.c
index f85644c..52f21d6 100644 (file)
--- a/slant.c
+++ b/slant.c
@@ -2079,9 +2079,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2195,7 +2195,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/solo.c b/solo.c
index 8e50c3b..052ebef 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -5187,9 +5187,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -5511,7 +5511,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/tents.c b/tents.c
index 6cf406d..cfdcdc3 100644 (file)
--- a/tents.c
+++ b/tents.c
@@ -2522,9 +2522,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2597,7 +2597,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 94ed1a7..be0a730 100644 (file)
--- a/towers.c
+++ b/towers.c
@@ -1808,9 +1808,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1932,7 +1932,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index c5f89f8..51a21f0 100644 (file)
--- a/twiddle.c
+++ b/twiddle.c
@@ -1069,9 +1069,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
@@ -1291,7 +1291,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 29f0527..5dcca36 100644 (file)
--- a/unequal.c
+++ b/unequal.c
@@ -1865,9 +1865,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1958,7 +1958,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 869ff04..79bd3fa 100644 (file)
@@ -1813,9 +1813,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1936,7 +1936,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 843d99e..51b2ed2 100644 (file)
@@ -1349,9 +1349,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return FALSE;
+    return 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1402,7 +1402,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index b11f604..b20cb52 100644 (file)
@@ -795,9 +795,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return FALSE;
+    return 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -848,7 +848,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index fbaa630..6fac469 100644 (file)
@@ -2292,9 +2292,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -2345,7 +2345,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index b389eb5..53bd3a5 100644 (file)
@@ -1415,9 +1415,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1468,7 +1468,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 7a34475..c07c957 100644 (file)
@@ -1412,9 +1412,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_is_solved(game_state *state)
+static int game_status(game_state *state)
 {
-    return state->completed;
+    return state->completed ? +1 : 0;
 }
 
 static int game_timing_state(game_state *state, game_ui *ui)
@@ -1465,7 +1465,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
-    game_is_solved,
+    game_status,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,