Changed my mind about midend_is_solved: I've now reprototyped it as

midend_status(), and given it three return codes for win, (permanent)
loss and game-still-in-play. Depending on what the front end wants to
use it for, it may find any or all of these three states worth
distinguishing from each other.

(I suppose a further enhancement might be to add _non_-permanent loss
as a fourth distinct status, to describe situations in which you can't
play further without pressing Undo but doing so is not completely
pointless. That might reasonably include dead-end situations in Same
Game and Pegs, and blown-self-up situations in Mines and Inertia.
However, I haven't done this at present.)

[originally from svn r9179]
This commit is contained in:
Simon Tatham
2011-06-19 13:43:35 +00:00
parent 8dcdb33b77
commit 73daff3937
42 changed files with 188 additions and 164 deletions

23
guess.c
View File

@ -43,7 +43,7 @@ struct game_state {
pegrow solution;
int next_go; /* from 0 to nguesses-1;
if next_go == nguesses then they've lost. */
int solved;
int solved; /* +1 = win, -1 = lose, 0 = still playing */
};
static game_params *default_params(void)
@ -790,7 +790,7 @@ static game_state *execute_move(game_state *from, char *move)
if (!strcmp(move, "S")) {
ret = dup_game(from);
ret->solved = 1;
ret->solved = -1;
return ret;
} else if (move[0] == 'G') {
p = move+1;
@ -817,11 +817,11 @@ static game_state *execute_move(game_state *from, char *move)
nc_place = mark_pegs(ret->guesses[from->next_go], ret->solution, ret->params.ncolours);
if (nc_place == ret->solution->npegs) {
ret->solved = 1; /* win! */
ret->solved = +1; /* win! */
} else {
ret->next_go = from->next_go + 1;
if (ret->next_go >= ret->params.nguesses)
ret->solved = 1; /* 'lose' so we show the pegs. */
ret->solved = -1; /* lose, meaning we show the pegs. */
}
return ret;
@ -1273,7 +1273,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
currmove_redraw(dr, ds, state->next_go, COL_HOLD);
/* draw the solution (or the big rectangle) */
if ((state->solved != ds->solved) || !ds->started) {
if ((!state->solved ^ !ds->solved) || !ds->started) {
draw_rect(dr, SOLN_OX, SOLN_OY, SOLN_W, SOLN_H,
state->solved ? COL_BACKGROUND : COL_EMPTY);
draw_update(dr, SOLN_OX, SOLN_OY, SOLN_W, SOLN_H);
@ -1313,14 +1313,13 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
return 0.0F;
}
static int game_is_solved(game_state *state)
static int game_status(game_state *state)
{
/*
* We return true whenever the solution has been revealed, even
* (on spoiler grounds) if it wasn't guessed correctly.
*
* However, in that situation, 'solved' is still true, so we don't
* have to make any effort to arrange this.
* We return nonzero whenever the solution has been revealed, even
* (on spoiler grounds) if it wasn't guessed correctly. The
* correct return value from this function is already in
* state->solved.
*/
return state->solved;
}
@ -1373,7 +1372,7 @@ const struct game thegame = {
game_redraw,
game_anim_length,
game_flash_length,
game_is_solved,
game_status,
FALSE, FALSE, game_print_size, game_print,
FALSE, /* wants_statusbar */
FALSE, game_timing_state,