Recompute solutions in Inertia if the user strays from the path.

This commit is contained in:
Jonas Kölker
2015-10-01 21:29:42 +02:00
committed by Simon Tatham
parent bda4a963f4
commit b9dfef7a12
2 changed files with 46 additions and 37 deletions

View File

@ -735,7 +735,7 @@ static int compare_integers(const void *av, const void *bv)
static char *solve_game(const game_state *state, const game_state *currstate, static char *solve_game(const game_state *state, const game_state *currstate,
const char *aux, char **error) const char *aux, char **error)
{ {
int w = state->p.w, h = state->p.h, wh = w*h; int w = currstate->p.w, h = currstate->p.h, wh = w*h;
int *nodes, *nodeindex, *edges, *backedges, *edgei, *backedgei, *circuit; int *nodes, *nodeindex, *edges, *backedges, *edgei, *backedgei, *circuit;
int nedges; int nedges;
int *dist, *dist2, *list; int *dist, *dist2, *list;
@ -1645,6 +1645,38 @@ static char *interpret_move(const game_state *state, game_ui *ui,
return dupstr(buf); return dupstr(buf);
} }
static void install_new_solution(game_state *ret, const char *move)
{
int i;
soln *sol;
assert (*move == 'S');
++move;
sol = snew(soln);
sol->len = strlen(move);
sol->list = snewn(sol->len, unsigned char);
for (i = 0; i < sol->len; ++i) sol->list[i] = move[i] - '0';
if (ret->soln && --ret->soln->refcount == 0) {
sfree(ret->soln->list);
sfree(ret->soln);
}
ret->soln = sol;
sol->refcount = 1;
ret->cheated = TRUE;
ret->solnpos = 0;
}
static void discard_solution(game_state *ret)
{
--ret->soln->refcount;
assert(ret->soln->refcount > 0); /* ret has a soln-pointing dup */
ret->soln = NULL;
ret->solnpos = 0;
}
static game_state *execute_move(const game_state *state, const char *move) static game_state *execute_move(const game_state *state, const char *move)
{ {
int w = state->p.w, h = state->p.h /*, wh = w*h */; int w = state->p.w, h = state->p.h /*, wh = w*h */;
@ -1652,29 +1684,12 @@ static game_state *execute_move(const game_state *state, const char *move)
game_state *ret; game_state *ret;
if (*move == 'S') { if (*move == 'S') {
int len, i;
soln *sol;
/* /*
* This is a solve move, so we don't actually _change_ the * This is a solve move, so we don't actually _change_ the
* grid but merely set up a stored solution path. * grid but merely set up a stored solution path.
*/ */
move++;
len = strlen(move);
sol = snew(soln);
sol->len = len;
sol->list = snewn(len, unsigned char);
for (i = 0; i < len; i++)
sol->list[i] = move[i] - '0';
ret = dup_game(state); ret = dup_game(state);
ret->cheated = TRUE; install_new_solution(ret, move);
if (ret->soln && --ret->soln->refcount == 0) {
sfree(ret->soln->list);
sfree(ret->soln);
}
ret->soln = sol;
ret->solnpos = 0;
sol->refcount = 1;
return ret; return ret;
} }
@ -1715,22 +1730,18 @@ static game_state *execute_move(const game_state *state, const char *move)
} }
if (ret->soln) { if (ret->soln) {
/* if (ret->dead || ret->gems == 0)
* If this move is the correct next one in the stored discard_solution(ret);
* solution path, advance solnpos. else if (ret->soln->list[ret->solnpos] == dir) {
*/ ++ret->solnpos;
if (ret->soln->list[ret->solnpos] == dir && assert(ret->solnpos < ret->soln->len); /* or gems == 0 */
ret->solnpos+1 < ret->soln->len) { assert(!ret->dead); /* or not a solution */
ret->solnpos++;
} else { } else {
/* char *error = NULL, *soln = solve_game(NULL, ret, NULL, &error);
* Otherwise, the user has strayed from the path, so if (!error) {
* the path is no longer valid. install_new_solution(ret, soln);
*/ sfree(soln);
ret->soln->refcount--; } else discard_solution(ret);
assert(ret->soln->refcount > 0);/* `state' at least still exists */
ret->soln = NULL;
ret->solnpos = 0;
} }
} }

View File

@ -2032,9 +2032,7 @@ begin on this path. If you then move in that direction, the arrow
will update to indicate the next direction on the path. You can also will update to indicate the next direction on the path. You can also
press Space to automatically move in the direction of the hint press Space to automatically move in the direction of the hint
arrow. If you move in a different direction from the one shown by arrow. If you move in a different direction from the one shown by
the arrow, the hint arrows will stop appearing because you have the arrow, arrows will be shown only if the puzzle is still solvable.
strayed from the provided path; you can then use \q{Solve} again to
generate a new path if you want to.
All the actions described in \k{common-actions} are also available. All the actions described in \k{common-actions} are also available.
In particular, if you do run into a mine and die, you can use the In particular, if you do run into a mine and die, you can use the