From ff218728c6953ede1957ddb5b039bcb2ba920a44 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 23 Sep 2017 19:22:37 +0100 Subject: [PATCH] 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. --- pattern.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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++) {