From f7eb186184e678f32ebf38ecddd64e0c7127d577 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jonas=20K=C3=B6lker?= Date: Mon, 5 Oct 2015 17:59:39 +0200 Subject: [PATCH] Expand keyboard input options in Bridges, for faster entry. - Lay bridges (crosess) with Control-arrow (Shift-arrow) - Jump (non-orthogonally) to nearby islands with number keys, a..f - Mark islands as done with a single tap on the space bar --- bridges.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++- puzzles.but | 18 ++++++++++++------ 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/bridges.c b/bridges.c index 7a448e2..6f0e02d 100644 --- a/bridges.c +++ b/bridges.c @@ -2333,6 +2333,8 @@ static char *interpret_move(const game_state *state, game_ui *ui, int gx = FROMCOORD(x), gy = FROMCOORD(y); char buf[80], *ret; grid_type ggrid = INGRID(state,gx,gy) ? GRID(state,gx,gy) : 0; + int shift = button & MOD_SHFT, control = button & MOD_CTRL; + button &= ~MOD_MASK; if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (!INGRID(state, gx, gy)) return NULL; @@ -2372,6 +2374,12 @@ static char *interpret_move(const game_state *state, game_ui *ui, return ret; } else if (IS_CURSOR_MOVE(button)) { ui->cur_visible = 1; + if (control || shift) { + ui->dragx_src = ui->cur_x; + ui->dragy_src = ui->cur_y; + ui->dragging = TRUE; + ui->drag_is_noline = !control; + } if (ui->dragging) { int nx = ui->cur_x, ny = ui->cur_y; @@ -2441,7 +2449,7 @@ found: ui->cur_visible = 1; return ""; } - if (ui->dragging) { + if (ui->dragging || button == CURSOR_SELECT2) { ui_cancel_drag(ui); if (ui->dragx_dst == -1 && ui->dragy_dst == -1) { sprintf(buf, "M%d,%d", ui->cur_x, ui->cur_y); @@ -2459,6 +2467,51 @@ found: return ""; } } + } else if ((button >= '0' && button <= '9') || + (button >= 'a' && button <= 'f') || + (button >= 'A' && button <= 'F')) { + /* jump to island with .count == number closest to cur_{x,y} */ + int best_x = -1, best_y = -1, best_sqdist = -1, number = -1, i; + + if (button >= '0' && button <= '9') + number = (button == '0' ? 16 : button - '0'); + else if (button >= 'a' && button <= 'f') + number = 10 + button - 'a'; + else if (button >= 'A' && button <= 'F') + number = 10 + button - 'A'; + + if (!ui->cur_visible) { + ui->cur_visible = 1; + return ""; + } + + for (i = 0; i < state->n_islands; ++i) { + int x = state->islands[i].x, y = state->islands[i].y; + int dx = x - ui->cur_x, dy = y - ui->cur_y; + int sqdist = dx*dx + dy*dy; + + if (state->islands[i].count != number) + continue; + if (x == ui->cur_x && y == ui->cur_y) + continue; + + /* new_game() reads the islands in row-major order, so by + * breaking ties in favor of `first in state->islands' we + * also break ties by `lexicographically smallest (y, x)'. + * Thus, there's a stable pattern to how ties are broken + * which the user can learn and use to navigate faster. */ + if (best_sqdist == -1 || sqdist < best_sqdist) { + best_x = x; + best_y = y; + best_sqdist = sqdist; + } + } + if (best_x != -1 && best_y != -1) { + ui->cur_x = best_x; + ui->cur_y = best_y; + return ""; + } else + return NULL; } else if (button == 'g' || button == 'G') { ui->show_hints = 1 - ui->show_hints; return ""; diff --git a/puzzles.but b/puzzles.but index ff7ea58..d262ed9 100644 --- a/puzzles.but +++ b/puzzles.but @@ -2193,12 +2193,18 @@ it and restore your ability to modify it. You can also use the cursor keys to move around the grid: if possible the cursor will always move orthogonally, otherwise it will move -towards the nearest island to the indicated direction. Pressing the -return key followed by a cursor key will lay a bridge in that direction -(if available); pressing the space bar followed by a cursor key will -lay a \q{non-bridge} marker. - -You can mark an island as finished by pressing the return key twice. +towards the nearest island to the indicated direction. Holding Control +and pressing a cursor key will lay a bridge in that direction (if +available); Shift and a cursor key will lay a \q{non-bridge} marker. +Pressing the return key followed by a cursor key will also lay a +bridge in that direction. + +You can mark an island as finished by pressing the space bar or by +pressing the return key twice. + +By pressing a number key, you can jump to the nearest island with that +number. Letters \q{a}, ..., \q{f} count as 10, ..., 15 and \q{0} as +16. Violations of the puzzle rules will be marked in red: -- 2.30.2