chiark / gitweb /
Introduce a new game backend function (there seem to have been a lot
authorSimon Tatham <anakin@pobox.com>
Mon, 6 Jun 2005 11:21:36 +0000 (11:21 +0000)
committerSimon Tatham <anakin@pobox.com>
Mon, 6 Jun 2005 11:21:36 +0000 (11:21 +0000)
of these recently) whose job is to update a game_ui to be consistent
with a new game_state. This is called by midend.c in every situation
where the current game_state changes _other_ than as a result of
make_move (Undo, Redo, Restart, Solve).

The introduction of this function allows a game_ui to contain
information about selections or highlights within a game_state which
simply wouldn't make sense when transferred to another game_state.
In particular, I've used it to fix a subtle bug in Solo whereby,
although you couldn't right-click to pencil-mode highlight a filled
square, you could _get_ a pencil-mode highlight in a filled square
if you used Undo and Redo. (Undo to before the square was filled,
right-click to highlight it, then Redo. Alternatively, left-click
and clear the square, right-click to highlight it, then Undo.)

[originally from svn r5912]

13 files changed:
cube.c
fifteen.c
midend.c
mines.c
net.c
netslide.c
nullgame.c
pattern.c
puzzles.h
rect.c
sixteen.c
solo.c
twiddle.c

