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:
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,
|
||||
|
Reference in New Issue
Block a user