Add a function to every game backend which indicates whether a game
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 2 Apr 2011 16:19:12 +0000 (16:19 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 2 Apr 2011 16:19:12 +0000 (16:19 +0000)
state is in a solved position, and a midend function wrapping it.

(Or, at least, a situation in which further play is pointless. The
point is, given that game state, would it be a good idea for a front
end that does that sort of thing to proactively provide the option to
start a fresh game?)

git-svn-id: svn://svn.tartarus.org/sgt/puzzles@9140 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 d75c755..305feac 100644 (file)
@@ -1462,6 +1462,15 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
+static int game_is_solved(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;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1510,6 +1519,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index f8e9e76..0da6b44 100644 (file)
--- a/bridges.c
+++ b/bridges.c
@@ -2715,6 +2715,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2818,6 +2823,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/cube.c b/cube.c
index 18787c0..8fa1608 100644 (file)
--- a/cube.c
+++ b/cube.c
@@ -1710,6 +1710,11 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1758,6 +1763,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 076ef8b..571b960 100644 (file)
--- a/devel.but
+++ b/devel.but
@@ -1224,6 +1224,28 @@ 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()}
+
+\c int (*is_solved)(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}).
+
+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 TRUE in situations where the game is \e{lost} as well as
+won, if losing makes it unlikely that the player would play on.
+
+(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.)
+
 \S{backend-redraw} \cw{redraw()}
 
 \c void (*redraw)(drawing *dr, game_drawstate *ds,
@@ -3096,6 +3118,19 @@ The front end can expect its drawing API and/or
 \cw{activate_timer()} to be called from within a call to this
 function.
 
+\S{midend-is-solved} \cw{midend_is_solved()}
+
+\c int midend_is_solved(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()}
+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).
+
 \H{midend-can-undo} \cw{midend_can_undo()}
 
 \c int midend_can_undo(midend *me);