diff --git a/cube.c b/cube.c
index 0ff952fc97b3a6f76d9acce5ddb98f1b4f24a47f..ffefa2f17e20950d5b75dcad1df99ced6809113d 100644 (file)
--- a/cube.c
+++ b/cube.c
@@ -1003,6 +1003,11 @@ static void free_ui(game_ui *ui)
 {
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 struct game_drawstate {
     int ox, oy;                        /* pixel position of float origin */
 };
@@ -1637,6 +1642,7 @@ const struct game thegame = {
     FALSE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index bf2cdf1ad279aacc9b1bb0628a0448a2843a6ec1..a6402c9a912f4754e8790391fc4d07376415ccfa 100644 (file)
--- a/fifteen.c
+++ b/fifteen.c
@@ -451,6 +451,11 @@ static void free_ui(game_ui *ui)
 {
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button) {
     int gx, gy, dx, dy, ux, uy, up, p;
@@ -835,6 +840,7 @@ const struct game thegame = {
     TRUE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index b6b17207fcc4d487ce5a7ed3fc96e1e8c6c3351b..d8960a7b6eea2e50aa249d5253976b2f8c0e0dd6 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -228,6 +228,10 @@ void midend_new_game(midend_data *me)
 static int midend_undo(midend_data *me)
 {
     if (me->statepos > 1) {
+        if (me->ui)
+            me->ourgame->changed_state(me->ui,
+                                       me->states[me->statepos-1].state,
+                                       me->states[me->statepos-2].state);
        me->statepos--;
         me->dir = -1;
         return 1;
@@ -238,6 +242,10 @@ static int midend_undo(midend_data *me)
 static int midend_redo(midend_data *me)
 {
     if (me->statepos < me->nstates) {
+        if (me->ui)
+            me->ourgame->changed_state(me->ui,
+                                       me->states[me->statepos-1].state,
+                                       me->states[me->statepos].state);
        me->statepos++;
         me->dir = +1;
         return 1;
@@ -308,6 +316,10 @@ void midend_restart_game(midend_data *me)
     me->states[me->nstates].state = s;
     me->states[me->nstates].special = TRUE;   /* we just restarted */
     me->statepos = ++me->nstates;
+    if (me->ui)
+        me->ourgame->changed_state(me->ui,
+                                   me->states[me->statepos-2].state,
+                                   me->states[me->statepos-1].state);
     me->anim_time = 0.0;
     midend_finish_move(me);
     midend_redraw(me);
@@ -936,6 +948,10 @@ char *midend_solve(midend_data *me)
     me->states[me->nstates].state = s;
     me->states[me->nstates].special = TRUE;   /* created using solve */
     me->statepos = ++me->nstates;
+    if (me->ui)
+        me->ourgame->changed_state(me->ui,
+                                   me->states[me->statepos-2].state,
+                                   me->states[me->statepos-1].state);
     me->anim_time = 0.0;
     midend_finish_move(me);
     midend_redraw(me);
diff --git a/mines.c b/mines.c
index 4b9620e080b692a39240cfbaa191b1e0973941b3..286f76d614b387f0234c0bca75db7cd5fce4bd69 100644 (file)
--- a/mines.c
+++ b/mines.c
@@ -2475,6 +2475,11 @@ static void free_ui(game_ui *ui)
     sfree(ui);
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button)
 {
@@ -3044,6 +3049,7 @@ const struct game thegame = {
     TRUE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
diff --git a/net.c b/net.c
index 8a4f706052fccadbc9e17461f6329d92cf3e52b8..fe9b846af6b5118e71ca08d74b4490b19d974400 100644 (file)
--- a/net.c
+++ b/net.c
@@ -1786,6 +1786,11 @@ static void free_ui(game_ui *ui)
     sfree(ui);
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 /* ----------------------------------------------------------------------
  * Process a move.
  */
@@ -2591,6 +2596,7 @@ const struct game thegame = {
     FALSE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index 0ab3e3432b27b116af9a16bb0c0d996a9765cd61..e6751fe66048bde237e1f04d14dee47a54cc82dd 100644 (file)
@@ -1045,6 +1045,11 @@ static void slide_col(game_state *state, int dir, int col)
     slide_col_int(state->width, state->height, state->tiles, dir, col);
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *state, game_ui *ui,
                              game_drawstate *ds, int x, int y, int button)
 {
@@ -1749,6 +1754,7 @@ const struct game thegame = {
     FALSE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index 49173b6d0c2fadd5025e33368d7e1421ecdfaea8..3bcfe4633b1347880d0141472bc3906d493b485d 100644 (file)
@@ -142,6 +142,11 @@ static void free_ui(game_ui *ui)
 {
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button)
 {
@@ -244,6 +249,7 @@ const struct game thegame = {
     FALSE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index f8e8fc54b40d5b4349833ba0f38a11bdab06a916..dd8626ab2d79534c192be8170aa7291bc170f013 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -758,6 +758,11 @@ static void free_ui(game_ui *ui)
     sfree(ui);
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button) {
     game_state *ret;
@@ -1127,6 +1132,7 @@ const struct game thegame = {
     FALSE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index fbef531a32bd6fc795af97cd0116c0e60f68cb9d..1451f12fd18fc4650346367ced6befe107582da0 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -252,6 +252,8 @@ struct game {
     char *(*text_format)(game_state *state);
     game_ui *(*new_ui)(game_state *state);
     void (*free_ui)(game_ui *ui);
+    void (*changed_state)(game_ui *ui, game_state *oldstate,
+                          game_state *newstate);
     game_state *(*make_move)(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button);
     void (*size)(game_params *params, int *x, int *y);
diff --git a/rect.c b/rect.c
index 0448958925f80da18ebd2b65993708ecc5e7a794..c040efaa78552a0921076f3393c9a6de12c2c452 100644 (file)
--- a/rect.c
+++ b/rect.c
@@ -2183,6 +2183,11 @@ static void ui_draw_rect(game_state *state, game_ui *ui,
             }
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button) {
     int xc, yc;
@@ -2549,6 +2554,7 @@ const struct game thegame = {
     TRUE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index feab05dcd3357f66ae4eb7ede3039d49852f6435..9a347fa9153bab0d2f9b544d671cc630c4409ea8 100644 (file)
--- a/sixteen.c
+++ b/sixteen.c
@@ -578,6 +578,11 @@ static void free_ui(game_ui *ui)
 {
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button) {
     int cx, cy;
@@ -1006,6 +1011,7 @@ const struct game thegame = {
     TRUE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
diff --git a/solo.c b/solo.c
index 97acf76841a6e259efc1c27de4bc73c2a4a382e9..922f748e84957a809be11a001093aeefa2cb31b8 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -1853,6 +1853,22 @@ static void free_ui(game_ui *ui)
     sfree(ui);
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+    int c = newstate->c, r = newstate->r, cr = c*r;
+    /*
+     * We prevent pencil-mode highlighting of a filled square. So
+     * if the user has just filled in a square which we had a
+     * pencil-mode highlight in (by Undo, or by Redo, or by Solve),
+     * then we cancel the highlight.
+     */
+    if (ui->hx >= 0 && ui->hy >= 0 && ui->hpencil &&
+        newstate->grid[ui->hy * cr + ui->hx] != 0) {
+        ui->hx = ui->hy = -1;
+    }
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button)
 {
@@ -2278,6 +2294,7 @@ const struct game thegame = {
     TRUE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,
index 9ac4a3a5e8444ab7cb31b512082bea2fe0f1aeaa..b5548793e9c5479a537746b0f9d03315a88f9483 100644 (file)
--- a/twiddle.c
+++ b/twiddle.c
@@ -616,6 +616,11 @@ static void free_ui(game_ui *ui)
 {
 }
 
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+                               game_state *newstate)
+{
+}
+
 static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                              int x, int y, int button)
 {
@@ -1174,6 +1179,7 @@ const struct game thegame = {
     TRUE, game_text_format,
     new_ui,
     free_ui,
+    game_changed_state,
     make_move,
     game_size,
     game_colours,