aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2017-09-23 19:22:37 +0100
committerSimon Tatham <anakin@pobox.com>2017-09-23 19:24:16 +0100
commitff218728c6953ede1957ddb5b039bcb2ba920a44 (patch)
treee02d2701b8ec37c234de603ffa8d1595114d050b
parentb8313181a6104624000e9cc008e8e26b67aeb655 (diff)
downloadpuzzles-ff218728c6953ede1957ddb5b039bcb2ba920a44.zip
puzzles-ff218728c6953ede1957ddb5b039bcb2ba920a44.tar.gz
puzzles-ff218728c6953ede1957ddb5b039bcb2ba920a44.tar.bz2
puzzles-ff218728c6953ede1957ddb5b039bcb2ba920a44.tar.xz
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.
-rw-r--r--pattern.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/pattern.c b/pattern.c
index ece1ed4..e5f958a 100644
--- a/pattern.c
+++ b/pattern.c
@@ -308,7 +308,18 @@ static void generate(random_state *rs, int w, int h, unsigned char *retgrid)
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++) {