chiark / gitweb /
Improve connectedness-error highlighting in Singles.
authorSimon Tatham <anakin@pobox.com>
Sun, 21 Sep 2014 15:33:01 +0000 (15:33 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 21 Sep 2014 15:33:01 +0000 (15:33 +0000)
Using exactly the same policy as I did for Range the other day: if
multiple regions exist, then one is taken to be canonical and all the
others are marked as errors.

[originally from svn r10233]

singles.c

index 2aa9a69b7cf82ce8d4a328f218e73811a320fa02..a9b1d9d3b3005de5c5d487a04d980a8f3ec3817b 100644 (file)
--- a/singles.c
+++ b/singles.c
@@ -535,16 +535,28 @@ static int check_complete(game_state *state, unsigned flags)
     for (y = 0; y < h; y++) /* check rows from (0,y) */
         error += check_rowcol(state, y*w, 1, w, flags);
 
-    /* mark (all) white regions as an error if there is more than one.
-     * may want to make this less in-your-face (by only marking
-     * the smallest region as an error, for example -- but what if we
-     * have two regions of identical size?) */
-    for (i = 0; i < state->n; i++) {
-        if (!(state->flags[i] & F_BLACK) &&
-            dsf_size(dsf, i) < nwhite) {
-            error += 1;
-            if (flags & CC_MARK_ERRORS)
-                state->flags[i] |= F_ERROR;
+    /* If there's more than one white region, pick the largest one to
+     * be the canonical one (arbitrarily tie-breaking towards lower
+     * array indices), and mark all the others as erroneous. */
+    {
+        int largest = 0, canonical = -1;
+        for (i = 0; i < state->n; i++)
+            if (!(state->flags[i] & F_BLACK)) {
+                int size = dsf_size(dsf, i);
+                if (largest < size) {
+                    largest = size;
+                    canonical = i;
+                }
+            }
+
+        if (largest < nwhite) {
+            for (i = 0; i < state->n; i++)
+                if (!(state->flags[i] & F_BLACK) &&
+                    dsf_canonify(dsf, i) != canonical) {
+                    error += 1;
+                    if (flags & CC_MARK_ERRORS)
+                        state->flags[i] |= F_ERROR;
+                }
         }
     }