aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2023-08-27 13:22:45 +0100
committerSimon Tatham <anakin@pobox.com>2023-08-27 13:26:01 +0100
commit67496e74f68db900d8117be6de3c75285c29c489 (patch)
tree265f13ad10fe4ce19e9f24a85f5ea6153cfbc95c
parentd3f825c98c2877ca3e2763492ba99973c1b9dc5f (diff)
downloadpuzzles-67496e74f68db900d8117be6de3c75285c29c489.zip
puzzles-67496e74f68db900d8117be6de3c75285c29c489.tar.gz
puzzles-67496e74f68db900d8117be6de3c75285c29c489.tar.bz2
puzzles-67496e74f68db900d8117be6de3c75285c29c489.tar.xz
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).
-rw-r--r--singles.c10
1 files changed, 9 insertions, 1 deletions
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);