From f335fd5185bf40dfcf147826299d04ba84cc083a Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 2 Feb 2012 07:18:14 +0000 Subject: [PATCH] David Nickerson reports that it's possible to lay a line over a 'no line here' cross mark by dragging, and furthermore, that doing so puts that grid edge into a stuck state that no UI action short of undo can get it back out of. Fix drags to stop at crosses, and fix execute_move to fault any move string that nonetheless somehow managed to try to set a line over a cross without explicitly tagging it 'R'. git-svn-id: svn://svn.tartarus.org/sgt/puzzles@9400 cda61777-01e9-0310-a592-d414129be87e --- pearl.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/pearl.c b/pearl.c index 248d64e..fe6b9c3 100644 --- a/pearl.c +++ b/pearl.c @@ -1836,7 +1836,15 @@ static void update_ui_drag(game_state *state, game_ui *ui, int gx, int gy) if (ox == gx || oy == gy) { int dx = (gx < ox ? -1 : gx > ox ? +1 : 0); int dy = (gy < oy ? -1 : gy > oy ? +1 : 0); + int dir = (dy>0 ? D : dy<0 ? U : dx>0 ? R : L); while (ox != gx || oy != gy) { + /* + * If the drag attempts to cross a 'no line here' mark, + * stop there. We physically don't allow the user to drag + * over those marks. + */ + if (state->marks[oy*w+ox] & dir) + break; ox += dx; oy += dy; ui->dragcoords[ui->ndragcoords++] = oy * w + ox; @@ -2037,9 +2045,6 @@ static game_state *execute_move(game_state *state, char *move) if (!INGRID(state, x, y)) goto badmove; if (l < 0 || l > 15) goto badmove; - /* TODO trying to set a line over a no-line mark should be - * a failed move? */ - if (c == 'L') ret->lines[y*w + x] |= (char)l; else if (c == 'N') @@ -2052,6 +2057,16 @@ static game_state *execute_move(game_state *state, char *move) else if (c == 'M') ret->marks[y*w + x] ^= (char)l; + /* + * If we ended up trying to lay a line _over_ a mark, + * that's a failed move: interpret_move() should have + * ensured we never received a move string like that in + * the first place. + */ + if ((ret->lines[y*w + x] & (char)l) && + (ret->marks[y*w + x] & (char)l)) + goto badmove; + move += n; } else if (strcmp(move, "H") == 0) { pearl_solve(ret->shared->w, ret->shared->h, -- 2.11.0