From bc930a121466e0e33b46ff01db0153f5cfb79054 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 21 Sep 2014 15:33:01 +0000 Subject: [PATCH] Improve connectedness-error highlighting in Singles. 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 | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/singles.c b/singles.c index 2aa9a69..a9b1d9d 100644 --- 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; + } } }