+static int game_timing_state(game_state *state, game_ui *ui)
+{
+ return TRUE;
+}
+
+static void game_print_size(game_params *params, float *x, float *y)
+{
+ int pw, ph;
+
+ /*
+ * I'll use 5mm squares by default.
+ */
+ game_compute_size(params, 500, &pw, &ph);
+ *x = pw / 100.0;
+ *y = ph / 100.0;
+}
+
+static void game_print(drawing *dr, game_state *state, int tilesize)
+{
+ int w = state->w, h = state->h;
+ int ink = print_mono_colour(dr, 0);
+ int x, y;
+
+ /* Ick: fake up `ds->tilesize' for macro expansion purposes */
+ game_drawstate ads, *ds = &ads;
+ game_set_size(dr, ds, NULL, tilesize);
+
+ /*
+ * Border.
+ */
+ print_line_width(dr, TILE_SIZE / 16);
+ draw_rect_outline(dr, TOCOORD(w, 0), TOCOORD(h, 0),
+ w*TILE_SIZE, h*TILE_SIZE, ink);
+
+ /*
+ * Grid.
+ */
+ for (x = 1; x < w; x++) {
+ print_line_width(dr, TILE_SIZE / (x % 5 ? 128 : 24));
+ draw_line(dr, TOCOORD(w, x), TOCOORD(h, 0),
+ TOCOORD(w, x), TOCOORD(h, h), ink);
+ }
+ for (y = 1; y < h; y++) {
+ print_line_width(dr, TILE_SIZE / (y % 5 ? 128 : 24));
+ draw_line(dr, TOCOORD(w, 0), TOCOORD(h, y),
+ TOCOORD(w, w), TOCOORD(h, y), ink);
+ }
+
+ /*
+ * Clues.
+ */
+ draw_numbers(dr, ds, state, ink);
+
+ /*
+ * Solution.
+ */
+ print_line_width(dr, TILE_SIZE / 128);
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++) {
+ if (state->grid[y*w+x] == GRID_FULL)
+ draw_rect(dr, TOCOORD(w, x), TOCOORD(h, y),
+ TILE_SIZE, TILE_SIZE, ink);
+ else if (state->grid[y*w+x] == GRID_EMPTY)
+ draw_circle(dr, TOCOORD(w, x) + TILE_SIZE/2,
+ TOCOORD(h, y) + TILE_SIZE/2,
+ TILE_SIZE/12, ink, ink);
+ }
+}
+
+#ifdef COMBINED
+#define thegame pattern
+#endif
+
+const struct game thegame = {
+ "Pattern", "games.pattern", "pattern",
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ TRUE, game_configure, custom_params,
+ validate_params,
+ new_game_desc,
+ validate_desc,
+ new_game,
+ dup_game,
+ free_game,
+ TRUE, solve_game,
+ FALSE, game_can_format_as_text_now, game_text_format,
+ new_ui,
+ free_ui,
+ encode_ui,
+ decode_ui,
+ game_changed_state,
+ interpret_move,
+ execute_move,
+ PREFERRED_TILE_SIZE, game_compute_size, game_set_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ TRUE, FALSE, game_print_size, game_print,
+ FALSE, /* wants_statusbar */
+ FALSE, game_timing_state,
+ REQUIRE_RBUTTON, /* flags */
+};
+
+#ifdef STANDALONE_SOLVER
+
+int main(int argc, char **argv)