shithub: puzzles

Download patch

ref: ff218728c6953ede1957ddb5b039bcb2ba920a44
parent: b8313181a6104624000e9cc008e8e26b67aeb655
author: Simon Tatham <anakin@pobox.com>
date: Sat Sep 23 15:22:37 EDT 2017

Pattern: randomise rounding bias in generate().

Now, with an odd grid size, we choose the posterisation threshold so
that half the time it delivers ceil(n/2) black squares and half the
time it delivers floor(n/2). Previously it only did the former, which
meant that asking Pattern to generate a 1x1 puzzle (with the bug in
the previous commit fixed) would always generate the one with a single
black square, and never the one with a single white square. Both are
trivial to solve, of course, but it seemed inelegant!

No change to the number of black squares in the puzzle solution can
constitute a spoiler for the player, of course, because that number is
trivial to determine without doing any difficult reasoning, just by
adding up all the clues in one dimension.

--- a/pattern.c
+++ b/pattern.c
@@ -308,7 +308,18 @@
     fgrid2 = snewn(w*h, float);
     memcpy(fgrid2, fgrid, w*h*sizeof(float));
     qsort(fgrid2, w*h, sizeof(float), float_compare);
-    threshold = fgrid2[w*h/2];
+    /* Choose a threshold that makes half the pixels black. In case of
+     * an odd number of pixels, select randomly between just under and
+     * just over half. */
+    {
+        int index = w * h / 2;
+        if (w & h & 1)
+            index += random_upto(rs, 2);
+        if (index < w*h)
+            threshold = fgrid2[index];
+        else
+            threshold = fgrid2[w*h-1] + 1;
+    }
     sfree(fgrid2);
 
     for (i = 0; i < h; i++) {