X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/c823052456548bc19a37e35a0bfae944004ef049..9bb5bf60022c774f1d4624eb37e648db4edd8b3c:/fifteen.c diff --git a/fifteen.c b/fifteen.c index f7bcc68..78060f5 100644 --- a/fifteen.c +++ b/fifteen.c @@ -19,8 +19,8 @@ const int game_can_configure = TRUE; #define COORD(x) ( (x) * TILE_SIZE + BORDER ) #define FROMCOORD(x) ( ((x) - BORDER + TILE_SIZE) / TILE_SIZE - 1 ) -#define ANIM_TIME 0.1F -#define FLASH_FRAME 0.1F +#define ANIM_TIME 0.13F +#define FLASH_FRAME 0.13F #define X(state, i) ( (i) % (state)->w ) #define Y(state, i) ( (i) / (state)->w ) @@ -80,19 +80,19 @@ config_item *game_configure(game_params *params) ret = snewn(3, config_item); ret[0].name = "Width"; - ret[0].type = STRING; + ret[0].type = C_STRING; sprintf(buf, "%d", params->w); ret[0].sval = dupstr(buf); ret[0].ival = 0; ret[1].name = "Height"; - ret[1].type = STRING; + ret[1].type = C_STRING; sprintf(buf, "%d", params->h); ret[1].sval = dupstr(buf); ret[1].ival = 0; ret[2].name = NULL; - ret[2].type = ENDCFG; + ret[2].type = C_END; ret[2].sval = NULL; ret[2].ival = 0; @@ -131,7 +131,7 @@ int perm_parity(int *perm, int n) return ret; } -char *new_game_seed(game_params *params) +char *new_game_seed(game_params *params, random_state *rs) { int gap, n, i, x; int x1, x2, p1, p2, parity; @@ -149,7 +149,7 @@ char *new_game_seed(game_params *params) used[i] = FALSE; } - gap = rand_upto(n); + gap = random_upto(rs, n); tiles[gap] = 0; used[0] = TRUE; @@ -157,7 +157,7 @@ char *new_game_seed(game_params *params) * Place everything else except the last two tiles. */ for (x = 0, i = n-1; i > 2; i--) { - int k = rand_upto(i); + int k = random_upto(rs, i); int j; for (j = 0; j < n; j++) @@ -199,15 +199,16 @@ char *new_game_seed(game_params *params) * Determine the required parity of the overall permutation. * This is the XOR of: * - * - The chessboard parity ((x^y)&1) of the gap square. The - * bottom right, and therefore also the top left, count as - * even. + * - The chessboard parity ((x^y)&1) of the gap square. The + * bottom right counts as even. * * - The parity of n. (The target permutation is 1,...,n-1,0 * rather than 0,...,n-1; this is a cyclic permutation of * the starting point and hence is odd iff n is even.) */ - parity = (X(params, gap) ^ Y(params, gap) ^ (n+1)) & 1; + parity = ((X(params, gap) - (params->w-1)) ^ + (Y(params, gap) - (params->h-1)) ^ + (n+1)) & 1; /* * Try the last two tiles one way round. If that fails, swap @@ -245,6 +246,57 @@ char *new_game_seed(game_params *params) return ret; } +char *validate_seed(game_params *params, char *seed) +{ + char *p, *err; + int i, area; + int *used; + + area = params->w * params->h; + p = seed; + err = NULL; + + used = snewn(area, int); + for (i = 0; i < area; i++) + used[i] = FALSE; + + for (i = 0; i < area; i++) { + char *q = p; + int n; + + if (*p < '0' || *p > '9') { + err = "Not enough numbers in string"; + goto leave; + } + while (*p >= '0' && *p <= '9') + p++; + if (i < area-1 && *p != ',') { + err = "Expected comma after number"; + goto leave; + } + else if (i == area-1 && *p) { + err = "Excess junk at end of string"; + goto leave; + } + n = atoi(q); + if (n < 0 || n >= area) { + err = "Number out of range"; + goto leave; + } + if (used[n]) { + err = "Number used twice"; + goto leave; + } + used[n] = TRUE; + + if (*p) p++; /* eat comma */ + } + + leave: + sfree(used); + return err; +} + game_state *new_game(game_params *params, char *seed) { game_state *state = snew(game_state); @@ -297,7 +349,16 @@ void free_game(game_state *state) sfree(state); } -game_state *make_move(game_state *from, int x, int y, int button) +game_ui *new_ui(game_state *state) +{ + return NULL; +} + +void free_ui(game_ui *ui) +{ +} + +game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button) { int gx, gy, dx, dy, ux, uy, up, p; game_state *ret; @@ -467,7 +528,8 @@ static void draw_tile(frontend *fe, game_state *state, int x, int y, } void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, - game_state *state, float animtime, float flashtime) + game_state *state, game_ui *ui, + float animtime, float flashtime) { int i, pass, bgcolour;