diff options
| author | Simon Tatham <anakin@pobox.com> | 2005-05-02 13:17:10 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 2005-05-02 13:17:10 +0000 |
| commit | 4f7b65de2e5f6387a819dd3767f5459b06f5db11 (patch) | |
| tree | cae01c5919854fcbbffae43de6032fc50ae5c031 /rect.c | |
| parent | aea7b6181580df2f0b28d027832dee8d9abccd73 (diff) | |
| download | puzzles-4f7b65de2e5f6387a819dd3767f5459b06f5db11.zip puzzles-4f7b65de2e5f6387a819dd3767f5459b06f5db11.tar.gz puzzles-4f7b65de2e5f6387a819dd3767f5459b06f5db11.tar.bz2 puzzles-4f7b65de2e5f6387a819dd3767f5459b06f5db11.tar.xz | |
Added an automatic `Solve' feature to most games. This is useful for
various things:
- if you haven't fully understood what a game is about, it gives
you an immediate example of a puzzle plus its solution so you can
understand it
- in some games it's useful to compare your solution with the real
one and see where you made a mistake
- in the rearrangement games (Fifteen, Sixteen, Twiddle) it's handy
to be able to get your hands on a pristine grid quickly so you
can practise or experiment with manoeuvres on it
- it provides a good way of debugging the games if you think you've
encountered an unsolvable grid!
[originally from svn r5731]
Diffstat (limited to 'rect.c')
| -rw-r--r-- | rect.c | 67 |
1 files changed, 62 insertions, 5 deletions
@@ -82,7 +82,7 @@ struct game_state { int *grid; /* contains the numbers */ unsigned char *vedge; /* (w+1) x h */ unsigned char *hedge; /* w x (h+1) */ - int completed; + int completed, cheated; }; static game_params *default_params(void) @@ -386,6 +386,12 @@ 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_seed(game_params *params, random_state *rs, game_aux_info **aux) { @@ -829,6 +835,31 @@ static char *new_game_seed(game_params *params, random_state *rs, } /* + * Store the rectangle data in the game_aux_info. + */ + { + game_aux_info *ai = snew(game_aux_info); + + 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); + + 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 (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); + } + + *aux = ai; + } + + /* * Place numbers. */ numbers = snewn(params->w * params->h, int); @@ -899,9 +930,11 @@ static char *new_game_seed(game_params *params, random_state *rs, return seed; } -void game_free_aux_info(game_aux_info *aux) +static void game_free_aux_info(game_aux_info *ai) { - assert(!"Shouldn't happen"); + sfree(ai->vedge); + sfree(ai->hedge); + sfree(ai); } static char *validate_seed(game_params *params, char *seed) @@ -945,7 +978,7 @@ static game_state *new_game(game_params *params, char *seed) state->grid = snewn(area, int); state->vedge = snewn(area, unsigned char); state->hedge = snewn(area, unsigned char); - state->completed = FALSE; + state->completed = state->cheated = FALSE; i = 0; while (*seed) { @@ -987,6 +1020,7 @@ static game_state *dup_game(game_state *state) ret->grid = snewn(state->w * state->h, int); ret->completed = state->completed; + ret->cheated = state->cheated; memcpy(ret->grid, state->grid, state->w * state->h * sizeof(int)); memcpy(ret->vedge, state->vedge, state->w*state->h*sizeof(unsigned char)); @@ -1003,6 +1037,27 @@ static void free_game(game_state *state) sfree(state); } +static game_state *solve_game(game_state *state, game_aux_info *ai, + char **error) +{ + game_state *ret; + + if (!ai) { + *error = "Solution not known for this puzzle"; + return NULL; + } + + assert(state->w == ai->w); + assert(state->h == ai->h); + + ret = dup_game(state); + memcpy(ret->vedge, ai->vedge, ai->w * ai->h * sizeof(unsigned char)); + memcpy(ret->hedge, ai->hedge, ai->w * ai->h * sizeof(unsigned char)); + ret->cheated = TRUE; + + return ret; +} + static char *game_text_format(game_state *state) { char *ret, *p, buf[80]; @@ -1684,7 +1739,8 @@ static float game_anim_length(game_state *oldstate, static float game_flash_length(game_state *oldstate, game_state *newstate, int dir) { - if (!oldstate->completed && newstate->completed) + if (!oldstate->completed && newstate->completed && + !oldstate->cheated && !newstate->cheated) return FLASH_TIME; return 0.0F; } @@ -1714,6 +1770,7 @@ const struct game thegame = { new_game, dup_game, free_game, + TRUE, solve_game, TRUE, game_text_format, new_ui, free_ui, |