#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 )
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;
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;
used[i] = FALSE;
}
- gap = rand_upto(n);
+ gap = random_upto(rs, n);
tiles[gap] = 0;
used[0] = TRUE;
* 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++)
* 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
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);
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;
}
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;