mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Avoid invalid moves when solving Tracks
The solver, when it decided that an edge or square should be both TRACK and NOTRACK, would correctly decide that the puzzle was insoluble, but would also mark the edge with both flags in its working copy. This could then lead to assertion violations if that working copy of the board was used for something else, for instance if it was fed back into the solver. This couldn't happen in normal play, since failed solutions just cause the solve command to fail, but the diagnostic "H" command could trigger it from a save file, causing an assertion failure: "state->sflags[y*state->p.w + x] & S_CLUE". Now when the solver runs into this situation, it marks the puzzle as insoluble but doesn't set the invalid flag, so the board remains valid and future solve operations are safe. This save file is the one that demonstrated the problem: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection GAME :12:Train Tracks PARAMS :5:6x6t0 CPARAMS :5:6x6t0 DESC :31:b0t9l,,S0,00,0,0,4,0,0,S0,0,0,0 NSTATES :1:8 STATEPOS:1:2 MOVE :1:H MOVE :1:H MOVE :1:H MOVE :1:H MOVE :1:H MOVE :1:H MOVE :1:H
This commit is contained in:
8
tracks.c
8
tracks.c
@ -925,8 +925,8 @@ static int solve_set_sflag(game_state *state, int x, int y,
|
||||
if (state->sflags[i] & (f == S_TRACK ? S_NOTRACK : S_TRACK)) {
|
||||
solverdebug(("opposite flag already set there, marking IMPOSSIBLE"));
|
||||
state->impossible = true;
|
||||
}
|
||||
state->sflags[i] |= f;
|
||||
} else
|
||||
state->sflags[i] |= f;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -943,8 +943,8 @@ static int solve_set_eflag(game_state *state, int x, int y, int d,
|
||||
if (sf & (f == E_TRACK ? E_NOTRACK : E_TRACK)) {
|
||||
solverdebug(("opposite flag already set there, marking IMPOSSIBLE"));
|
||||
state->impossible = true;
|
||||
}
|
||||
S_E_SET(state, x, y, d, f);
|
||||
} else
|
||||
S_E_SET(state, x, y, d, f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user