shithub: puzzles

Download patch

ref: b4aaa11943fb72b09fe173bc97bd9313ff94738c
parent: b5e02b0b9c1b35b0b907bf6d63e62b9fafd9cb7e
author: Simon Tatham <[email protected]>
date: Thu Jan 19 07:47:55 EST 2023

Tracks: tighten up the 'illegal solve submoves' fix.

Chris mentioned in the commit message that there was a risk that
illegal moves might be permitted when playing on after a solve. So
I've changed the condition so that it depends only on whether the move
_currently being executed_ is a solve, rather than whether there was a
solve action anywhere in the undo history.

(Also, wrapped overlong lines while I was here.)

--- a/tracks.c
+++ b/tracks.c
@@ -2408,6 +2408,7 @@
     int w = state->p.w, x, y, n, i;
     char c, d;
     unsigned f;
+    bool move_is_solve = false;
     game_state *ret = dup_game(state);
 
     /* this is breaking the bank on GTK, which vsprintf's into a fixed-size buffer
@@ -2418,6 +2419,7 @@
         c = *move;
         if (c == 'S') {
             ret->used_solve = true;
+            move_is_solve = true;
             move++;
         } else if (c == 'T' || c == 't' || c == 'N' || c == 'n') {
             /* set track, clear track; set notrack, clear notrack */
@@ -2429,7 +2431,8 @@
             f = (c == 'T' || c == 't') ? S_TRACK : S_NOTRACK;
 
             if (d == 'S') {
-                if (!ui_can_flip_square(ret, x, y, f == S_NOTRACK) && !ret->used_solve)
+                if (!ui_can_flip_square(ret, x, y, f == S_NOTRACK) &&
+                    !move_is_solve)
                     goto badmove;
                 if (c == 'T' || c == 'N')
                     ret->sflags[y*w+x] |= f;
@@ -2440,7 +2443,8 @@
                     unsigned df = 1<<i;
 
                     if (MOVECHAR(df) == d) {
-                        if (!ui_can_flip_edge(ret, x, y, df, f == S_NOTRACK) && !ret->used_solve)
+                        if (!ui_can_flip_edge(ret, x, y, df, f == S_NOTRACK) &&
+                            !move_is_solve)
                             goto badmove;
                         if (c == 'T' || c == 'N')
                             S_E_SET(ret, x, y, df, f);