Singles: prevent hangs at low puzzle sizes.

A user reports that trying to generate a 2x2 or 3x3 puzzle at Tricky
difficulty causes the generator to hang, for the usual reason that
there aren't any - puzzles of that size are either ambiguous or Easy.

The usual response in this code base is to quietly downgrade the
puzzle difficulty when absolutely necessary, so here's some code to do
that (and also for 2x3, which the user didn't test, but unsurprisingly
behaves the same way).
This commit is contained in:
Simon Tatham
2023-08-27 13:22:45 +01:00
parent d3f825c98c
commit 67496e74f6

View File

@ -1308,9 +1308,10 @@ found:
return j; return j;
} }
static char *new_game_desc(const game_params *params, random_state *rs, static char *new_game_desc(const game_params *params_orig, random_state *rs,
char **aux, bool interactive) char **aux, bool interactive)
{ {
game_params *params = dup_params(params_orig);
game_state *state = blank_game(params->w, params->h); game_state *state = blank_game(params->w, params->h);
game_state *tosolve = blank_game(params->w, params->h); game_state *tosolve = blank_game(params->w, params->h);
int i, j, *scratch, *rownums, *colnums, x, y, ntries; int i, j, *scratch, *rownums, *colnums, x, y, ntries;
@ -1319,6 +1320,12 @@ static char *new_game_desc(const game_params *params, random_state *rs,
digit *latin; digit *latin;
struct solver_state *ss = solver_state_new(state); struct solver_state *ss = solver_state_new(state);
/* Downgrade difficulty to Easy for puzzles so tiny that they aren't
* possible to generate at Tricky. These are 2x2, 2x3 and 3x3, i.e.
* any puzzle that doesn't have one dimension at least 4. */
if ((w < 4 || h < 4) && params->diff > DIFF_EASY)
params->diff = DIFF_EASY;
scratch = snewn(state->n, int); scratch = snewn(state->n, int);
rownums = snewn(h*o, int); rownums = snewn(h*o, int);
colnums = snewn(w*o, int); colnums = snewn(w*o, int);
@ -1412,6 +1419,7 @@ randomise:
free_game(tosolve); free_game(tosolve);
free_game(state); free_game(state);
free_params(params);
solver_state_free(ss); solver_state_free(ss);
sfree(scratch); sfree(scratch);
sfree(rownums); sfree(rownums);