From 97b03cc67a31c1d0869a21c50b9ca31f78775ff9 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sat, 11 Feb 2023 22:49:36 +0000 Subject: [PATCH] Don't allow moves that change the constraints in Unequal Unequal has a flags word per cell. Some of those flags are fixed, like the locations of the ">" signs, but others indicate errors and are used to allow the player to mark clues as "spent". Move strings beginning with "F" allow the user to change the "spent" flags, but they shouldn't allow the user to change any other flags, especially those marking the constraints. Without this fix, the following save file gives a "solver_nminmax: Assertion `x >= 0 && y >= 0 && x < o && y < o' failed" after it adds a clue that points off the board: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection GAME :7:Unequal PARAMS :3:3e0 CPARAMS :3:3e0 DESC :17:0,0,0,0,0,0,0,0,0 NSTATES :2:3 STATEPOS:1:3 MOVE :6:F2,0,4 MOVE :1:H --- unequal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unequal.c b/unequal.c index 52041bb..e0e08a1 100644 --- a/unequal.c +++ b/unequal.c @@ -84,6 +84,7 @@ struct game_params { #define ADJ_TO_SPENT(x) ((x) << 9) #define F_ERROR_MASK (F_ERROR|F_ERROR_UP|F_ERROR_RIGHT|F_ERROR_DOWN|F_ERROR_LEFT) +#define F_SPENT_MASK (F_SPENT_UP|F_SPENT_RIGHT|F_SPENT_DOWN|F_SPENT_LEFT) struct game_state { int order; @@ -1706,7 +1707,8 @@ static game_state *execute_move(const game_state *state, const char *move) check_complete(ret->nums, ret, true); return ret; } else if (move[0] == 'F' && sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 && - x >= 0 && x < state->order && y >= 0 && y < state->order) { + x >= 0 && x < state->order && y >= 0 && y < state->order && + (n & ~F_SPENT_MASK) == 0) { ret = dup_game(state); GRID(ret, flags, x, y) ^= n; return ret;