From f018ef97d34b9126744e63cc2112c302fcae4ab4 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 12 Mar 2023 14:11:34 +0000 Subject: [PATCH] Galaxies: fix recursion depth limit in solver. The static variable 'solver_recurse_depth' is _mostly_ used by the standalone solver, to appropriately indent the solver diagnostics for the current recursion level. So most uses of it are guarded by an '#ifdef STANDALONE_SOLVER' statement, or some equivalent (such as being inside the solvep() macro). One exception is the check that limits the recursion depth to 5, to avoid getting hung up forever on a too-hard game. Unfortunately, this check depends on the variable actually incrementing when we recurse another level - and it wasn't, because the increment itself was under ifdef! So the generator in live Galaxies could recurse arbitrarily deep, and generate puzzles that the standalone solver found too hard _even_ at Unreasonable mode. Removed the ifdefs, so that solver_recurse_depth is now incremented and decremented. Also, make sure to initialise the depth to 0 at the start of a solver run, just in case it had a bogus value left over from a previous run. --- galaxies.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/galaxies.c b/galaxies.c index 0db0d54..fc20b34 100644 --- a/galaxies.c +++ b/galaxies.c @@ -187,6 +187,7 @@ struct game_state { }; static bool check_complete(const game_state *state, int *dsf, int *colours); +static int solver_state_inner(game_state *state, int maxdiff); static int solver_state(game_state *state, int maxdiff); static int solver_obvious(game_state *state); static int solver_obvious_dot(game_state *state, space *dot); @@ -2415,9 +2416,7 @@ static int solver_recurse(game_state *state, int maxdiff) solver_recurse_depth*4, "", rctx.best->x, rctx.best->y, rctx.bestn)); -#ifdef STANDALONE_SOLVER solver_recurse_depth++; -#endif ingrid = snewn(gsz, space); memcpy(ingrid, state->grid, gsz * sizeof(space)); @@ -2432,7 +2431,7 @@ static int solver_recurse(game_state *state, int maxdiff) state->dots[n]->x, state->dots[n]->y, "Attempting for recursion"); - ret = solver_state(state, maxdiff); + ret = solver_state_inner(state, maxdiff); if (diff == DIFF_IMPOSSIBLE && ret != DIFF_IMPOSSIBLE) { /* we found our first solved grid; copy it away. */ @@ -2464,9 +2463,7 @@ static int solver_recurse(game_state *state, int maxdiff) break; } -#ifdef STANDALONE_SOLVER solver_recurse_depth--; -#endif if (outgrid) { /* we found (at least one) soln; copy it back to state */ @@ -2477,7 +2474,7 @@ static int solver_recurse(game_state *state, int maxdiff) return diff; } -static int solver_state(game_state *state, int maxdiff) +static int solver_state_inner(game_state *state, int maxdiff) { solver_ctx *sctx = new_solver(state); int ret, diff = DIFF_NORMAL; @@ -2544,6 +2541,12 @@ got_result: return diff; } +static int solver_state(game_state *state, int maxdiff) +{ + solver_recurse_depth = 0; + return solver_state_inner(state, maxdiff); +} + #ifndef EDITOR static char *solve_game(const game_state *state, const game_state *currstate, const char *aux, const char **error)