aboutsummaryrefslogtreecommitdiff
path: root/solo.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 /solo.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 'solo.c')
-rw-r--r--solo.c152
1 files changed, 66 insertions, 86 deletions
diff --git a/solo.c b/solo.c
index 20e6c07..0abed8c 100644
--- a/solo.c
+++ b/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) {
-
- assert(c == ai->c);
- assert(r == ai->r);
- grid = ai->grid;
- grid_needs_freeing = FALSE;
+ if (ai)
+ return dupstr(ai);
- } 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 = snewn(cr*cr, digit);
+ memcpy(grid, state->grid, cr*cr);
+ rsolve_ret = rsolve(c, r, grid, NULL, 2);
- 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 */
-
- /*
- * 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);
+ ret = encode_solve_move(cr, grid);
- 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,