mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
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
This commit is contained in:

committed by
Simon Tatham

parent
96b6f55ec8
commit
f7eb186184
55
bridges.c
55
bridges.c
@ -2333,6 +2333,8 @@ static char *interpret_move(const game_state *state, game_ui *ui,
|
|||||||
int gx = FROMCOORD(x), gy = FROMCOORD(y);
|
int gx = FROMCOORD(x), gy = FROMCOORD(y);
|
||||||
char buf[80], *ret;
|
char buf[80], *ret;
|
||||||
grid_type ggrid = INGRID(state,gx,gy) ? GRID(state,gx,gy) : 0;
|
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 (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
|
||||||
if (!INGRID(state, gx, gy)) return NULL;
|
if (!INGRID(state, gx, gy)) return NULL;
|
||||||
@ -2372,6 +2374,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
|
|||||||
return ret;
|
return ret;
|
||||||
} else if (IS_CURSOR_MOVE(button)) {
|
} else if (IS_CURSOR_MOVE(button)) {
|
||||||
ui->cur_visible = 1;
|
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) {
|
if (ui->dragging) {
|
||||||
int nx = ui->cur_x, ny = ui->cur_y;
|
int nx = ui->cur_x, ny = ui->cur_y;
|
||||||
|
|
||||||
@ -2441,7 +2449,7 @@ found:
|
|||||||
ui->cur_visible = 1;
|
ui->cur_visible = 1;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (ui->dragging) {
|
if (ui->dragging || button == CURSOR_SELECT2) {
|
||||||
ui_cancel_drag(ui);
|
ui_cancel_drag(ui);
|
||||||
if (ui->dragx_dst == -1 && ui->dragy_dst == -1) {
|
if (ui->dragx_dst == -1 && ui->dragy_dst == -1) {
|
||||||
sprintf(buf, "M%d,%d", ui->cur_x, ui->cur_y);
|
sprintf(buf, "M%d,%d", ui->cur_x, ui->cur_y);
|
||||||
@ -2459,6 +2467,51 @@ found:
|
|||||||
return "";
|
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') {
|
} else if (button == 'g' || button == 'G') {
|
||||||
ui->show_hints = 1 - ui->show_hints;
|
ui->show_hints = 1 - ui->show_hints;
|
||||||
return "";
|
return "";
|
||||||
|
16
puzzles.but
16
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
|
You can also use the cursor keys to move around the grid: if possible
|
||||||
the cursor will always move orthogonally, otherwise it will move
|
the cursor will always move orthogonally, otherwise it will move
|
||||||
towards the nearest island to the indicated direction. Pressing the
|
towards the nearest island to the indicated direction. Holding Control
|
||||||
return key followed by a cursor key will lay a bridge in that direction
|
and pressing a cursor key will lay a bridge in that direction (if
|
||||||
(if available); pressing the space bar followed by a cursor key will
|
available); Shift and a cursor key will lay a \q{non-bridge} marker.
|
||||||
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 return key twice.
|
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:
|
Violations of the puzzle rules will be marked in red:
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user