From 3220eba4ad23a856bc83d0e5d5aea04ae76e154b Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 2 May 2005 16:59:50 +0000 Subject: [PATCH] I've changed my mind. For the benefit of users with slower computers, let's save the Solo and Pattern grids at generation time and regurgitate them when asked to solve, rather than doing all the work over again. git-svn-id: svn://svn.tartarus.org/sgt/puzzles@5737 cda61777-01e9-0310-a592-d414129be87e --- pattern.c | 40 ++++++++++++++++++++++++++++++++-------- solo.c | 58 +++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 73 insertions(+), 25 deletions(-) diff --git a/pattern.c b/pattern.c index 0f0a9c6..a728e15 100644 --- a/pattern.c +++ b/pattern.c @@ -472,6 +472,11 @@ 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_seed(game_params *params, random_state *rs, game_aux_info **aux) { @@ -485,6 +490,20 @@ static char *new_game_seed(game_params *params, random_state *rs, rowdata = snewn(max, int); /* + * Save the solved game in an aux_info. + */ + { + game_aux_info *ai = snew(game_aux_info); + + ai->w = params->w; + ai->h = params->h; + ai->grid = snewn(ai->w * ai->h, unsigned char); + memcpy(ai->grid, grid, ai->w * ai->h); + + *aux = ai; + } + + /* * Seed is a slash-separated list of row contents; each row * contents section is a dot-separated list of integers. Row * contents are listed in the order (columns left to right, @@ -539,7 +558,8 @@ static char *new_game_seed(game_params *params, random_state *rs, static void game_free_aux_info(game_aux_info *aux) { - assert(!"Shouldn't happen"); + sfree(aux->grid); + sfree(aux); } static char *validate_seed(game_params *params, char *seed) @@ -651,21 +671,25 @@ static void free_game(game_state *state) sfree(state); } -static game_state *solve_game(game_state *state, game_aux_info *aux, +static game_state *solve_game(game_state *state, game_aux_info *ai, char **error) { game_state *ret; + ret = dup_game(state); + ret->completed = ret->cheated = TRUE; + /* - * I could have stored the grid I invented in the game_aux_info - * and extracted it here where available, but it seems easier - * just to run my internal solver in all cases. + * If we already have the solved state in an aux_info, copy it + * out. */ + if (ai) { - ret = dup_game(state); - ret->completed = ret->cheated = TRUE; + assert(ret->w == ai->w); + assert(ret->h == ai->h); + memcpy(ret->grid, ai->grid, ai->w * ai->h); - { + } else { int w = state->w, h = state->h, i, j, done_any, max; unsigned char *matrix, *workspace; int *rowdata; diff --git a/solo.c b/solo.c index dc3bbc4..eb35e00 100644 --- a/solo.c +++ b/solo.c @@ -1351,6 +1351,11 @@ 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 *new_game_seed(game_params *params, random_state *rs, game_aux_info **aux) { @@ -1394,6 +1399,18 @@ static char *new_game_seed(game_params *params, random_state *rs, assert(ret == 1); assert(check_valid(c, r, grid)); + /* + * Save the solved grid in the aux_info. + */ + { + 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)); + *aux = ai; + } + /* * Now we have a solved grid, start removing things from it * while preserving solubility. @@ -1516,7 +1533,8 @@ static char *new_game_seed(game_params *params, random_state *rs, static void game_free_aux_info(game_aux_info *aux) { - assert(!"Shouldn't happen"); + sfree(aux->grid); + sfree(aux); } static char *validate_seed(game_params *params, char *seed) @@ -1614,31 +1632,37 @@ static void free_game(game_state *state) sfree(state); } -static game_state *solve_game(game_state *state, game_aux_info *aux, +static game_state *solve_game(game_state *state, game_aux_info *ai, char **error) { game_state *ret; - int c = state->c, r = state->r; + int c = state->c, r = state->r, cr = c*r; int rsolve_ret; - /* - * I could have stored the grid I invented in the game_aux_info - * and extracted it here where available, but it seems easier - * just to run my internal solver in all cases. - */ - ret = dup_game(state); ret->completed = ret->cheated = TRUE; - rsolve_ret = rsolve(c, r, ret->grid, NULL, 2); + /* + * If we already have the solution in the aux_info, save + * ourselves some time. + */ + if (ai) { + + assert(c == ai->c); + assert(r == ai->r); + memcpy(ret->grid, ai->grid, cr * cr * sizeof(digit)); - if (rsolve_ret != 1) { - free_game(ret); - if (rsolve_ret == 0) - *error = "No solution exists for this puzzle"; - else - *error = "Multiple solutions exist for this puzzle"; - return NULL; + } else { + rsolve_ret = rsolve(c, r, ret->grid, NULL, 2); + + if (rsolve_ret != 1) { + free_game(ret); + if (rsolve_ret == 0) + *error = "No solution exists for this puzzle"; + else + *error = "Multiple solutions exist for this puzzle"; + return NULL; + } } return ret; -- 2.11.0