chiark / gitweb /
Fix premature completion flash in Tracks.
authorSimon Tatham <anakin@pobox.com>
Fri, 23 Oct 2015 18:33:52 +0000 (19:33 +0100)
committerSimon Tatham <anakin@pobox.com>
Fri, 23 Oct 2015 18:33:52 +0000 (19:33 +0100)
Commit 44e2690ab loosened check_completion's idea of what made a
square count as 'having track in it' for purposes of checking
violations of the row/column counts. Unfortunately, that loosened
notion also applied to the check for the game being complete - so the
game would announce a win as soon as you had every square shaded, even
if you hadn't actually laid all the exact track positions down.

Now we separately count up the number of track-ish squares and the
number of fully completed ones, and use the former for error checking
and the latter for completion checking.

tracks.c

index c6b3d8e148c70787dc917481712ff47cb23a16ef..cecfe7c6616d49530fdb111a34cf59eb0b4f43a1 100644 (file)
--- a/tracks.c
+++ b/tracks.c
@@ -1517,7 +1517,7 @@ static void dsf_update_completion(game_state *state, int *loopclass,
 static int check_completion(game_state *state, int mark)
 {
     int w = state->p.w, h = state->p.h, x, y, i, target, ret = TRUE;
-    int ntrack, nnotrack;
+    int ntrack, nnotrack, ntrackcomplete;
     int *dsf, loopclass, pathclass;
 
     if (mark) {
@@ -1533,14 +1533,20 @@ static int check_completion(game_state *state, int mark)
         }
     }
 
-    /* A cell is 'complete' if it has any edges marked as TRACK. */
+    /* A cell is 'complete', for the purposes of marking the game as
+     * finished, if it has two edges marked as TRACK. But it only has
+     * to have one edge marked as TRACK, or be filled in as trackful
+     * without any specific edges known, to count towards checking
+     * row/column clue errors. */
     for (x = 0; x < w; x++) {
         target = state->numbers->numbers[x];
-        ntrack = nnotrack = 0;
+        ntrack = nnotrack = ntrackcomplete = 0;
         for (y = 0; y < h; y++) {
             if (S_E_COUNT(state, x, y, E_TRACK) > 0 ||
                 state->sflags[y*w+x] & S_TRACK)
                 ntrack++;
+            if (S_E_COUNT(state, x, y, E_TRACK) == 2)
+                ntrackcomplete++;
             if (state->sflags[y*w+x] & S_NOTRACK)
                 nnotrack++;
         }
@@ -1551,16 +1557,18 @@ static int check_completion(game_state *state, int mark)
                 state->num_errors[x] = 1;
             }
         }
-        if (ntrack != target)
+        if (ntrackcomplete != target)
             ret = FALSE;
     }
     for (y = 0; y < h; y++) {
         target = state->numbers->numbers[w+y];
-        ntrack = nnotrack = 0;
+        ntrack = nnotrack = ntrackcomplete = 0;
         for (x = 0; x < w; x++) {
             if (S_E_COUNT(state, x, y, E_TRACK) > 0 ||
                 state->sflags[y*w+x] & S_TRACK)
                 ntrack++;
+            if (S_E_COUNT(state, x, y, E_TRACK) == 2)
+                ntrackcomplete++;
             if (state->sflags[y*w+x] & S_NOTRACK)
                 nnotrack++;
         }
@@ -1571,7 +1579,7 @@ static int check_completion(game_state *state, int mark)
                 state->num_errors[w+y] = 1;
             }
         }
-        if (ntrack != target)
+        if (ntrackcomplete != target)
             ret = FALSE;
     }