mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
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'. [originally from svn r9400]
This commit is contained in:
21
pearl.c
21
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) {
|
if (ox == gx || oy == gy) {
|
||||||
int dx = (gx < ox ? -1 : gx > ox ? +1 : 0);
|
int dx = (gx < ox ? -1 : gx > ox ? +1 : 0);
|
||||||
int dy = (gy < oy ? -1 : gy > oy ? +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) {
|
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;
|
ox += dx;
|
||||||
oy += dy;
|
oy += dy;
|
||||||
ui->dragcoords[ui->ndragcoords++] = oy * w + ox;
|
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 (!INGRID(state, x, y)) goto badmove;
|
||||||
if (l < 0 || l > 15) 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')
|
if (c == 'L')
|
||||||
ret->lines[y*w + x] |= (char)l;
|
ret->lines[y*w + x] |= (char)l;
|
||||||
else if (c == 'N')
|
else if (c == 'N')
|
||||||
@ -2052,6 +2057,16 @@ static game_state *execute_move(game_state *state, char *move)
|
|||||||
else if (c == 'M')
|
else if (c == 'M')
|
||||||
ret->marks[y*w + x] ^= (char)l;
|
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;
|
move += n;
|
||||||
} else if (strcmp(move, "H") == 0) {
|
} else if (strcmp(move, "H") == 0) {
|
||||||
pearl_solve(ret->shared->w, ret->shared->h,
|
pearl_solve(ret->shared->w, ret->shared->h,
|
||||||
|
Reference in New Issue
Block a user