Having played Keen a bit following the clue-generation fix in r9165,

I've decided that the extremely low density of one-option
multiplication clues is not a universally good idea after all: it
seems to me to make puzzles _quantitatively_ harder, even if Keen's
difficulty-level system can't see any difference in the set of modes
of reasoning required at least once to solve the grid.

So I've readjusted the clue selection, so that multiplicative clues
with only one workable pair of factors are restored to 'good' status
at Normal difficulty level and below, and only considered less-than-
fully-desirable at Hard and above. I think that's a reasonable
compromise.

[originally from svn r9170]
[r9165 == e7b2a9dd8d8915802fb69ce2242b1f913b7f3172]
This commit is contained in:
Simon Tatham
2011-05-07 13:22:17 +00:00
parent 4a172274f2
commit bd539ae870

43
keen.c
View File

@ -887,13 +887,11 @@ done
* suitable for what. * suitable for what.
*/ */
#define F_ADD 0x01 #define F_ADD 0x01
#define F_ADD_BAD 0x02 #define F_SUB 0x02
#define F_SUB 0x04 #define F_MUL 0x04
#define F_SUB_BAD 0x08 #define F_DIV 0x08
#define F_MUL 0x10 #define BAD_SHIFT 4
#define F_MUL_BAD 0x20
#define F_DIV 0x40
#define F_DIV_BAD 0x80
for (i = 0; i < a; i++) { for (i = 0; i < a; i++) {
singletons[i] = 0; singletons[i] = 0;
j = dsf_canonify(dsf, i); j = dsf_canonify(dsf, i);
@ -917,24 +915,22 @@ done
if (v > 4 && v < 2*w-2) if (v > 4 && v < 2*w-2)
singletons[j] |= F_ADD; singletons[j] |= F_ADD;
else else
singletons[j] |= F_ADD_BAD; singletons[j] |= F_ADD << BAD_SHIFT;
/* /*
* Multiplication clues: similarly, we prefer clues * Multiplication clues: above Normal difficulty, we
* of this type which leave multiple options open. * prefer (but don't absolutely insist on) clues of
* We can't rule out all the others, though, because * this type which leave multiple options open.
* there are very very few 2-square multiplication
* clues that _don't_ leave only one option.
*/ */
v = p * q; v = p * q;
n = 0; n = 0;
for (k = 1; k <= w; k++) for (k = 1; k <= w; k++)
if (v % k == 0 && v / k <= w && v / k != k) if (v % k == 0 && v / k <= w && v / k != k)
n++; n++;
if (n > 2) if (n <= 2 && diff > DIFF_NORMAL)
singletons[j] |= F_MUL; singletons[j] |= F_MUL << BAD_SHIFT;
else else
singletons[j] |= F_MUL_BAD; singletons[j] |= F_MUL;
/* /*
* Subtraction: we completely avoid a difference of * Subtraction: we completely avoid a difference of
@ -976,11 +972,10 @@ done
long clue; long clue;
int good, bad; int good, bad;
switch (k) { switch (k) {
case 0: clue = C_DIV; good = F_DIV; bad = F_DIV_BAD; break; case 0: clue = C_DIV; good = F_DIV; break;
case 1: clue = C_SUB; good = F_SUB; bad = F_SUB_BAD; break; case 1: clue = C_SUB; good = F_SUB; break;
case 2: clue = C_MUL; good = F_MUL; bad = F_MUL_BAD; break; case 2: clue = C_MUL; good = F_MUL; break;
default /* case 3 */ : default /* case 3 */ : clue = C_ADD; good = F_ADD; break;
clue = C_ADD; good = F_ADD; bad = F_ADD_BAD; break;
} }
for (i = 0; i < a; i++) { for (i = 0; i < a; i++) {
@ -993,6 +988,7 @@ done
} }
if (i == a) { if (i == a) {
/* didn't find a nice one, use a nasty one */ /* didn't find a nice one, use a nasty one */
bad = good << BAD_SHIFT;
for (i = 0; i < a; i++) { for (i = 0; i < a; i++) {
j = order[i]; j = order[i];
if (singletons[j] & bad) { if (singletons[j] & bad) {
@ -1010,13 +1006,10 @@ done
break; break;
} }
#undef F_ADD #undef F_ADD
#undef F_ADD_BAD
#undef F_SUB #undef F_SUB
#undef F_SUB_BAD
#undef F_MUL #undef F_MUL
#undef F_MUL_BAD
#undef F_DIV #undef F_DIV
#undef F_DIV_BAD #undef BAD_SHIFT
/* /*
* Having chosen the clue types, calculate the clue values. * Having chosen the clue types, calculate the clue values.