return TRUE;
}
-static game_params *decode_params(char const *string)
+static void decode_params(game_params *ret, char const *string)
{
- game_params *ret = snew(game_params);
-
ret->w = ret->h = atoi(string);
ret->n = 2;
ret->rowsonly = ret->orientable = FALSE;
}
string++;
}
-
- return ret;
}
-static char *encode_params(game_params *params)
+static char *encode_params(game_params *params, int full)
{
char buf[256];
sprintf(buf, "%dx%dn%d%s%s", params->w, params->h, params->n,
params->rowsonly ? "r" : "",
params->orientable ? "o" : "");
+ /* Shuffle limit is part of the limited parameters, because we have to
+ * supply the target move count. */
+ if (params->movetarget)
+ sprintf(buf + strlen(buf), "m%d", params->movetarget);
return dupstr(buf);
}
return ok;
}
-static char *new_game_seed(game_params *params, random_state *rs,
+static char *new_game_desc(game_params *params, random_state *rs,
game_aux_info **aux)
{
int *grid;
} while (grid_complete(grid, wh, params->orientable));
/*
- * Now construct the game seed, by describing the grid as a
- * simple sequence of integers. They're comma-separated, unless
- * the puzzle is orientable in which case they're separated by
- * orientation letters `u', `d', `l' and `r'.
+ * Now construct the game description, by describing the grid
+ * as a simple sequence of integers. They're comma-separated,
+ * unless the puzzle is orientable in which case they're
+ * separated by orientation letters `u', `d', `l' and `r'.
*/
ret = NULL;
retlen = 0;
assert(!"Shouldn't happen");
}
-static char *validate_seed(game_params *params, char *seed)
+static char *validate_desc(game_params *params, char *desc)
{
char *p, *err;
int w = params->w, h = params->h, wh = w*h;
int i;
- p = seed;
+ p = desc;
err = NULL;
for (i = 0; i < wh; i++) {
return NULL;
}
-static game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *desc)
{
game_state *state = snew(game_state);
int w = params->w, h = params->h, n = params->n, wh = w*h;
state->grid = snewn(wh, int);
- p = seed;
+ p = desc;
for (i = 0; i < wh; i++) {
state->grid[i] = 4 * atoi(p);
y -= (n-1) * TILE_SIZE / 2;
x = FROMCOORD(x);
y = FROMCOORD(y);
- if (x < 0 || x > w-n || y < 0 || y > w-n)
+ dir = (button == LEFT_BUTTON ? 1 : -1);
+ if (x < 0 || x > w-n || y < 0 || y > h-n)
return NULL;
+ } else if (button == 'a' || button == 'A' || button==MOD_NUM_KEYPAD+'7') {
+ x = y = 0;
+ dir = (button == 'A' ? -1 : +1);
+ } else if (button == 'b' || button == 'B' || button==MOD_NUM_KEYPAD+'9') {
+ x = w-n;
+ y = 0;
+ dir = (button == 'B' ? -1 : +1);
+ } else if (button == 'c' || button == 'C' || button==MOD_NUM_KEYPAD+'1') {
+ x = 0;
+ y = h-n;
+ dir = (button == 'C' ? -1 : +1);
+ } else if (button == 'd' || button == 'D' || button==MOD_NUM_KEYPAD+'3') {
+ x = w-n;
+ y = h-n;
+ dir = (button == 'D' ? -1 : +1);
+ } else if (button==MOD_NUM_KEYPAD+'8' && (w-n) % 2 == 0) {
+ x = (w-n) / 2;
+ y = 0;
+ dir = +1;
+ } else if (button==MOD_NUM_KEYPAD+'2' && (w-n) % 2 == 0) {
+ x = (w-n) / 2;
+ y = h-n;
+ dir = +1;
+ } else if (button==MOD_NUM_KEYPAD+'4' && (h-n) % 2 == 0) {
+ x = 0;
+ y = (h-n) / 2;
+ dir = +1;
+ } else if (button==MOD_NUM_KEYPAD+'6' && (h-n) % 2 == 0) {
+ x = w-n;
+ y = (h-n) / 2;
+ dir = +1;
+ } else if (button==MOD_NUM_KEYPAD+'5' && (w-n) % 2 == 0 && (h-n) % 2 == 0){
+ x = (w-n) / 2;
+ y = (h-n) / 2;
+ dir = +1;
+ } else {
+ return NULL; /* no move to be made */
+ }
- /*
- * This is a valid move. Make it.
- */
- ret = dup_game(from);
- ret->just_used_solve = FALSE; /* zero this in a hurry */
- ret->movecount++;
- dir = (button == LEFT_BUTTON ? 1 : -1);
- do_rotate(ret->grid, w, h, n, ret->orientable, x, y, dir);
- ret->lastx = x;
- ret->lasty = y;
- ret->lastr = dir;
+ /*
+ * This is a valid move. Make it.
+ */
+ ret = dup_game(from);
+ ret->just_used_solve = FALSE; /* zero this in a hurry */
+ ret->movecount++;
+ do_rotate(ret->grid, w, h, n, ret->orientable, x, y, dir);
+ ret->lastx = x;
+ ret->lasty = y;
+ ret->lastr = dir;
- /*
- * See if the game has been completed. To do this we simply
- * test that the grid contents are in increasing order.
- */
- if (!ret->completed && grid_complete(ret->grid, wh, ret->orientable))
- ret->completed = ret->movecount;
- return ret;
- }
- return NULL;
+ /*
+ * See if the game has been completed. To do this we simply
+ * test that the grid contents are in increasing order.
+ */
+ if (!ret->completed && grid_complete(ret->grid, wh, ret->orientable))
+ ret->completed = ret->movecount;
+ return ret;
}
/* ----------------------------------------------------------------------
dup_params,
TRUE, game_configure, custom_params,
validate_params,
- new_game_seed,
+ new_game_desc,
game_free_aux_info,
- validate_seed,
+ validate_desc,
new_game,
dup_game,
free_game,