aboutsummaryrefslogtreecommitdiff
path: root/pattern.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2005-06-28 11:14:09 +0000
committerSimon Tatham <anakin@pobox.com>2005-06-28 11:14:09 +0000
commit89fdc09c29f1219a7660ad6d1839cc914a009c02 (patch)
treec9e9e95e109aa01df1a0ca8d310467929cf3049b /pattern.c
parent6c9beb697bd61c7e8d0eac8b7fce54cde134d9c9 (diff)
downloadpuzzles-89fdc09c29f1219a7660ad6d1839cc914a009c02.zip
puzzles-89fdc09c29f1219a7660ad6d1839cc914a009c02.tar.gz
puzzles-89fdc09c29f1219a7660ad6d1839cc914a009c02.tar.bz2
puzzles-89fdc09c29f1219a7660ad6d1839cc914a009c02.tar.xz
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]
Diffstat (limited to 'pattern.c')
-rw-r--r--pattern.c125
1 files changed, 53 insertions, 72 deletions
diff --git a/pattern.c b/pattern.c
index 115e813..671b56f 100644
--- a/pattern.c
+++ b/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);
+
+ /*
+ * String format is exactly the same as a solve move, so we
+ * can just dupstr this in solve_game().
+ */
- ai->w = params->w;
- ai->h = params->h;
- ai->grid = grid;
+ 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);
-
- 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);
+ if (ai)
+ return dupstr(ai);
- memset(matrix, 0, w*h);
+ matrix = snewn(w*h, unsigned char);
+ max = max(w, h);
+ workspace = snewn(max*3, unsigned char);
+ rowdata = snewn(max+1, int);
- 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);
+ memset(matrix, 0, w*h);
- sfree(workspace);
- sfree(rowdata);
+ 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);
- 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;
- }
- }
+ sfree(workspace);
+ sfree(rowdata);
- 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,