Fix outdated comment
[sgt/puzzles] / solo.c
diff --git a/solo.c b/solo.c
index 4b4adea..eb35e00 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -107,7 +107,7 @@ struct game_state {
     int c, r;
     digit *grid;
     unsigned char *immutable;         /* marks which digits are clues */
-    int completed;
+    int completed, cheated;
 };
 
 static game_params *default_params(void)
@@ -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.
@@ -1514,9 +1531,10 @@ 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 *aux)
 {
-    assert(!"Shouldn't happen");
+    sfree(aux->grid);
+    sfree(aux);
 }
 
 static char *validate_seed(game_params *params, char *seed)
@@ -1560,7 +1578,7 @@ static game_state *new_game(game_params *params, char *seed)
     state->immutable = snewn(area, unsigned char);
     memset(state->immutable, FALSE, area);
 
-    state->completed = FALSE;
+    state->completed = state->cheated = FALSE;
 
     i = 0;
     while (*seed) {
@@ -1602,6 +1620,7 @@ static game_state *dup_game(game_state *state)
     memcpy(ret->immutable, state->immutable, area);
 
     ret->completed = state->completed;
+    ret->cheated = state->cheated;
 
     return ret;
 }
@@ -1613,6 +1632,42 @@ 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;
+    int c = state->c, r = state->r, cr = c*r;
+    int rsolve_ret;
+
+    ret = dup_game(state);
+    ret->completed = ret->cheated = TRUE;
+
+    /*
+     * 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));
+
+    } 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;
+}
+
 static char *grid_text_format(int c, int r, digit *grid)
 {
     int cr = c*r;
@@ -1940,7 +1995,8 @@ static float game_anim_length(game_state *oldstate, game_state *newstate,
 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;
 }
@@ -1970,6 +2026,7 @@ const struct game thegame = {
     new_game,
     dup_game,
     free_game,
+    TRUE, solve_game,
     TRUE, game_text_format,
     new_ui,
     free_ui,