X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/4e0bfa1907aaa46547eb9beff74a31c415814bab..b725220b2f16c89753a2e3bcf793d4822fe3b35c:/unfinished/slide.c diff --git a/unfinished/slide.c b/unfinished/slide.c index 8a954a3..634c5de 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 @@ -654,7 +651,7 @@ static void generate_board(int w, int h, int *rtx, int *rty, int *minmoves, int *list, nlist, pos; int tx, ty; int i, j; - int moves; + int moves = 0; /* placate optimiser */ /* * Set up a board and fill it with singletons, except for a @@ -824,6 +821,9 @@ static void generate_board(int w, int h, int *rtx, int *rty, int *minmoves, } } + sfree(dsf); + sfree(list); + sfree(tried_merge); sfree(board2); *rtx = tx; @@ -1169,6 +1169,11 @@ static char *solve_game(game_state *state, game_state *currstate, return ret; } +static int game_can_format_as_text_now(game_params *params) +{ + return TRUE; +} + static char *game_text_format(game_state *state) { return board_text_format(state->w, state->h, state->board, @@ -1345,17 +1350,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; @@ -1576,7 +1600,8 @@ static void game_compute_size(game_params *params, int tilesize, int *x, int *y) { /* fool the macros */ - struct dummy { int tilesize; } dummy = { tilesize }, *ds = &dummy; + struct dummy { int tilesize; } dummy, *ds = &dummy; + dummy.tilesize = tilesize; *x = params->w * TILESIZE + 2*BORDER; *y = params->h * TILESIZE + 2*BORDER; @@ -2282,7 +2307,7 @@ static void game_print(drawing *dr, game_state *state, int tilesize) } #ifdef COMBINED -#define thegame nullgame +#define thegame slide #endif const struct game thegame = { @@ -2301,7 +2326,7 @@ const struct game thegame = { dup_game, free_game, TRUE, solve_game, - TRUE, game_text_format, + TRUE, game_can_format_as_text_now, game_text_format, new_ui, free_ui, encode_ui,