mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
More serialisation changes: the game_aux_info structure has now been
retired, and replaced with a simple string. Most of the games which use it simply encode the string in the same way that the Solve move will also be encoded, i.e. solve_game() simply returns dupstr(aux_info). Again, this is a better approach than writing separate game_aux_info serialise/deserialise functions because doing it this way is self-testing (the strings are created and parsed during the course of any Solve operation at all). [originally from svn r6029]
This commit is contained in:
10
cube.c
10
cube.c
@ -586,7 +586,7 @@ static void classify_grid_square_callback(void *ctx, struct grid_square *sq)
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
struct grid_data data;
|
||||
int i, j, k, m, area, facesperclass;
|
||||
@ -687,11 +687,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static void add_grid_square_callback(void *ctx, struct grid_square *sq)
|
||||
{
|
||||
game_state *state = (game_state *)ctx;
|
||||
@ -985,7 +980,7 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -1714,7 +1709,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
10
fifteen.c
10
fifteen.c
@ -152,7 +152,7 @@ static int perm_parity(int *perm, int n)
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
int gap, n, i, x;
|
||||
int x1, x2, p1, p2, parity;
|
||||
@ -267,11 +267,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
char *p, *err;
|
||||
@ -380,7 +375,7 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
return dupstr("S");
|
||||
}
|
||||
@ -882,7 +877,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
10
flip.c
10
flip.c
@ -347,7 +347,7 @@ static void addneighbours(tree234 *t, int w, int h, int cx, int cy,
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
int w = params->w, h = params->h, wh = w * h;
|
||||
int i, j;
|
||||
@ -595,11 +595,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int w = params->w, h = params->h, wh = w * h;
|
||||
@ -676,7 +671,7 @@ static void rowxor(unsigned char *row1, unsigned char *row2, int len)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
int w = state->w, h = state->h, wh = w * h;
|
||||
unsigned char *equations, *solution, *shortest;
|
||||
@ -1229,7 +1224,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
5
gtk.c
5
gtk.c
@ -1500,12 +1500,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
while (n-- > 0) {
|
||||
game_aux_info *aux = NULL;
|
||||
char *aux = NULL;
|
||||
char *desc = thegame.new_desc(par, rs, &aux, FALSE);
|
||||
printf("%s:%s\n", parstr, desc);
|
||||
sfree(desc);
|
||||
if (aux)
|
||||
thegame.free_aux_info(aux);
|
||||
sfree(aux);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
10
guess.c
10
guess.c
@ -264,7 +264,7 @@ static void free_pegrow(pegrow pegs)
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
unsigned char *bmp = snewn(params->npegs, unsigned char);
|
||||
char *ret;
|
||||
@ -286,11 +286,6 @@ newcol:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
unsigned char *bmp;
|
||||
@ -365,7 +360,7 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
return dupstr("S");
|
||||
}
|
||||
@ -1260,7 +1255,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
16
midend.c
16
midend.c
@ -48,7 +48,7 @@ struct midend_data {
|
||||
* may also be typed directly into Mines if you like.)
|
||||
*/
|
||||
char *desc, *privdesc, *seedstr;
|
||||
game_aux_info *aux_info;
|
||||
char *aux_info;
|
||||
enum { GOT_SEED, GOT_DESC, GOT_NOTHING } genmode;
|
||||
int nstates, statesize, statepos;
|
||||
|
||||
@ -140,8 +140,7 @@ void midend_free(midend_data *me)
|
||||
sfree(me->states);
|
||||
sfree(me->desc);
|
||||
sfree(me->seedstr);
|
||||
if (me->aux_info)
|
||||
me->ourgame->free_aux_info(me->aux_info);
|
||||
sfree(me->aux_info);
|
||||
me->ourgame->free_params(me->params);
|
||||
if (me->npresets) {
|
||||
for (i = 0; i < me->npresets; i++) {
|
||||
@ -235,8 +234,7 @@ void midend_new_game(midend_data *me)
|
||||
|
||||
sfree(me->desc);
|
||||
sfree(me->privdesc);
|
||||
if (me->aux_info)
|
||||
me->ourgame->free_aux_info(me->aux_info);
|
||||
sfree(me->aux_info);
|
||||
me->aux_info = NULL;
|
||||
|
||||
rs = random_init(me->seedstr, strlen(me->seedstr));
|
||||
@ -634,13 +632,12 @@ float *midend_colours(midend_data *me, int *ncolours)
|
||||
float *ret;
|
||||
|
||||
if (me->nstates == 0) {
|
||||
game_aux_info *aux = NULL;
|
||||
char *aux = NULL;
|
||||
char *desc = me->ourgame->new_desc(me->params, me->random,
|
||||
&aux, TRUE);
|
||||
state = me->ourgame->new_game(me, me->params, desc);
|
||||
sfree(desc);
|
||||
if (aux)
|
||||
me->ourgame->free_aux_info(aux);
|
||||
sfree(aux);
|
||||
} else
|
||||
state = me->states[0].state;
|
||||
|
||||
@ -925,8 +922,7 @@ static char *midend_game_id_int(midend_data *me, char *id, int defmode)
|
||||
|
||||
me->desc = dupstr(desc);
|
||||
me->genmode = GOT_DESC;
|
||||
if (me->aux_info)
|
||||
me->ourgame->free_aux_info(me->aux_info);
|
||||
sfree(me->aux_info);
|
||||
me->aux_info = NULL;
|
||||
}
|
||||
|
||||
|
10
mines.c
10
mines.c
@ -1946,7 +1946,7 @@ static char *new_mine_layout(int w, int h, int n, int x, int y, int unique,
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
/*
|
||||
* We generate the coordinates of an initial click even if they
|
||||
@ -1984,11 +1984,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
}
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int wh = params->w * params->h;
|
||||
@ -2298,7 +2293,7 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
if (!state->layout->mines) {
|
||||
*error = "Game has not been started yet";
|
||||
@ -3045,7 +3040,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
49
net.c
49
net.c
@ -77,11 +77,6 @@ struct game_params {
|
||||
float barrier_probability;
|
||||
};
|
||||
|
||||
struct game_aux_info {
|
||||
int width, height;
|
||||
unsigned char *tiles;
|
||||
};
|
||||
|
||||
struct game_state {
|
||||
int width, height, wrapping, completed;
|
||||
int last_rotate_x, last_rotate_y, last_rotate_dir;
|
||||
@ -1139,7 +1134,7 @@ static void perturb(int w, int h, unsigned char *tiles, int wrapping,
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
tree234 *possibilities, *barriertree;
|
||||
int w, h, x, y, cx, cy, nbarriers;
|
||||
@ -1401,16 +1396,16 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the unshuffled grid in an aux_info.
|
||||
* Save the unshuffled grid in aux.
|
||||
*/
|
||||
{
|
||||
game_aux_info *solution;
|
||||
char *solution;
|
||||
int i;
|
||||
|
||||
solution = snew(game_aux_info);
|
||||
solution->width = w;
|
||||
solution->height = h;
|
||||
solution->tiles = snewn(w * h, unsigned char);
|
||||
memcpy(solution->tiles, tiles, w * h);
|
||||
solution = snewn(w * h + 1, char);
|
||||
for (i = 0; i < w * h; i++)
|
||||
solution[i] = "0123456789abcdef"[tiles[i] & 0xF];
|
||||
solution[w*h] = '\0';
|
||||
|
||||
*aux = solution;
|
||||
}
|
||||
@ -1515,12 +1510,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
sfree(aux->tiles);
|
||||
sfree(aux);
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int w = params->width, h = params->height;
|
||||
@ -1667,27 +1656,34 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
unsigned char *tiles;
|
||||
char *ret;
|
||||
int retlen, retsize;
|
||||
int i;
|
||||
int tiles_need_freeing;
|
||||
|
||||
tiles = snewn(state->width * state->height, unsigned char);
|
||||
|
||||
if (!aux) {
|
||||
/*
|
||||
* Run the internal solver on the provided grid. This might
|
||||
* not yield a complete solution.
|
||||
*/
|
||||
tiles = snewn(state->width * state->height, unsigned char);
|
||||
memcpy(tiles, state->tiles, state->width * state->height);
|
||||
net_solver(state->width, state->height, tiles,
|
||||
state->barriers, state->wrapping);
|
||||
tiles_need_freeing = TRUE;
|
||||
} else {
|
||||
tiles = aux->tiles;
|
||||
tiles_need_freeing = FALSE;
|
||||
for (i = 0; i < state->width * state->height; i++) {
|
||||
int c = aux[i];
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
tiles[i] = c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
tiles[i] = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
tiles[i] = c - 'A' + 10;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1747,6 +1743,8 @@ static char *solve_game(game_state *state, game_state *currstate,
|
||||
ret[retlen] = '\0';
|
||||
ret = sresize(ret, retlen+1, char);
|
||||
|
||||
sfree(tiles);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2747,7 +2745,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
51
netslide.c
51
netslide.c
@ -82,11 +82,6 @@ struct game_params {
|
||||
int movetarget;
|
||||
};
|
||||
|
||||
struct game_aux_info {
|
||||
int width, height;
|
||||
unsigned char *tiles;
|
||||
};
|
||||
|
||||
struct game_state {
|
||||
int width, height, cx, cy, wrapping, completed;
|
||||
int used_solve, just_used_solve;
|
||||
@ -330,7 +325,7 @@ static char *validate_params(game_params *params)
|
||||
*/
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
tree234 *possibilities, *barriertree;
|
||||
int w, h, x, y, cx, cy, nbarriers;
|
||||
@ -535,19 +530,22 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the unshuffled grid. We do this using a separate
|
||||
* reference-counted structure since it's a large chunk of
|
||||
* memory which we don't want to have to replicate in every
|
||||
* game state while playing.
|
||||
* Save the unshuffled grid in aux.
|
||||
*/
|
||||
{
|
||||
game_aux_info *solution;
|
||||
char *solution;
|
||||
int i;
|
||||
|
||||
solution = snew(game_aux_info);
|
||||
solution->width = w;
|
||||
solution->height = h;
|
||||
solution->tiles = snewn(w * h, unsigned char);
|
||||
memcpy(solution->tiles, tiles, w * h);
|
||||
/*
|
||||
* String format is exactly the same as a solve move, so we
|
||||
* can just dupstr this in solve_game().
|
||||
*/
|
||||
|
||||
solution = snewn(w * h + 2, char);
|
||||
solution[0] = 'S';
|
||||
for (i = 0; i < w * h; i++)
|
||||
solution[i+1] = "0123456789abcdef"[tiles[i] & 0xF];
|
||||
solution[w*h+1] = '\0';
|
||||
|
||||
*aux = solution;
|
||||
}
|
||||
@ -698,12 +696,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
sfree(aux->tiles);
|
||||
sfree(aux);
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int w = params->width, h = params->height;
|
||||
@ -894,24 +886,14 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
char *ret;
|
||||
int i;
|
||||
|
||||
if (!aux) {
|
||||
*error = "Solution not known for this puzzle";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(aux->width == state->width);
|
||||
assert(aux->height == state->height);
|
||||
ret = snewn(aux->width * aux->height + 2, char);
|
||||
ret[0] = 'S';
|
||||
for (i = 0; i < aux->width * aux->height; i++)
|
||||
ret[i+1] = "0123456789abcdef"[aux->tiles[i] & 0xF];
|
||||
ret[i+1] = '\0';
|
||||
return ret;
|
||||
return dupstr(aux);
|
||||
}
|
||||
|
||||
static char *game_text_format(game_state *state)
|
||||
@ -1822,7 +1804,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
10
nullgame.c
10
nullgame.c
@ -84,16 +84,11 @@ static char *validate_params(game_params *params)
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
return dupstr("FIXME");
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
return NULL;
|
||||
@ -123,7 +118,7 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -255,7 +250,6 @@ const struct game thegame = {
|
||||
FALSE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
125
pattern.c
125
pattern.c
@ -466,13 +466,8 @@ static unsigned char *generate_soluble(random_state *rs, int w, int h)
|
||||
return grid;
|
||||
}
|
||||
|
||||
struct game_aux_info {
|
||||
int w, h;
|
||||
unsigned char *grid;
|
||||
};
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
unsigned char *grid;
|
||||
int i, j, max, rowlen, *rowdata;
|
||||
@ -484,14 +479,22 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
rowdata = snewn(max, int);
|
||||
|
||||
/*
|
||||
* Save the solved game in an aux_info.
|
||||
* Save the solved game in aux.
|
||||
*/
|
||||
{
|
||||
game_aux_info *ai = snew(game_aux_info);
|
||||
char *ai = snewn(params->w * params->h + 2, char);
|
||||
|
||||
ai->w = params->w;
|
||||
ai->h = params->h;
|
||||
ai->grid = grid;
|
||||
/*
|
||||
* String format is exactly the same as a solve move, so we
|
||||
* can just dupstr this in solve_game().
|
||||
*/
|
||||
|
||||
ai[0] = 'S';
|
||||
|
||||
for (i = 0; i < params->w * params->h; i++)
|
||||
ai[i+1] = grid[i] ? '1' : '0';
|
||||
|
||||
ai[params->w * params->h + 1] = '\0';
|
||||
|
||||
*aux = ai;
|
||||
}
|
||||
@ -549,12 +552,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
sfree(aux->grid);
|
||||
sfree(aux);
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int i, n, rowspace;
|
||||
@ -665,81 +662,66 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *ai, char **error)
|
||||
char *ai, char **error)
|
||||
{
|
||||
unsigned char *matrix;
|
||||
int matrix_needs_freeing;
|
||||
int full, empty;
|
||||
int w = state->w, h = state->h;
|
||||
int i;
|
||||
char *ret;
|
||||
int done_any, max;
|
||||
unsigned char *workspace;
|
||||
int *rowdata;
|
||||
|
||||
/*
|
||||
* If we already have the solved state in an aux_info, copy it
|
||||
* out.
|
||||
* If we already have the solved state in ai, copy it out.
|
||||
*/
|
||||
if (ai) {
|
||||
assert(ai->w == w && ai->h == h);
|
||||
if (ai)
|
||||
return dupstr(ai);
|
||||
|
||||
matrix = ai->grid;
|
||||
matrix_needs_freeing = FALSE;
|
||||
full = GRID_FULL;
|
||||
empty = GRID_EMPTY;
|
||||
} else {
|
||||
int done_any, max;
|
||||
unsigned char *workspace;
|
||||
int *rowdata;
|
||||
matrix = snewn(w*h, unsigned char);
|
||||
max = max(w, h);
|
||||
workspace = snewn(max*3, unsigned char);
|
||||
rowdata = snewn(max+1, int);
|
||||
|
||||
matrix = snewn(w*h, unsigned char);
|
||||
max = max(w, h);
|
||||
workspace = snewn(max*3, unsigned char);
|
||||
rowdata = snewn(max+1, int);
|
||||
memset(matrix, 0, w*h);
|
||||
|
||||
memset(matrix, 0, w*h);
|
||||
do {
|
||||
done_any = 0;
|
||||
for (i=0; i<h; i++) {
|
||||
memcpy(rowdata, state->rowdata + state->rowsize*(w+i),
|
||||
max*sizeof(int));
|
||||
rowdata[state->rowlen[w+i]] = 0;
|
||||
done_any |= do_row(workspace, workspace+max, workspace+2*max,
|
||||
matrix+i*w, w, 1, rowdata);
|
||||
}
|
||||
for (i=0; i<w; i++) {
|
||||
memcpy(rowdata, state->rowdata + state->rowsize*i, max*sizeof(int));
|
||||
rowdata[state->rowlen[i]] = 0;
|
||||
done_any |= do_row(workspace, workspace+max, workspace+2*max,
|
||||
matrix+i, h, w, rowdata);
|
||||
}
|
||||
} while (done_any);
|
||||
|
||||
do {
|
||||
done_any = 0;
|
||||
for (i=0; i<h; i++) {
|
||||
memcpy(rowdata, state->rowdata + state->rowsize*(w+i),
|
||||
max*sizeof(int));
|
||||
rowdata[state->rowlen[w+i]] = 0;
|
||||
done_any |= do_row(workspace, workspace+max, workspace+2*max,
|
||||
matrix+i*w, w, 1, rowdata);
|
||||
}
|
||||
for (i=0; i<w; i++) {
|
||||
memcpy(rowdata, state->rowdata + state->rowsize*i, max*sizeof(int));
|
||||
rowdata[state->rowlen[i]] = 0;
|
||||
done_any |= do_row(workspace, workspace+max, workspace+2*max,
|
||||
matrix+i, h, w, rowdata);
|
||||
}
|
||||
} while (done_any);
|
||||
sfree(workspace);
|
||||
sfree(rowdata);
|
||||
|
||||
sfree(workspace);
|
||||
sfree(rowdata);
|
||||
|
||||
for (i = 0; i < w*h; i++) {
|
||||
if (matrix[i] != BLOCK && matrix[i] != DOT) {
|
||||
sfree(matrix);
|
||||
*error = "Solving algorithm cannot complete this puzzle";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
matrix_needs_freeing = TRUE;
|
||||
full = BLOCK;
|
||||
empty = DOT;
|
||||
for (i = 0; i < w*h; i++) {
|
||||
if (matrix[i] != BLOCK && matrix[i] != DOT) {
|
||||
sfree(matrix);
|
||||
*error = "Solving algorithm cannot complete this puzzle";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = snewn(w*h+2, char);
|
||||
ret[0] = 'S';
|
||||
for (i = 0; i < w*h; i++) {
|
||||
assert(matrix[i] == full || matrix[i] == empty);
|
||||
ret[i+1] = (matrix[i] == full ? '1' : '0');
|
||||
assert(matrix[i] == BLOCK || matrix[i] == DOT);
|
||||
ret[i+1] = (matrix[i] == BLOCK ? '1' : '0');
|
||||
}
|
||||
ret[w*h+1] = '\0';
|
||||
|
||||
if (matrix_needs_freeing)
|
||||
sfree(matrix);
|
||||
sfree(matrix);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1194,7 +1176,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
@ -70,7 +70,6 @@ typedef struct midend_data midend_data;
|
||||
typedef struct random_state random_state;
|
||||
typedef struct game_params game_params;
|
||||
typedef struct game_state game_state;
|
||||
typedef struct game_aux_info game_aux_info;
|
||||
typedef struct game_ui game_ui;
|
||||
typedef struct game_drawstate game_drawstate;
|
||||
typedef struct game game;
|
||||
@ -262,15 +261,14 @@ struct game {
|
||||
game_params *(*custom_params)(config_item *cfg);
|
||||
char *(*validate_params)(game_params *params);
|
||||
char *(*new_desc)(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive);
|
||||
void (*free_aux_info)(game_aux_info *aux);
|
||||
char **aux, int interactive);
|
||||
char *(*validate_desc)(game_params *params, char *desc);
|
||||
game_state *(*new_game)(midend_data *me, game_params *params, char *desc);
|
||||
game_state *(*dup_game)(game_state *state);
|
||||
void (*free_game)(game_state *state);
|
||||
int can_solve;
|
||||
char *(*solve)(game_state *orig, game_state *curr,
|
||||
game_aux_info *aux, char **error);
|
||||
char *aux, char **error);
|
||||
int can_format_as_text;
|
||||
char *(*text_format)(game_state *state);
|
||||
game_ui *(*new_ui)(game_state *state);
|
||||
|
135
rect.c
135
rect.c
@ -1117,14 +1117,8 @@ static void display_grid(game_params *params, int *grid, int *numbers, int all)
|
||||
}
|
||||
#endif
|
||||
|
||||
struct game_aux_info {
|
||||
int w, h;
|
||||
unsigned char *vedge; /* (w+1) x h */
|
||||
unsigned char *hedge; /* w x (h+1) */
|
||||
};
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
int *grid, *numbers = NULL;
|
||||
int x, y, y2, y2last, yx, run, i, nsquares;
|
||||
@ -1679,26 +1673,31 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the rectangle data in the game_aux_info.
|
||||
* Store the solution in aux.
|
||||
*/
|
||||
{
|
||||
game_aux_info *ai = snew(game_aux_info);
|
||||
char *ai;
|
||||
int len;
|
||||
|
||||
ai->w = params->w;
|
||||
ai->h = params->h;
|
||||
ai->vedge = snewn(ai->w * ai->h, unsigned char);
|
||||
ai->hedge = snewn(ai->w * ai->h, unsigned char);
|
||||
len = 2 + (params->w-1)*params->h + (params->h-1)*params->w;
|
||||
ai = snewn(len, char);
|
||||
|
||||
ai[0] = 'S';
|
||||
|
||||
p = ai+1;
|
||||
|
||||
for (y = 0; y < params->h; y++)
|
||||
for (x = 1; x < params->w; x++) {
|
||||
vedge(ai, x, y) =
|
||||
index(params, grid, x, y) != index(params, grid, x-1, y);
|
||||
}
|
||||
for (x = 1; x < params->w; x++)
|
||||
*p++ = (index(params, grid, x, y) !=
|
||||
index(params, grid, x-1, y) ? '1' : '0');
|
||||
|
||||
for (y = 1; y < params->h; y++)
|
||||
for (x = 0; x < params->w; x++) {
|
||||
hedge(ai, x, y) =
|
||||
index(params, grid, x, y) != index(params, grid, x, y-1);
|
||||
}
|
||||
for (x = 0; x < params->w; x++)
|
||||
*p++ = (index(params, grid, x, y) !=
|
||||
index(params, grid, x, y-1) ? '1' : '0');
|
||||
|
||||
assert(p - ai == len-1);
|
||||
*p = '\0';
|
||||
|
||||
*aux = ai;
|
||||
}
|
||||
@ -1746,13 +1745,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *ai)
|
||||
{
|
||||
sfree(ai->vedge);
|
||||
sfree(ai->hedge);
|
||||
sfree(ai);
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int area = params->w * params->h;
|
||||
@ -1854,61 +1846,53 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *ai, char **error)
|
||||
char *ai, char **error)
|
||||
{
|
||||
unsigned char *vedge, *hedge;
|
||||
int edges_need_freeing;
|
||||
int x, y, len;
|
||||
char *ret, *p;
|
||||
int i, j, n;
|
||||
struct numberdata *nd;
|
||||
|
||||
if (!ai) {
|
||||
int i, j, n;
|
||||
struct numberdata *nd;
|
||||
if (ai)
|
||||
return dupstr(ai);
|
||||
|
||||
/*
|
||||
* Attempt the in-built solver.
|
||||
*/
|
||||
/*
|
||||
* Attempt the in-built solver.
|
||||
*/
|
||||
|
||||
/* Set up each number's (very short) candidate position list. */
|
||||
for (i = n = 0; i < state->h * state->w; i++)
|
||||
if (state->grid[i])
|
||||
n++;
|
||||
/* Set up each number's (very short) candidate position list. */
|
||||
for (i = n = 0; i < state->h * state->w; i++)
|
||||
if (state->grid[i])
|
||||
n++;
|
||||
|
||||
nd = snewn(n, struct numberdata);
|
||||
nd = snewn(n, struct numberdata);
|
||||
|
||||
for (i = j = 0; i < state->h * state->w; i++)
|
||||
if (state->grid[i]) {
|
||||
nd[j].area = state->grid[i];
|
||||
nd[j].npoints = 1;
|
||||
nd[j].points = snewn(1, struct point);
|
||||
nd[j].points[0].x = i % state->w;
|
||||
nd[j].points[0].y = i / state->w;
|
||||
j++;
|
||||
}
|
||||
for (i = j = 0; i < state->h * state->w; i++)
|
||||
if (state->grid[i]) {
|
||||
nd[j].area = state->grid[i];
|
||||
nd[j].npoints = 1;
|
||||
nd[j].points = snewn(1, struct point);
|
||||
nd[j].points[0].x = i % state->w;
|
||||
nd[j].points[0].y = i / state->w;
|
||||
j++;
|
||||
}
|
||||
|
||||
assert(j == n);
|
||||
assert(j == n);
|
||||
|
||||
vedge = snewn(state->w * state->h, unsigned char);
|
||||
hedge = snewn(state->w * state->h, unsigned char);
|
||||
memset(vedge, 0, state->w * state->h);
|
||||
memset(hedge, 0, state->w * state->h);
|
||||
edges_need_freeing = TRUE;
|
||||
vedge = snewn(state->w * state->h, unsigned char);
|
||||
hedge = snewn(state->w * state->h, unsigned char);
|
||||
memset(vedge, 0, state->w * state->h);
|
||||
memset(hedge, 0, state->w * state->h);
|
||||
|
||||
rect_solver(state->w, state->h, n, nd, hedge, vedge, NULL);
|
||||
rect_solver(state->w, state->h, n, nd, hedge, vedge, NULL);
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
for (i = 0; i < n; i++)
|
||||
sfree(nd[i].points);
|
||||
sfree(nd);
|
||||
} else {
|
||||
assert(state->w == ai->w);
|
||||
assert(state->h == ai->h);
|
||||
vedge = ai->vedge;
|
||||
hedge = ai->hedge;
|
||||
edges_need_freeing = FALSE;
|
||||
}
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
for (i = 0; i < n; i++)
|
||||
sfree(nd[i].points);
|
||||
sfree(nd);
|
||||
|
||||
len = 2 + (state->w-1)*state->h + (state->h-1)*state->w;
|
||||
ret = snewn(len, char);
|
||||
@ -1916,18 +1900,16 @@ static char *solve_game(game_state *state, game_state *currstate,
|
||||
p = ret;
|
||||
*p++ = 'S';
|
||||
for (y = 0; y < state->h; y++)
|
||||
for (x = 1; x < state->w; x++)
|
||||
*p++ = vedge[y*state->w+x] ? '1' : '0';
|
||||
for (x = 1; x < state->w; x++)
|
||||
*p++ = vedge[y*state->w+x] ? '1' : '0';
|
||||
for (y = 1; y < state->h; y++)
|
||||
for (x = 0; x < state->w; x++)
|
||||
*p++ = hedge[y*state->w+x] ? '1' : '0';
|
||||
*p++ = '\0';
|
||||
assert(p - ret == len);
|
||||
|
||||
if (edges_need_freeing) {
|
||||
sfree(vedge);
|
||||
sfree(hedge);
|
||||
}
|
||||
sfree(vedge);
|
||||
sfree(hedge);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2799,7 +2781,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
10
samegame.c
10
samegame.c
@ -240,7 +240,7 @@ static char *validate_params(game_params *params)
|
||||
*/
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
char *ret;
|
||||
int n, i, j, c, retlen, *tiles;
|
||||
@ -282,11 +282,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int area = params->w * params->h, i;
|
||||
@ -356,7 +351,7 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -999,7 +994,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
10
sixteen.c
10
sixteen.c
@ -195,7 +195,7 @@ static int perm_parity(int *perm, int n)
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
int stop, n, i, x;
|
||||
int x1, x2, p1, p2;
|
||||
@ -398,11 +398,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
@ -511,7 +506,7 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
return dupstr("S");
|
||||
}
|
||||
@ -1060,7 +1055,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
152
solo.c
152
solo.c
@ -1419,13 +1419,51 @@ static int symmetries(game_params *params, int x, int y, int *output, int s)
|
||||
return i;
|
||||
}
|
||||
|
||||
struct game_aux_info {
|
||||
int c, r;
|
||||
digit *grid;
|
||||
};
|
||||
static char *encode_solve_move(int cr, digit *grid)
|
||||
{
|
||||
int i, len;
|
||||
char *ret, *p, *sep;
|
||||
|
||||
/*
|
||||
* It's surprisingly easy to work out _exactly_ how long this
|
||||
* string needs to be. To decimal-encode all the numbers from 1
|
||||
* to n:
|
||||
*
|
||||
* - every number has a units digit; total is n.
|
||||
* - all numbers above 9 have a tens digit; total is max(n-9,0).
|
||||
* - all numbers above 99 have a hundreds digit; total is max(n-99,0).
|
||||
* - and so on.
|
||||
*/
|
||||
len = 0;
|
||||
for (i = 1; i <= cr; i *= 10)
|
||||
len += max(cr - i + 1, 0);
|
||||
len += cr; /* don't forget the commas */
|
||||
len *= cr; /* there are cr rows of these */
|
||||
|
||||
/*
|
||||
* Now len is one bigger than the total size of the
|
||||
* comma-separated numbers (because we counted an
|
||||
* additional leading comma). We need to have a leading S
|
||||
* and a trailing NUL, so we're off by one in total.
|
||||
*/
|
||||
len++;
|
||||
|
||||
ret = snewn(len, char);
|
||||
p = ret;
|
||||
*p++ = 'S';
|
||||
sep = "";
|
||||
for (i = 0; i < cr*cr; i++) {
|
||||
p += sprintf(p, "%s%d", sep, grid[i]);
|
||||
sep = ",";
|
||||
}
|
||||
*p++ = '\0';
|
||||
assert(p - ret == len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
int c = params->c, r = params->r, cr = c*r;
|
||||
int area = cr*cr;
|
||||
@ -1493,25 +1531,19 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
assert(check_valid(c, r, grid));
|
||||
|
||||
/*
|
||||
* Save the solved grid in the aux_info.
|
||||
* Save the solved grid in aux.
|
||||
*/
|
||||
{
|
||||
game_aux_info *ai = snew(game_aux_info);
|
||||
ai->c = c;
|
||||
ai->r = r;
|
||||
ai->grid = snewn(cr * cr, digit);
|
||||
memcpy(ai->grid, grid, cr * cr * sizeof(digit));
|
||||
/*
|
||||
* We might already have written *aux the last time we
|
||||
* went round this loop, in which case we should free
|
||||
* the old aux_info before overwriting it with the new
|
||||
* one.
|
||||
* the old aux before overwriting it with the new one.
|
||||
*/
|
||||
if (*aux) {
|
||||
sfree((*aux)->grid);
|
||||
sfree(*aux);
|
||||
}
|
||||
*aux = ai;
|
||||
|
||||
*aux = encode_solve_move(cr, grid);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1652,12 +1684,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
sfree(aux->grid);
|
||||
sfree(aux);
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
int area = params->r * params->r * params->c * params->c;
|
||||
@ -1760,81 +1786,36 @@ static void free_game(game_state *state)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *ai, char **error)
|
||||
char *ai, char **error)
|
||||
{
|
||||
int c = state->c, r = state->r, cr = c*r;
|
||||
int i, len;
|
||||
char *ret, *p, *sep;
|
||||
char *ret;
|
||||
digit *grid;
|
||||
int grid_needs_freeing;
|
||||
int rsolve_ret;
|
||||
|
||||
/*
|
||||
* If we already have the solution in the aux_info, save
|
||||
* ourselves some time.
|
||||
* If we already have the solution in ai, save ourselves some
|
||||
* time.
|
||||
*/
|
||||
if (ai) {
|
||||
if (ai)
|
||||
return dupstr(ai);
|
||||
|
||||
assert(c == ai->c);
|
||||
assert(r == ai->r);
|
||||
grid = ai->grid;
|
||||
grid_needs_freeing = FALSE;
|
||||
grid = snewn(cr*cr, digit);
|
||||
memcpy(grid, state->grid, cr*cr);
|
||||
rsolve_ret = rsolve(c, r, grid, NULL, 2);
|
||||
|
||||
} else {
|
||||
int rsolve_ret;
|
||||
|
||||
grid = snewn(cr*cr, digit);
|
||||
memcpy(grid, state->grid, cr*cr);
|
||||
rsolve_ret = rsolve(c, r, grid, NULL, 2);
|
||||
|
||||
if (rsolve_ret != 1) {
|
||||
sfree(grid);
|
||||
if (rsolve_ret == 0)
|
||||
*error = "No solution exists for this puzzle";
|
||||
else
|
||||
*error = "Multiple solutions exist for this puzzle";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grid_needs_freeing = TRUE;
|
||||
if (rsolve_ret != 1) {
|
||||
sfree(grid);
|
||||
if (rsolve_ret == 0)
|
||||
*error = "No solution exists for this puzzle";
|
||||
else
|
||||
*error = "Multiple solutions exist for this puzzle";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's surprisingly easy to work out _exactly_ how long this
|
||||
* string needs to be. To decimal-encode all the numbers from 1
|
||||
* to n:
|
||||
*
|
||||
* - every number has a units digit; total is n.
|
||||
* - all numbers above 9 have a tens digit; total is max(n-9,0).
|
||||
* - all numbers above 99 have a hundreds digit; total is max(n-99,0).
|
||||
* - and so on.
|
||||
*/
|
||||
len = 0;
|
||||
for (i = 1; i <= cr; i *= 10)
|
||||
len += max(cr - i + 1, 0);
|
||||
len += cr; /* don't forget the commas */
|
||||
len *= cr; /* there are cr rows of these */
|
||||
ret = encode_solve_move(cr, grid);
|
||||
|
||||
/*
|
||||
* Now len is one bigger than the total size of the
|
||||
* comma-separated numbers (because we counted an
|
||||
* additional leading comma). We need to have a leading S
|
||||
* and a trailing NUL, so we're off by one in total.
|
||||
*/
|
||||
len++;
|
||||
|
||||
ret = snewn(len, char);
|
||||
p = ret;
|
||||
*p++ = 'S';
|
||||
sep = "";
|
||||
for (i = 0; i < cr*cr; i++) {
|
||||
p += sprintf(p, "%s%d", sep, grid[i]);
|
||||
sep = ",";
|
||||
}
|
||||
*p++ = '\0';
|
||||
assert(p - ret == len);
|
||||
|
||||
if (grid_needs_freeing)
|
||||
sfree(grid);
|
||||
sfree(grid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2420,7 +2401,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
10
twiddle.c
10
twiddle.c
@ -307,7 +307,7 @@ static int grid_complete(int *grid, int wh, int orientable)
|
||||
}
|
||||
|
||||
static char *new_game_desc(game_params *params, random_state *rs,
|
||||
game_aux_info **aux, int interactive)
|
||||
char **aux, int interactive)
|
||||
{
|
||||
int *grid;
|
||||
int w = params->w, h = params->h, n = params->n, wh = w*h;
|
||||
@ -430,11 +430,6 @@ static char *new_game_desc(game_params *params, random_state *rs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void game_free_aux_info(game_aux_info *aux)
|
||||
{
|
||||
assert(!"Shouldn't happen");
|
||||
}
|
||||
|
||||
static char *validate_desc(game_params *params, char *desc)
|
||||
{
|
||||
char *p, *err;
|
||||
@ -547,7 +542,7 @@ static int compare_int(const void *av, const void *bv)
|
||||
}
|
||||
|
||||
static char *solve_game(game_state *state, game_state *currstate,
|
||||
game_aux_info *aux, char **error)
|
||||
char *aux, char **error)
|
||||
{
|
||||
return dupstr("S");
|
||||
}
|
||||
@ -1224,7 +1219,6 @@ const struct game thegame = {
|
||||
TRUE, game_configure, custom_params,
|
||||
validate_params,
|
||||
new_game_desc,
|
||||
game_free_aux_info,
|
||||
validate_desc,
|
||||
new_game,
|
||||
dup_game,
|
||||
|
Reference in New Issue
Block a user