#include "puzzles.h"
enum {
- COL_BACKGROUND,
+ COL_BACKGROUND, COL_BACKGROUND2,
COL_1, COL_2, COL_3, COL_4, COL_5, COL_6, COL_7, COL_8,
COL_MINE, COL_BANG, COL_CROSS, COL_FLAG, COL_FLAGBASE, COL_QUERY,
COL_HIGHLIGHT, COL_LOWLIGHT,
struct game_state {
int w, h, n, dead, won;
+ int used_solve, just_used_solve;
struct mine_layout *layout; /* real mine positions */
signed char *grid; /* player knowledge */
/*
state->h = params->h;
state->n = params->n;
state->dead = state->won = FALSE;
+ state->used_solve = state->just_used_solve = FALSE;
wh = state->w * state->h;
ret->n = state->n;
ret->dead = state->dead;
ret->won = state->won;
+ ret->used_solve = state->used_solve;
+ ret->just_used_solve = state->just_used_solve;
ret->layout = state->layout;
ret->layout->refcount++;
ret->grid = snewn(ret->w * ret->h, char);
static game_state *solve_game(game_state *state, game_aux_info *aux,
char **error)
{
- return NULL;
+ /*
+ * Simply expose the entire grid as if it were a completed
+ * solution.
+ */
+ game_state *ret;
+ int yy, xx;
+
+ if (!state->layout->mines) {
+ *error = "Game has not been started yet";
+ return NULL;
+ }
+
+ ret = dup_game(state);
+ for (yy = 0; yy < ret->h; yy++)
+ for (xx = 0; xx < ret->w; xx++) {
+
+ if (ret->layout->mines[yy*ret->w+xx]) {
+ ret->grid[yy*ret->w+xx] = -1;
+ } else {
+ int dx, dy, v;
+
+ v = 0;
+
+ for (dx = -1; dx <= +1; dx++)
+ for (dy = -1; dy <= +1; dy++)
+ if (xx+dx >= 0 && xx+dx < ret->w &&
+ yy+dy >= 0 && yy+dy < ret->h &&
+ ret->layout->mines[(yy+dy)*ret->w+(xx+dx)])
+ v++;
+
+ ret->grid[yy*ret->w+xx] = v;
+ }
+ }
+ ret->used_solve = ret->just_used_solve = TRUE;
+ ret->won = TRUE;
+
+ return ret;
}
static char *game_text_format(game_state *state)
sfree(ui);
}
-static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
- int button)
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button)
{
game_state *ret;
int cx, cy;
return NULL;
ret = dup_game(from);
+ ret->just_used_solve = FALSE;
ret->grid[cy * from->w + cx] ^= (-2 ^ -1);
return ret;
if (from->grid[cy * from->w + cx] == -2 ||
from->grid[cy * from->w + cx] == -3) {
ret = dup_game(from);
+ ret->just_used_solve = FALSE;
open_square(ret, cx, cy);
return ret;
}
if (n == from->grid[cy * from->w + cx]) {
ret = dup_game(from);
+ ret->just_used_solve = FALSE;
for (dy = -1; dy <= +1; dy++)
for (dx = -1; dx <= +1; dx++)
if (cx+dx >= 0 && cx+dx < ret->w &&
frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
+ ret[COL_BACKGROUND2 * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 19.0 / 20.0;
+ ret[COL_BACKGROUND2 * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 19.0 / 20.0;
+ ret[COL_BACKGROUND2 * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 19.0 / 20.0;
+
ret[COL_1 * 3 + 0] = 0.0F;
ret[COL_1 * 3 + 1] = 0.0F;
ret[COL_1 * 3 + 2] = 1.0F;
/*
* Omit the highlights in this case.
*/
- draw_rect(fe, x, y, TILE_SIZE, TILE_SIZE, bg);
+ draw_rect(fe, x, y, TILE_SIZE, TILE_SIZE,
+ bg == COL_BACKGROUND ? COL_BACKGROUND2 : bg);
draw_line(fe, x, y, x + TILE_SIZE - 1, y, COL_LOWLIGHT);
draw_line(fe, x, y, x, y + TILE_SIZE - 1, COL_LOWLIGHT);
} else {
* on), we clear the square to COL_BANG.
*/
draw_rect(fe, x, y, TILE_SIZE, TILE_SIZE,
- (v == 65 ? COL_BANG : bg));
+ (v == 65 ? COL_BANG :
+ bg == COL_BACKGROUND ? COL_BACKGROUND2 : bg));
draw_line(fe, x, y, x + TILE_SIZE - 1, y, COL_LOWLIGHT);
draw_line(fe, x, y, x, y + TILE_SIZE - 1, COL_LOWLIGHT);
if (state->dead) {
sprintf(statusbar, "GAME OVER!");
} else if (state->won) {
- sprintf(statusbar, "COMPLETED!");
+ if (state->used_solve)
+ sprintf(statusbar, "Auto-solved.");
+ else
+ sprintf(statusbar, "COMPLETED!");
} else {
sprintf(statusbar, "Mines marked: %d / %d", markers, mines);
}
static float game_flash_length(game_state *oldstate, game_state *newstate,
int dir, game_ui *ui)
{
+ if (oldstate->used_solve || newstate->used_solve)
+ return 0.0F;
+
if (dir > 0 && !oldstate->dead && !oldstate->won) {
if (newstate->dead) {
ui->flash_is_death = TRUE;
new_game,
dup_game,
free_game,
- FALSE, solve_game,
+ TRUE, solve_game,
TRUE, game_text_format,
new_ui,
free_ui,