aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pearl.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/pearl.c b/pearl.c
index 3c2e81c..b3b8249 100644
--- a/pearl.c
+++ b/pearl.c
@@ -1891,6 +1891,11 @@ struct game_drawstate {
char *draglines; /* size w*h; lines flipped by current drag */
};
+static void interpret_ui_drag(const game_state *state, const game_ui *ui,
+ bool *clearing, int i, int *sx, int *sy,
+ int *dx, int *dy, int *dir,
+ int *oldstate, int *newstate);
+
static void update_ui_drag(const game_state *state, game_ui *ui,
int gx, int gy)
{
@@ -1919,13 +1924,42 @@ static void update_ui_drag(const game_state *state, game_ui *ui,
* the drag path so far has the effect of truncating the path back
* to that square, so a player can back out part of an uncommitted
* drag without having to let go of the mouse.
+ *
+ * An exception is that you're allowed to drag round in a loop
+ * back to the very start of the drag, provided that doesn't
+ * create a vertex of the wrong degree. This allows a player who's
+ * after an extra challenge to draw the entire loop in a single
+ * drag, without it cancelling itself just before release.
*/
- for (i = 0; i < ui->ndragcoords; i++)
+ for (i = 1; i < ui->ndragcoords; i++)
if (pos == ui->dragcoords[i]) {
ui->ndragcoords = i+1;
return;
}
+ if (pos == ui->dragcoords[0]) {
+ /* More complex check for a loop-shaped drag, which has to go
+ * through interpret_ui_drag to decide on the final degree of
+ * the start/end vertex. */
+ ui->dragcoords[ui->ndragcoords] = pos;
+ bool clearing = true;
+ int lines = state->lines[pos] & (L|R|U|D);
+ for (i = 0; i < ui->ndragcoords; i++) {
+ int sx, sy, dx, dy, dir, oldstate, newstate;
+ interpret_ui_drag(state, ui, &clearing, i, &sx, &sy, &dx, &dy,
+ &dir, &oldstate, &newstate);
+ if (sx == gx && sy == gy)
+ lines ^= (oldstate ^ newstate);
+ if (dx == gx && dy == gy)
+ lines ^= (F(oldstate) ^ F(newstate));
+ }
+ if (NBITS(lines) > 2) {
+ /* Bad vertex degree: fall back to the backtracking behaviour. */
+ ui->ndragcoords = 1;
+ return;
+ }
+ }
+
/*
* Otherwise, dragging the mouse into a square that's a rook-move
* away from the last one on the path extends the path.