index 3a0acd7..21d4b67 100644 (file)
@@ -1535,6 +1535,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1623,6 +1628,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index e74d10a..338a993 100644 (file)
--- a/fifteen.c
+++ b/fifteen.c
@@ -830,6 +830,11 @@ static float game_flash_length(game_state *oldstate,
         return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -878,6 +883,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index b6d0ed1..8b4a7c3 100644 (file)
--- a/filling.c
+++ b/filling.c
@@ -1617,6 +1617,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1715,6 +1720,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                                /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/flip.c b/flip.c
index d7fbd8e..f8b96ae 100644 (file)
--- a/flip.c
+++ b/flip.c
@@ -1251,6 +1251,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1299,6 +1304,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 55efa94..77ef597 100644 (file)
@@ -3348,6 +3348,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -3568,6 +3573,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
 #ifdef EDITOR
     FALSE, FALSE, NULL, NULL,
     TRUE,                              /* wants_statusbar */
diff --git a/guess.c b/guess.c
index 38cdf25..a1d9841 100644 (file)
--- a/guess.c
+++ b/guess.c
@@ -1314,6 +1314,18 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(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.
+     */
+    return state->solved;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1362,6 +1374,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 0af3f57..d29a676 100644 (file)
--- a/inertia.c
+++ b/inertia.c
@@ -2135,6 +2135,16 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(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.
+     */
+    return !state->gems;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2183,6 +2193,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/keen.c b/keen.c
index bec5055..da55fb2 100644 (file)
--- a/keen.c
+++ b/keen.c
@@ -2013,6 +2013,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     if (state->completed)
@@ -2289,6 +2294,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 20e9cec..5b97b2b 100644 (file)
--- a/lightup.c
+++ b/lightup.c
@@ -2160,6 +2160,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2262,6 +2267,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/loopy.c b/loopy.c
index 37c85d5..5b41d0a 100644 (file)
--- a/loopy.c
+++ b/loopy.c
@@ -3834,6 +3834,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->solved;
+}
+
 static void game_print_size(game_params *params, float *x, float *y)
 {
     int pw, ph;
@@ -3960,6 +3965,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE /* wants_statusbar */,
     FALSE, game_timing_state,
index 7af3d86..1df2caf 100644 (file)
--- a/magnets.c
+++ b/magnets.c
@@ -2235,6 +2235,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2374,6 +2379,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/map.c b/map.c
index 12cf507..556a9ec 100644 (file)
--- a/map.c
+++ b/map.c
@@ -3025,6 +3025,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
        return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -3218,6 +3223,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, TRUE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 300e2bf..0c8b3c0 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -1336,6 +1336,21 @@ char *midend_solve(midend *me)
     return NULL;
 }
 
+int midend_is_solved(midend *me)
+{
+    /*
+     * We should probably never be called when the state stack has no
+     * states on it at all - ideally, midends should never be left in
+     * that state for long enough to get put down and forgotten about.
+     * But if we are, I think we return _true_ - pedantically speaking
+     * a midend in that state is 'vacuously solved', and more
+     * 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));
+}
+
 char *midend_rewrite_statusbar(midend *me, char *text)
 {
     /*
diff --git a/mines.c b/mines.c
index f6f6a85..1d72bb2 100644 (file)
--- a/mines.c
+++ b/mines.c
@@ -3084,6 +3084,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->won;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     if (state->dead || state->won || ui->completed || !state->layout->mines)
@@ -3134,6 +3139,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     TRUE, game_timing_state,
diff --git a/net.c b/net.c
index c6226f2..b8fd7e6 100644 (file)
--- a/net.c
+++ b/net.c
@@ -2864,6 +2864,11 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -3039,6 +3044,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 552b728..436b786 100644 (file)
@@ -1829,6 +1829,11 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return FALSE;
@@ -1877,6 +1882,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 118cefe..1484587 100644 (file)
@@ -238,6 +238,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return FALSE;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -286,6 +291,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 544c10b..4a72acf 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -1282,6 +1282,11 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1386,6 +1391,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/pegs.c b/pegs.c
index e6e0d27..195bca1 100644 (file)
--- a/pegs.c
+++ b/pegs.c
@@ -1269,6 +1269,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1317,6 +1322,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 6933e70..1561f4a 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -253,6 +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_can_undo(midend *me);
 int midend_can_redo(midend *me);
 void midend_supersede_game_desc(midend *me, char *desc, char *privdesc);
@@ -478,6 +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 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 a82acb3..9bc28e6 100644 (file)
--- a/range.c
+++ b/range.c
@@ -1480,6 +1480,11 @@ static float game_flash_length(game_state *from, game_state *to,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->was_solved;
+}
+
 /* ----------------------------------------------------------------------
  * Drawing routines.
  */
@@ -1727,6 +1732,7 @@ struct game const thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE, /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/rect.c b/rect.c
index 82256f7..f9ab508 100644 (file)
--- a/rect.c
+++ b/rect.c
@@ -2855,6 +2855,11 @@ static float game_flash_length(game_state *oldstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2960,6 +2965,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 5a8c2cb..dc1f380 100644 (file)
@@ -1611,6 +1611,16 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
        return 0.0F;
 }
 
+static int game_is_solved(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.
+     */
+    return state->complete;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1659,6 +1669,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index fc04c19..a9c38f5 100644 (file)
@@ -2122,6 +2122,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2203,6 +2208,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index c20d0cf..2c33337 100644 (file)
--- a/singles.c
+++ b/singles.c
@@ -1735,6 +1735,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1821,6 +1826,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index f77b993..6f061cd 100644 (file)
--- a/sixteen.c
+++ b/sixteen.c
@@ -1073,6 +1073,11 @@ static float game_flash_length(game_state *oldstate,
         return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1121,6 +1126,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/slant.c b/slant.c
index 35cbd47..f85644c 100644 (file)
--- a/slant.c
+++ b/slant.c
@@ -2079,6 +2079,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2190,6 +2195,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/solo.c b/solo.c
index 3d3fa83..52e89cb 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -5169,6 +5169,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     if (state->completed)
@@ -5488,6 +5493,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
diff --git a/tents.c b/tents.c
index 0de5567..2a87248 100644 (file)
--- a/tents.c
+++ b/tents.c
@@ -2524,6 +2524,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2594,6 +2599,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index e29da01..7beaf87 100644 (file)
--- a/towers.c
+++ b/towers.c
@@ -1809,6 +1809,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     if (state->completed)
@@ -1928,6 +1933,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 36b19e1..6acf4cf 100644 (file)
--- a/twiddle.c
+++ b/twiddle.c
@@ -1070,6 +1070,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
                        game_state *state, int dir, game_ui *ui,
                        float animtime, float flashtime)
@@ -1287,6 +1292,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index 57fbea3..099f0f8 100644 (file)
--- a/unequal.c
+++ b/unequal.c
@@ -1864,6 +1864,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1952,6 +1957,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 7f7e0a2..869ff04 100644 (file)
@@ -1813,6 +1813,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     if (state->completed)
@@ -1931,6 +1936,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index bd40dba..843d99e 100644 (file)
@@ -1349,6 +1349,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return FALSE;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1397,6 +1402,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 75f0f43..b11f604 100644 (file)
@@ -795,6 +795,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return FALSE;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -843,6 +848,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 634c5de..3ea3c95 100644 (file)
@@ -2293,6 +2293,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2341,6 +2346,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     TRUE,                             /* wants_statusbar */
     FALSE, game_timing_state,
index c9cf2de..b389eb5 100644 (file)
@@ -1415,6 +1415,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
         return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1463,6 +1468,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,
index 74a5e10..7a34475 100644 (file)
@@ -1412,6 +1412,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_is_solved(game_state *state)
+{
+    return state->completed;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -1460,6 +1465,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_is_solved,
     FALSE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,