chiark / gitweb /
Adjust Keen's grid generation to constrain the maximum size of clue
authorSimon Tatham <anakin@pobox.com>
Fri, 12 Apr 2013 16:28:53 +0000 (16:28 +0000)
committerSimon Tatham <anakin@pobox.com>
Fri, 12 Apr 2013 16:28:53 +0000 (16:28 +0000)
blocks, because 'make test' showed up very large blocks as an
occasional slowdown factor in game generation (takes too long to
iterate over all possibilities). This is a good idea in any case,
because really big multiplicative clue numbers have trouble fitting in
the square.

[originally from svn r9827]

keen.c

diff --git a/keen.c b/keen.c
index 5087465ef675accee91070f4db5074b8686f06b9..e951dbabd7de26876134888f473f3dc10acc7cd9 100644 (file)
--- a/keen.c
+++ b/keen.c
@@ -42,6 +42,14 @@ static char const keen_diffchars[] = DIFFLIST(ENCODE);
 #define CMASK 0x60000000L
 #define CUNIT 0x20000000L
 
+/*
+ * Maximum size of any clue block. Very large ones are annoying in UI
+ * terms (if they're multiplicative you end up with too many digits to
+ * fit in the square) and also in solver terms (too many possibilities
+ * to iterate over).
+ */
+#define MAXBLK 6
+
 enum {
     COL_BACKGROUND,
     COL_GRID,
@@ -847,26 +855,34 @@ done
                x = i % w;
                y = i / w;
 
-               if (x > 0 &&
+               if (x > 0 && dsf_size(dsf, i-1) < MAXBLK &&
                    (best == -1 || revorder[i-1] < revorder[best]))
                    best = i-1;
-               if (x+1 < w &&
+               if (x+1 < w && dsf_size(dsf, i+1) < MAXBLK &&
                    (best == -1 || revorder[i+1] < revorder[best]))
                    best = i+1;
-               if (y > 0 &&
+               if (y > 0 && dsf_size(dsf, i-w) < MAXBLK &&
                    (best == -1 || revorder[i-w] < revorder[best]))
                    best = i-w;
-               if (y+1 < w &&
+               if (y+1 < w && dsf_size(dsf, i+w) < MAXBLK &&
                    (best == -1 || revorder[i+w] < revorder[best]))
                    best = i+w;
 
                if (best >= 0) {
-                   singletons[i] = FALSE;
+                   singletons[i] = singletons[best] = FALSE;
                    dsf_merge(dsf, i, best);
                }
            }
        }
 
+        /* Quit and start again if we have any singletons left over
+         * which we weren't able to do anything at all with. */
+       for (i = 0; i < a; i++)
+           if (singletons[i])
+                break;
+        if (i < a)
+            continue;
+
        /*
         * Decide what would be acceptable clues for each block.
         *