* That hook can talk to the game_ui and set the cheated flag,
* and then make_move can avoid setting the `won' flag after that.
*
- * - delay game description generation until first click
- * + do we actually _need_ to do this? Hmm.
- * + it's a perfectly good puzzle game without
- * + but it might be useful when we start timing, since it
- * ensures the user is really paying attention.
- *
- * - timer
- *
* - question marks (arrgh, preferences?)
*
* - sensible parameter constraints
return "Width must be greater than zero";
if (params->h <= 0)
return "Height must be greater than zero";
+ if (params->n > params->w * params->h - 9)
+ return "Too many mines for grid size";
/*
* FIXME: Need more constraints here. Not sure what the
}
static char *new_game_desc(game_params *params, random_state *rs,
- game_aux_info **aux)
+ game_aux_info **aux, int interactive)
{
-#ifdef PREOPENED
- int x = random_upto(rs, params->w);
- int y = random_upto(rs, params->h);
- char *grid, *desc;
-
- grid = new_mine_layout(params->w, params->h, params->n,
- x, y, params->unique, rs);
-#else
- char *rsdesc, *desc;
+ if (!interactive) {
+ /*
+ * For batch-generated grids, pre-open one square.
+ */
+ int x = random_upto(rs, params->w);
+ int y = random_upto(rs, params->h);
+ char *grid, *desc;
+
+ grid = new_mine_layout(params->w, params->h, params->n,
+ x, y, params->unique, rs, &desc);
+ sfree(grid);
+ return desc;
+ } else {
+ char *rsdesc, *desc;
- rsdesc = random_state_encode(rs);
- desc = snewn(strlen(rsdesc) + 100, char);
- sprintf(desc, "r%d,%c,%s", params->n, params->unique ? 'u' : 'a', rsdesc);
- sfree(rsdesc);
- return desc;
-#endif
+ rsdesc = random_state_encode(rs);
+ desc = snewn(strlen(rsdesc) + 100, char);
+ sprintf(desc, "r%d,%c,%s", params->n, params->unique ? 'u' : 'a', rsdesc);
+ sfree(rsdesc);
+ return desc;
+ }
}
static void game_free_aux_info(game_aux_info *aux)
static char *game_text_format(game_state *state)
{
- return NULL;
+ char *ret;
+ int x, y;
+
+ ret = snewn((state->w + 1) * state->h + 1, char);
+ for (y = 0; y < state->h; y++) {
+ for (x = 0; x < state->w; x++) {
+ int v = state->grid[y*state->w+x];
+ if (v == 0)
+ v = '-';
+ else if (v >= 1 && v <= 8)
+ v = '0' + v;
+ else if (v == -1)
+ v = '*';
+ else if (v == -2 || v == -3)
+ v = '?';
+ else if (v >= 64)
+ v = '!';
+ ret[y * (state->w+1) + x] = v;
+ }
+ ret[y * (state->w+1) + state->w] = '\n';
+ }
+ ret[(state->w + 1) * state->h] = '\0';
+
+ return ret;
}
struct game_ui {
return TRUE;
}
+static int game_timing_state(game_state *state)
+{
+ if (state->dead || state->won || !state->layout->mines)
+ return FALSE;
+ return TRUE;
+}
+
#ifdef COMBINED
#define thegame mines
#endif
dup_game,
free_game,
FALSE, solve_game,
- FALSE, game_text_format,
+ TRUE, game_text_format,
new_ui,
free_ui,
make_move,
game_anim_length,
game_flash_length,
game_wants_statusbar,
+ TRUE, game_timing_state,
};