shithub: puzzles

Download patch

ref: e6116563bd78021370a41964ee668e49a30688ea
parent: be8f9c528448feea0612f16e49fe605338b1344b
author: Simon Tatham <anakin@pobox.com>
date: Sat May 12 09:13:39 EDT 2007

More forgiving selection of dragging targets.

[originally from svn r7574]

--- a/unfinished/slide.c
+++ b/unfinished/slide.c
@@ -5,9 +5,6 @@
 /*
  * TODO:
  * 
- *  - The dragging semantics are still subtly wrong in complex
- *    cases.
- * 
  *  - Improve the generator.
  *     * actually, we seem to be mostly sensible already now. I
  * 	 want more choice over the type of main block and location
@@ -1345,17 +1342,36 @@
 	 */
 	return "";
     } else if (button == LEFT_DRAG && ui->dragging) {
+	int dist, distlimit, dx, dy, s, px, py;
+
 	tx = FROMCOORD(x);
 	ty = FROMCOORD(y);
 
 	tx -= ui->drag_offset_x;
 	ty -= ui->drag_offset_y;
-	if (tx < 0 || tx >= w || ty < 0 || ty >= h ||
-	    !ui->reachable[ty*w+tx])
-	    return NULL;	       /* this drag has no effect */
 
-	ui->drag_currpos = ty*w+tx;
-	return "";
+	/*
+	 * Now search outwards from (tx,ty), in order of Manhattan
+	 * distance, until we find a reachable square.
+	 */
+	distlimit = w+tx;
+	distlimit = max(distlimit, h+ty);
+	distlimit = max(distlimit, tx);
+	distlimit = max(distlimit, ty);
+	for (dist = 0; dist <= distlimit; dist++) {
+	    for (dx = -dist; dx <= dist; dx++)
+		for (s = -1; s <= +1; s += 2) {
+		    dy = s * (dist - abs(dx));
+		    px = tx + dx;
+		    py = ty + dy;
+		    if (px >= 0 && px < w && py >= 0 && py < h &&
+			ui->reachable[py*w+px]) {
+			ui->drag_currpos = py*w+px;
+			return "";
+		    }
+		}
+	}
+	return NULL;		       /* give up - this drag has no effect */
     } else if (button == LEFT_RELEASE && ui->dragging) {
 	char data[256], *str;