From 67496e74f68db900d8117be6de3c75285c29c489 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 27 Aug 2023 13:22:45 +0100 Subject: 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). --- singles.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/singles.c b/singles.c index a310a4a..98d4b17 100644 --- a/singles.c +++ b/singles.c @@ -1308,9 +1308,10 @@ found: 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) { + game_params *params = dup_params(params_orig); game_state *state = blank_game(params->w, params->h); game_state *tosolve = blank_game(params->w, params->h); 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; 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); rownums = snewn(h*o, int); colnums = snewn(w*o, int); @@ -1412,6 +1419,7 @@ randomise: free_game(tosolve); free_game(state); + free_params(params); solver_state_free(ss); sfree(scratch); sfree(rownums); -- cgit v1.1