chiark / gitweb /
Add a function to every game backend which indicates whether a game
authorSimon Tatham <anakin@pobox.com>
Sat, 2 Apr 2011 16:19:12 +0000 (16:19 +0000)
committerSimon Tatham <anakin@pobox.com>
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?)

[originally from svn r9140]

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 d75c755515ec466f5718a250388fa5f8f1bd27a7..305feac09f2b0269658ea7135b472d909e3d513a 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 f8e9e768fa2820ff7fd6316d943d3f2c0a2ce2a2..0da6b444cd0e333715547fb5820397b17020a57e 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 18787c02687f78916804bb348d116f1ecef0a290..8fa1608780e2b61226e50a2714b2c864374696ce 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 076ef8b1ba37775ab148cdea4c7d96e7bfae184b..571b960391d70008b7a1266a3c217c9578d8a896 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 3a0acd76eef58d416fd25ddefb6b774855bddebc..21d4b67e04585c7113705d8c3d322402e7981a53 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 e74d10a92a5a78873b3cc91c02f559a15a370667..338a993ae255722c703f104ba5f04de97946f716 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 b6d0ed1166629e46afce360e6d64725ef463b830..8b4a7c35342b45deeff29e185ace3d5378ecd8ef 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 d7fbd8e241ef73a69ca0d89e8fcbe142f910cfef..f8b96aebc04b3012b8f46db868d32d8adb99b578 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 55efa94d137097ed06c9cc46edef896d4050f64e..77ef597a1b63ece6af0816f3fde0d19c1148d0f2 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 38cdf25d365582cc085af01170bd743b438c1d0c..a1d984103e5e4d547ccaac89ab6321a284ee2c25 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 0af3f574021a8a8d0c67faa477dae588a414d852..d29a67669d761baf52c3c9fd2340935c4acf8dc5 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 bec505551ff985897e36adf0f59ba2f66e91e9f1..da55fb2084503b4c9a546c6fe3205c6e1ece6d67 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 20e9cecddee09973e0506211db890155ffceef5e..5b97b2b0704d45cfada22938b9ff86c5e3f7bd96 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 37c85d59b94d2f89f8097d7d22c393a4f5e63a3a..5b41d0ad6f2dcb6d0c639243d5d26531f0fc9c5c 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 7af3d86e35bbd49588008c14a09463289714c018..1df2cafeaddcde83562a93987dbd4460db1104d1 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 12cf5078f89d25c0df7f964095b2b80f43861ea1..556a9ec03e77798ada5c3a1bd267a74c745de5bc 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 300e2bf835c9a9bd988372bba3f13b17e263d2e8..0c8b3c003226a71f916b20dd9ebe17c323a9fcf4 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 f6f6a855e38548f2ac48bb18b37d7ca36e305e93..1d72bb2019031fcd5f7a7e2774d524eac58ff090 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 c6226f2aca134c94ca46f8ac0c488f93847062fa..b8fd7e66580d93e4d5c25b7ec53c6a8d836299b5 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 552b728c4f9d2dcc7fddae2568fadc4edc0cc44f..436b786c82b7af54ed05acc3c7a48e27d30be89e 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 118cefe43bc30d64637d36c882c681e4be4fe6a6..1484587982f61bade8a52fe88054779633a75f50 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 544c10b174254afe03dda62df2078e632ee88d2b..4a72acfc19dc1955307e83cf264604c09cff2a39 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 e6e0d27981f149559d3a9e1a30b392c62fad0167..195bca1c3fbd62e41e48056d169c035990779125 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 6933e709e7026960110b8ed897901a07f890d5cb..1561f4a81dea5de88ff215a626e635724cb0f8ec 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 a82acb34593f434fd5f3e892897dd3c314c0645b..9bc28e6abe47036d3a06a8e06f94455392771d3d 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 82256f7d1b610634e4422abb5caa637d088b0f4e..f9ab508eb428529c0e80a24261c6b2d4450603c2 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 5a8c2cbd0cf973327a3f48c15bc6ef596e666093..dc1f380dcc7abe06d1a60fe8f8cfcde8cdff3215 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 fc04c19be3c02158b8b79b308c284b9715b632cc..a9c38f5bf4b0f7209b455efb7ad85e0ba507ed17 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 c20d0cf89c763f16bbd0fe231b2a80c384558b36..2c33337106e2503e76b43d4ee691a20017ff18b4 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 f77b993f1eb31fab827cdd0d480aeadf11b5ed3f..6f061cd84f15397f02c0c6dbcc3217eada282c91 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 35cbd47850b37e2a57dee9b0bcd75216b786df86..f85644c98b8153021e789ba975091953760d6ec2 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 3d3fa8310df07b5440b41dfbd234dfad52ea4f27..52e89cb63a7195cccaac4393c50982b738711499 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 0de5567be210bd1f5c580dfc1d1831555ed1b6bd..2a87248ac1b20f731265f3c318b2f8642fb6fc37 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 e29da015431417d9db8c46eb11f5b2a7066418b2..7beaf87ad988b4e8584e5a052cd91995d825b120 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 36b19e16219eaab446724db288521ddb4a2de365..6acf4cf5337373c9687fa4a277396587268cd259 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 57fbea37f57fdbaf7f390c9f5d0a6c5472a14c16..099f0f84bdab289ed573d0cbf68070bd01656ecb 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 7f7e0a2b97a0259498082ada52ed7303a1012c3b..869ff04bde11d0a7e80063de459c17b6cb2ade0f 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 bd40dba66a9647b2f501fa58f70004a1ab39446e..843d99ea35e8c799c41927a443d52de777814057 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 75f0f43f05b8095d914705ebfe0a0caf069ba5c9..b11f604b5f3eec6af88f01ae48a05b2dd64e1a58 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 634c5dec8a6e685de309e8d7f3914138f28cbaf8..3ea3c951ed0dd96ca541cb74f93d8baec750b797 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 c9cf2dea35c9fb19bc98c91d6709e4396ca30886..b389eb5792c823f6af786dea721baaa631634e45 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 74a5e10076c1684e703f96470417e3b8c1719ce3..7a34475ef9fffce061ea48fdd3574db1b939867f 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,