aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2007-05-12 13:13:39 +0000
committerSimon Tatham <anakin@pobox.com>2007-05-12 13:13:39 +0000
commite6116563bd78021370a41964ee668e49a30688ea (patch)
treea4cbbf7b58e880af43e269e8e19184bb74df4ab2
parentbe8f9c528448feea0612f16e49fe605338b1344b (diff)
downloadpuzzles-e6116563bd78021370a41964ee668e49a30688ea.zip
puzzles-e6116563bd78021370a41964ee668e49a30688ea.tar.gz
puzzles-e6116563bd78021370a41964ee668e49a30688ea.tar.bz2
puzzles-e6116563bd78021370a41964ee668e49a30688ea.tar.xz
More forgiving selection of dragging targets.
[originally from svn r7574]
-rw-r--r--unfinished/slide.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/unfinished/slide.c b/unfinished/slide.c
index 8a954a3..84639ed 100644
--- 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 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
*/
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;