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
if (ox == gx || oy == gy) {
int dx = (gx < ox ? -1 : gx > ox ? +1 : 0);
int dy = (gy < oy ? -1 : gy > oy ? +1 : 0);
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) {
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;
ox += dx;
oy += dy;
ui->dragcoords[ui->ndragcoords++] = oy * w + ox;
if (!INGRID(state, x, y)) goto badmove;
if (l < 0 || l > 15) goto badmove;
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')
if (c == 'L')
ret->lines[y*w + x] |= (char)l;
else if (c == 'N')
else if (c == 'M')
ret->marks[y*w + x] ^= (char)l;
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,
move += n;
} else if (strcmp(move, "H") == 0) {
pearl_solve(ret->shared->w, ret->shared->h,