chiark / gitweb /
Update changelog for 20170923.ff218728-0+iwj2~3.gbpc58e0c release
[sgt-puzzles.git] / mines.c
1 /*
2  * mines.c: Minesweeper clone with sophisticated grid generation.
3  * 
4  * Still TODO:
5  *
6  *  - think about configurably supporting question marks. Once,
7  *    that is, we've thought about configurability in general!
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <assert.h>
14 #include <ctype.h>
15 #include <math.h>
16
17 #include "tree234.h"
18 #include "puzzles.h"
19
20 enum {
21     COL_BACKGROUND, COL_BACKGROUND2,
22     COL_1, COL_2, COL_3, COL_4, COL_5, COL_6, COL_7, COL_8,
23     COL_MINE, COL_BANG, COL_CROSS, COL_FLAG, COL_FLAGBASE, COL_QUERY,
24     COL_HIGHLIGHT, COL_LOWLIGHT,
25     COL_WRONGNUMBER,
26     COL_CURSOR,
27     NCOLOURS
28 };
29
30 #define PREFERRED_TILE_SIZE 20
31 #define TILE_SIZE (ds->tilesize)
32 #ifdef SMALL_SCREEN
33 #define BORDER 8
34 #else
35 #define BORDER (TILE_SIZE * 3 / 2)
36 #endif
37 #define HIGHLIGHT_WIDTH (TILE_SIZE / 10)
38 #define OUTER_HIGHLIGHT_WIDTH (BORDER / 10)
39 #define COORD(x)  ( (x) * TILE_SIZE + BORDER )
40 #define FROMCOORD(x)  ( ((x) - BORDER + TILE_SIZE) / TILE_SIZE - 1 )
41
42 #define FLASH_FRAME 0.13F
43
44 struct game_params {
45     int w, h, n;
46     int unique;
47 };
48
49 struct mine_layout {
50     /*
51      * This structure is shared between all the game_states for a
52      * given instance of the puzzle, so we reference-count it.
53      */
54     int refcount;
55     char *mines;
56     /*
57      * If we haven't yet actually generated the mine layout, here's
58      * all the data we will need to do so.
59      */
60     int n, unique;
61     random_state *rs;
62     midend *me;                /* to give back the new game desc */
63 };
64
65 struct game_state {
66     int w, h, n, dead, won;
67     int used_solve;
68     struct mine_layout *layout;        /* real mine positions */
69     signed char *grid;                         /* player knowledge */
70     /*
71      * Each item in the `grid' array is one of the following values:
72      * 
73      *  - 0 to 8 mean the square is open and has a surrounding mine
74      *    count.
75      * 
76      *  - -1 means the square is marked as a mine.
77      * 
78      *  - -2 means the square is unknown.
79      * 
80      *  - -3 means the square is marked with a question mark
81      *    (FIXME: do we even want to bother with this?).
82      * 
83      *  - 64 means the square has had a mine revealed when the game
84      *    was lost.
85      * 
86      *  - 65 means the square had a mine revealed and this was the
87      *    one the player hits.
88      * 
89      *  - 66 means the square has a crossed-out mine because the
90      *    player had incorrectly marked it.
91      */
92 };
93
94 static game_params *default_params(void)
95 {
96     game_params *ret = snew(game_params);
97
98     ret->w = ret->h = 9;
99     ret->n = 10;
100     ret->unique = TRUE;
101
102     return ret;
103 }
104
105 static const struct game_params mines_presets[] = {
106   {9, 9, 10, TRUE},
107   {9, 9, 35, TRUE},
108   {16, 16, 40, TRUE},
109   {16, 16, 99, TRUE},
110 #ifndef SMALL_SCREEN
111   {30, 16, 99, TRUE},
112   {30, 16, 170, TRUE},
113 #endif
114 };
115
116 static int game_fetch_preset(int i, char **name, game_params **params)
117 {
118     game_params *ret;
119     char str[80];
120
121     if (i < 0 || i >= lenof(mines_presets))
122         return FALSE;
123
124     ret = snew(game_params);
125     *ret = mines_presets[i];
126
127     sprintf(str, "%dx%d, %d mines", ret->w, ret->h, ret->n);
128
129     *name = dupstr(str);
130     *params = ret;
131     return TRUE;
132 }
133
134 static void free_params(game_params *params)
135 {
136     sfree(params);
137 }
138
139 static game_params *dup_params(const game_params *params)
140 {
141     game_params *ret = snew(game_params);
142     *ret = *params;                    /* structure copy */
143     return ret;
144 }
145
146 static void decode_params(game_params *params, char const *string)
147 {
148     char const *p = string;
149
150     params->w = atoi(p);
151     while (*p && isdigit((unsigned char)*p)) p++;
152     if (*p == 'x') {
153         p++;
154         params->h = atoi(p);
155         while (*p && isdigit((unsigned char)*p)) p++;
156     } else {
157         params->h = params->w;
158     }
159     if (*p == 'n') {
160         p++;
161         params->n = atoi(p);
162         while (*p && (*p == '.' || isdigit((unsigned char)*p))) p++;
163     } else {
164         params->n = params->w * params->h / 10;
165     }
166
167     while (*p) {
168         if (*p == 'a') {
169             p++;
170             params->unique = FALSE;
171         } else
172             p++;                       /* skip any other gunk */
173     }
174 }
175
176 static char *encode_params(const game_params *params, int full)
177 {
178     char ret[400];
179     int len;
180
181     len = sprintf(ret, "%dx%d", params->w, params->h);
182     /*
183      * Mine count is a generation-time parameter, since it can be
184      * deduced from the mine bitmap!
185      */
186     if (full)
187         len += sprintf(ret+len, "n%d", params->n);
188     if (full && !params->unique)
189         ret[len++] = 'a';
190     assert(len < lenof(ret));
191     ret[len] = '\0';
192
193     return dupstr(ret);
194 }
195
196 static config_item *game_configure(const game_params *params)
197 {
198     config_item *ret;
199     char buf[80];
200
201     ret = snewn(5, config_item);
202
203     ret[0].name = "Width";
204     ret[0].type = C_STRING;
205     sprintf(buf, "%d", params->w);
206     ret[0].u.string.sval = dupstr(buf);
207
208     ret[1].name = "Height";
209     ret[1].type = C_STRING;
210     sprintf(buf, "%d", params->h);
211     ret[1].u.string.sval = dupstr(buf);
212
213     ret[2].name = "Mines";
214     ret[2].type = C_STRING;
215     sprintf(buf, "%d", params->n);
216     ret[2].u.string.sval = dupstr(buf);
217
218     ret[3].name = "Ensure solubility";
219     ret[3].type = C_BOOLEAN;
220     ret[3].u.boolean.bval = params->unique;
221
222     ret[4].name = NULL;
223     ret[4].type = C_END;
224
225     return ret;
226 }
227
228 static game_params *custom_params(const config_item *cfg)
229 {
230     game_params *ret = snew(game_params);
231
232     ret->w = atoi(cfg[0].u.string.sval);
233     ret->h = atoi(cfg[1].u.string.sval);
234     ret->n = atoi(cfg[2].u.string.sval);
235     if (strchr(cfg[2].u.string.sval, '%'))
236         ret->n = ret->n * (ret->w * ret->h) / 100;
237     ret->unique = cfg[3].u.boolean.bval;
238
239     return ret;
240 }
241
242 static const char *validate_params(const game_params *params, int full)
243 {
244     /*
245      * Lower limit on grid size: each dimension must be at least 3.
246      * 1 is theoretically workable if rather boring, but 2 is a
247      * real problem: there is often _no_ way to generate a uniquely
248      * solvable 2xn Mines grid. You either run into two mines
249      * blocking the way and no idea what's behind them, or one mine
250      * and no way to know which of the two rows it's in. If the
251      * mine count is even you can create a soluble grid by packing
252      * all the mines at one end (so what when you hit a two-mine
253      * wall there are only as many covered squares left as there
254      * are mines); but if it's odd, you are doomed, because you
255      * _have_ to have a gap somewhere which you can't determine the
256      * position of.
257      */
258     if (full && params->unique && (params->w <= 2 || params->h <= 2))
259         return "Width and height must both be greater than two";
260     if (params->n > params->w * params->h - 9)
261         return "Too many mines for grid size";
262
263     /*
264      * FIXME: Need more constraints here. Not sure what the
265      * sensible limits for Minesweeper actually are. The limits
266      * probably ought to change, however, depending on uniqueness.
267      */
268
269     return NULL;
270 }
271
272 /* ----------------------------------------------------------------------
273  * Minesweeper solver, used to ensure the generated grids are
274  * solvable without having to take risks.
275  */
276
277 /*
278  * Count the bits in a word. Only needs to cope with 16 bits.
279  */
280 static int bitcount16(int inword)
281 {
282     unsigned int word = inword;
283
284     word = ((word & 0xAAAA) >> 1) + (word & 0x5555);
285     word = ((word & 0xCCCC) >> 2) + (word & 0x3333);
286     word = ((word & 0xF0F0) >> 4) + (word & 0x0F0F);
287     word = ((word & 0xFF00) >> 8) + (word & 0x00FF);
288
289     return (int)word;
290 }
291
292 /*
293  * We use a tree234 to store a large number of small localised
294  * sets, each with a mine count. We also keep some of those sets
295  * linked together into a to-do list.
296  */
297 struct set {
298     short x, y, mask, mines;
299     int todo;
300     struct set *prev, *next;
301 };
302
303 static int setcmp(void *av, void *bv)
304 {
305     struct set *a = (struct set *)av;
306     struct set *b = (struct set *)bv;
307
308     if (a->y < b->y)
309         return -1;
310     else if (a->y > b->y)
311         return +1;
312     else if (a->x < b->x)
313         return -1;
314     else if (a->x > b->x)
315         return +1;
316     else if (a->mask < b->mask)
317         return -1;
318     else if (a->mask > b->mask)
319         return +1;
320     else
321         return 0;
322 }
323
324 struct setstore {
325     tree234 *sets;
326     struct set *todo_head, *todo_tail;
327 };
328
329 static struct setstore *ss_new(void)
330 {
331     struct setstore *ss = snew(struct setstore);
332     ss->sets = newtree234(setcmp);
333     ss->todo_head = ss->todo_tail = NULL;
334     return ss;
335 }
336
337 /*
338  * Take two input sets, in the form (x,y,mask). Munge the first by
339  * taking either its intersection with the second or its difference
340  * with the second. Return the new mask part of the first set.
341  */
342 static int setmunge(int x1, int y1, int mask1, int x2, int y2, int mask2,
343                     int diff)
344 {
345     /*
346      * Adjust the second set so that it has the same x,y
347      * coordinates as the first.
348      */
349     if (abs(x2-x1) >= 3 || abs(y2-y1) >= 3) {
350         mask2 = 0;
351     } else {
352         while (x2 > x1) {
353             mask2 &= ~(4|32|256);
354             mask2 <<= 1;
355             x2--;
356         }
357         while (x2 < x1) {
358             mask2 &= ~(1|8|64);
359             mask2 >>= 1;
360             x2++;
361         }
362         while (y2 > y1) {
363             mask2 &= ~(64|128|256);
364             mask2 <<= 3;
365             y2--;
366         }
367         while (y2 < y1) {
368             mask2 &= ~(1|2|4);
369             mask2 >>= 3;
370             y2++;
371         }
372     }
373
374     /*
375      * Invert the second set if `diff' is set (we're after A &~ B
376      * rather than A & B).
377      */
378     if (diff)
379         mask2 ^= 511;
380
381     /*
382      * Now all that's left is a logical AND.
383      */
384     return mask1 & mask2;
385 }
386
387 static void ss_add_todo(struct setstore *ss, struct set *s)
388 {
389     if (s->todo)
390         return;                        /* already on it */
391
392 #ifdef SOLVER_DIAGNOSTICS
393     printf("adding set on todo list: %d,%d %03x %d\n",
394            s->x, s->y, s->mask, s->mines);
395 #endif
396
397     s->prev = ss->todo_tail;
398     if (s->prev)
399         s->prev->next = s;
400     else
401         ss->todo_head = s;
402     ss->todo_tail = s;
403     s->next = NULL;
404     s->todo = TRUE;
405 }
406
407 static void ss_add(struct setstore *ss, int x, int y, int mask, int mines)
408 {
409     struct set *s;
410
411     assert(mask != 0);
412
413     /*
414      * Normalise so that x and y are genuinely the bounding
415      * rectangle.
416      */
417     while (!(mask & (1|8|64)))
418         mask >>= 1, x++;
419     while (!(mask & (1|2|4)))
420         mask >>= 3, y++;
421
422     /*
423      * Create a set structure and add it to the tree.
424      */
425     s = snew(struct set);
426     s->x = x;
427     s->y = y;
428     s->mask = mask;
429     s->mines = mines;
430     s->todo = FALSE;
431     if (add234(ss->sets, s) != s) {
432         /*
433          * This set already existed! Free it and return.
434          */
435         sfree(s);
436         return;
437     }
438
439     /*
440      * We've added a new set to the tree, so put it on the todo
441      * list.
442      */
443     ss_add_todo(ss, s);
444 }
445
446 static void ss_remove(struct setstore *ss, struct set *s)
447 {
448     struct set *next = s->next, *prev = s->prev;
449
450 #ifdef SOLVER_DIAGNOSTICS
451     printf("removing set %d,%d %03x\n", s->x, s->y, s->mask);
452 #endif
453     /*
454      * Remove s from the todo list.
455      */
456     if (prev)
457         prev->next = next;
458     else if (s == ss->todo_head)
459         ss->todo_head = next;
460
461     if (next)
462         next->prev = prev;
463     else if (s == ss->todo_tail)
464         ss->todo_tail = prev;
465
466     s->todo = FALSE;
467
468     /*
469      * Remove s from the tree.
470      */
471     del234(ss->sets, s);
472
473     /*
474      * Destroy the actual set structure.
475      */
476     sfree(s);
477 }
478
479 /*
480  * Return a dynamically allocated list of all the sets which
481  * overlap a provided input set.
482  */
483 static struct set **ss_overlap(struct setstore *ss, int x, int y, int mask)
484 {
485     struct set **ret = NULL;
486     int nret = 0, retsize = 0;
487     int xx, yy;
488
489     for (xx = x-3; xx < x+3; xx++)
490         for (yy = y-3; yy < y+3; yy++) {
491             struct set stmp, *s;
492             int pos;
493
494             /*
495              * Find the first set with these top left coordinates.
496              */
497             stmp.x = xx;
498             stmp.y = yy;
499             stmp.mask = 0;
500
501             if (findrelpos234(ss->sets, &stmp, NULL, REL234_GE, &pos)) {
502                 while ((s = index234(ss->sets, pos)) != NULL &&
503                        s->x == xx && s->y == yy) {
504                     /*
505                      * This set potentially overlaps the input one.
506                      * Compute the intersection to see if they
507                      * really overlap, and add it to the list if
508                      * so.
509                      */
510                     if (setmunge(x, y, mask, s->x, s->y, s->mask, FALSE)) {
511                         /*
512                          * There's an overlap.
513                          */
514                         if (nret >= retsize) {
515                             retsize = nret + 32;
516                             ret = sresize(ret, retsize, struct set *);
517                         }
518                         ret[nret++] = s;
519                     }
520
521                     pos++;
522                 }
523             }
524         }
525
526     ret = sresize(ret, nret+1, struct set *);
527     ret[nret] = NULL;
528
529     return ret;
530 }
531
532 /*
533  * Get an element from the head of the set todo list.
534  */
535 static struct set *ss_todo(struct setstore *ss)
536 {
537     if (ss->todo_head) {
538         struct set *ret = ss->todo_head;
539         ss->todo_head = ret->next;
540         if (ss->todo_head)
541             ss->todo_head->prev = NULL;
542         else
543             ss->todo_tail = NULL;
544         ret->next = ret->prev = NULL;
545         ret->todo = FALSE;
546         return ret;
547     } else {
548         return NULL;
549     }
550 }
551
552 struct squaretodo {
553     int *next;
554     int head, tail;
555 };
556
557 static void std_add(struct squaretodo *std, int i)
558 {
559     if (std->tail >= 0)
560         std->next[std->tail] = i;
561     else
562         std->head = i;
563     std->tail = i;
564     std->next[i] = -1;
565 }
566
567 typedef int (*open_cb)(void *, int, int);
568
569 static void known_squares(int w, int h, struct squaretodo *std,
570                           signed char *grid,
571                           open_cb open, void *openctx,
572                           int x, int y, int mask, int mine)
573 {
574     int xx, yy, bit;
575
576     bit = 1;
577
578     for (yy = 0; yy < 3; yy++)
579         for (xx = 0; xx < 3; xx++) {
580             if (mask & bit) {
581                 int i = (y + yy) * w + (x + xx);
582
583                 /*
584                  * It's possible that this square is _already_
585                  * known, in which case we don't try to add it to
586                  * the list twice.
587                  */
588                 if (grid[i] == -2) {
589
590                     if (mine) {
591                         grid[i] = -1;   /* and don't open it! */
592                     } else {
593                         grid[i] = open(openctx, x + xx, y + yy);
594                         assert(grid[i] != -1);   /* *bang* */
595                     }
596                     std_add(std, i);
597
598                 }
599             }
600             bit <<= 1;
601         }
602 }
603
604 /*
605  * This is data returned from the `perturb' function. It details
606  * which squares have become mines and which have become clear. The
607  * solver is (of course) expected to honourably not use that
608  * knowledge directly, but to efficently adjust its internal data
609  * structures and proceed based on only the information it
610  * legitimately has.
611  */
612 struct perturbation {
613     int x, y;
614     int delta;                         /* +1 == become a mine; -1 == cleared */
615 };
616 struct perturbations {
617     int n;
618     struct perturbation *changes;
619 };
620
621 /*
622  * Main solver entry point. You give it a grid of existing
623  * knowledge (-1 for a square known to be a mine, 0-8 for empty
624  * squares with a given number of neighbours, -2 for completely
625  * unknown), plus a function which you can call to open new squares
626  * once you're confident of them. It fills in as much more of the
627  * grid as it can.
628  * 
629  * Return value is:
630  * 
631  *  - -1 means deduction stalled and nothing could be done
632  *  - 0 means deduction succeeded fully
633  *  - >0 means deduction succeeded but some number of perturbation
634  *    steps were required; the exact return value is the number of
635  *    perturb calls.
636  */
637
638 typedef struct perturbations *(*perturb_cb) (void *, signed char *, int, int, int);
639
640 static int minesolve(int w, int h, int n, signed char *grid,
641                      open_cb open,
642                      perturb_cb perturb,
643                      void *ctx, random_state *rs)
644 {
645     struct setstore *ss = ss_new();
646     struct set **list;
647     struct squaretodo astd, *std = &astd;
648     int x, y, i, j;
649     int nperturbs = 0;
650
651     /*
652      * Set up a linked list of squares with known contents, so that
653      * we can process them one by one.
654      */
655     std->next = snewn(w*h, int);
656     std->head = std->tail = -1;
657
658     /*
659      * Initialise that list with all known squares in the input
660      * grid.
661      */
662     for (y = 0; y < h; y++) {
663         for (x = 0; x < w; x++) {
664             i = y*w+x;
665             if (grid[i] != -2)
666                 std_add(std, i);
667         }
668     }
669
670     /*
671      * Main deductive loop.
672      */
673     while (1) {
674         int done_something = FALSE;
675         struct set *s;
676
677         /*
678          * If there are any known squares on the todo list, process
679          * them and construct a set for each.
680          */
681         while (std->head != -1) {
682             i = std->head;
683 #ifdef SOLVER_DIAGNOSTICS
684             printf("known square at %d,%d [%d]\n", i%w, i/w, grid[i]);
685 #endif
686             std->head = std->next[i];
687             if (std->head == -1)
688                 std->tail = -1;
689
690             x = i % w;
691             y = i / w;
692
693             if (grid[i] >= 0) {
694                 int dx, dy, mines, bit, val;
695 #ifdef SOLVER_DIAGNOSTICS
696                 printf("creating set around this square\n");
697 #endif
698                 /*
699                  * Empty square. Construct the set of non-known squares
700                  * around this one, and determine its mine count.
701                  */
702                 mines = grid[i];
703                 bit = 1;
704                 val = 0;
705                 for (dy = -1; dy <= +1; dy++) {
706                     for (dx = -1; dx <= +1; dx++) {
707 #ifdef SOLVER_DIAGNOSTICS
708                         printf("grid %d,%d = %d\n", x+dx, y+dy, grid[i+dy*w+dx]);
709 #endif
710                         if (x+dx < 0 || x+dx >= w || y+dy < 0 || y+dy >= h)
711                             /* ignore this one */;
712                         else if (grid[i+dy*w+dx] == -1)
713                             mines--;
714                         else if (grid[i+dy*w+dx] == -2)
715                             val |= bit;
716                         bit <<= 1;
717                     }
718                 }
719                 if (val)
720                     ss_add(ss, x-1, y-1, val, mines);
721             }
722
723             /*
724              * Now, whether the square is empty or full, we must
725              * find any set which contains it and replace it with
726              * one which does not.
727              */
728             {
729 #ifdef SOLVER_DIAGNOSTICS
730                 printf("finding sets containing known square %d,%d\n", x, y);
731 #endif
732                 list = ss_overlap(ss, x, y, 1);
733
734                 for (j = 0; list[j]; j++) {
735                     int newmask, newmines;
736
737                     s = list[j];
738
739                     /*
740                      * Compute the mask for this set minus the
741                      * newly known square.
742                      */
743                     newmask = setmunge(s->x, s->y, s->mask, x, y, 1, TRUE);
744
745                     /*
746                      * Compute the new mine count.
747                      */
748                     newmines = s->mines - (grid[i] == -1);
749
750                     /*
751                      * Insert the new set into the collection,
752                      * unless it's been whittled right down to
753                      * nothing.
754                      */
755                     if (newmask)
756                         ss_add(ss, s->x, s->y, newmask, newmines);
757
758                     /*
759                      * Destroy the old one; it is actually obsolete.
760                      */
761                     ss_remove(ss, s);
762                 }
763
764                 sfree(list);
765             }
766
767             /*
768              * Marking a fresh square as known certainly counts as
769              * doing something.
770              */
771             done_something = TRUE;
772         }
773
774         /*
775          * Now pick a set off the to-do list and attempt deductions
776          * based on it.
777          */
778         if ((s = ss_todo(ss)) != NULL) {
779
780 #ifdef SOLVER_DIAGNOSTICS
781             printf("set to do: %d,%d %03x %d\n", s->x, s->y, s->mask, s->mines);
782 #endif
783             /*
784              * Firstly, see if this set has a mine count of zero or
785              * of its own cardinality.
786              */
787             if (s->mines == 0 || s->mines == bitcount16(s->mask)) {
788                 /*
789                  * If so, we can immediately mark all the squares
790                  * in the set as known.
791                  */
792 #ifdef SOLVER_DIAGNOSTICS
793                 printf("easy\n");
794 #endif
795                 known_squares(w, h, std, grid, open, ctx,
796                               s->x, s->y, s->mask, (s->mines != 0));
797
798                 /*
799                  * Having done that, we need do nothing further
800                  * with this set; marking all the squares in it as
801                  * known will eventually eliminate it, and will
802                  * also permit further deductions about anything
803                  * that overlaps it.
804                  */
805                 continue;
806             }
807
808             /*
809              * Failing that, we now search through all the sets
810              * which overlap this one.
811              */
812             list = ss_overlap(ss, s->x, s->y, s->mask);
813
814             for (j = 0; list[j]; j++) {
815                 struct set *s2 = list[j];
816                 int swing, s2wing, swc, s2wc;
817
818                 /*
819                  * Find the non-overlapping parts s2-s and s-s2,
820                  * and their cardinalities.
821                  * 
822                  * I'm going to refer to these parts as `wings'
823                  * surrounding the central part common to both
824                  * sets. The `s wing' is s-s2; the `s2 wing' is
825                  * s2-s.
826                  */
827                 swing = setmunge(s->x, s->y, s->mask, s2->x, s2->y, s2->mask,
828                                  TRUE);
829                 s2wing = setmunge(s2->x, s2->y, s2->mask, s->x, s->y, s->mask,
830                                  TRUE);
831                 swc = bitcount16(swing);
832                 s2wc = bitcount16(s2wing);
833
834                 /*
835                  * If one set has more mines than the other, and
836                  * the number of extra mines is equal to the
837                  * cardinality of that set's wing, then we can mark
838                  * every square in the wing as a known mine, and
839                  * every square in the other wing as known clear.
840                  */
841                 if (swc == s->mines - s2->mines ||
842                     s2wc == s2->mines - s->mines) {
843                     known_squares(w, h, std, grid, open, ctx,
844                                   s->x, s->y, swing,
845                                   (swc == s->mines - s2->mines));
846                     known_squares(w, h, std, grid, open, ctx,
847                                   s2->x, s2->y, s2wing,
848                                   (s2wc == s2->mines - s->mines));
849                     continue;
850                 }
851
852                 /*
853                  * Failing that, see if one set is a subset of the
854                  * other. If so, we can divide up the mine count of
855                  * the larger set between the smaller set and its
856                  * complement, even if neither smaller set ends up
857                  * being immediately clearable.
858                  */
859                 if (swc == 0 && s2wc != 0) {
860                     /* s is a subset of s2. */
861                     assert(s2->mines > s->mines);
862                     ss_add(ss, s2->x, s2->y, s2wing, s2->mines - s->mines);
863                 } else if (s2wc == 0 && swc != 0) {
864                     /* s2 is a subset of s. */
865                     assert(s->mines > s2->mines);
866                     ss_add(ss, s->x, s->y, swing, s->mines - s2->mines);
867                 }
868             }
869
870             sfree(list);
871
872             /*
873              * In this situation we have definitely done
874              * _something_, even if it's only reducing the size of
875              * our to-do list.
876              */
877             done_something = TRUE;
878         } else if (n >= 0) {
879             /*
880              * We have nothing left on our todo list, which means
881              * all localised deductions have failed. Our next step
882              * is to resort to global deduction based on the total
883              * mine count. This is computationally expensive
884              * compared to any of the above deductions, which is
885              * why we only ever do it when all else fails, so that
886              * hopefully it won't have to happen too often.
887              * 
888              * If you pass n<0 into this solver, that informs it
889              * that you do not know the total mine count, so it
890              * won't even attempt these deductions.
891              */
892
893             int minesleft, squaresleft;
894             int nsets, setused[10], cursor;
895
896             /*
897              * Start by scanning the current grid state to work out
898              * how many unknown squares we still have, and how many
899              * mines are to be placed in them.
900              */
901             squaresleft = 0;
902             minesleft = n;
903             for (i = 0; i < w*h; i++) {
904                 if (grid[i] == -1)
905                     minesleft--;
906                 else if (grid[i] == -2)
907                     squaresleft++;
908             }
909
910 #ifdef SOLVER_DIAGNOSTICS
911             printf("global deduction time: squaresleft=%d minesleft=%d\n",
912                    squaresleft, minesleft);
913             for (y = 0; y < h; y++) {
914                 for (x = 0; x < w; x++) {
915                     int v = grid[y*w+x];
916                     if (v == -1)
917                         putchar('*');
918                     else if (v == -2)
919                         putchar('?');
920                     else if (v == 0)
921                         putchar('-');
922                     else
923                         putchar('0' + v);
924                 }
925                 putchar('\n');
926             }
927 #endif
928
929             /*
930              * If there _are_ no unknown squares, we have actually
931              * finished.
932              */
933             if (squaresleft == 0) {
934                 assert(minesleft == 0);
935                 break;
936             }
937
938             /*
939              * First really simple case: if there are no more mines
940              * left, or if there are exactly as many mines left as
941              * squares to play them in, then it's all easy.
942              */
943             if (minesleft == 0 || minesleft == squaresleft) {
944                 for (i = 0; i < w*h; i++)
945                     if (grid[i] == -2)
946                         known_squares(w, h, std, grid, open, ctx,
947                                       i % w, i / w, 1, minesleft != 0);
948                 continue;              /* now go back to main deductive loop */
949             }
950
951             /*
952              * Failing that, we have to do some _real_ work.
953              * Ideally what we do here is to try every single
954              * combination of the currently available sets, in an
955              * attempt to find a disjoint union (i.e. a set of
956              * squares with a known mine count between them) such
957              * that the remaining unknown squares _not_ contained
958              * in that union either contain no mines or are all
959              * mines.
960              * 
961              * Actually enumerating all 2^n possibilities will get
962              * a bit slow for large n, so I artificially cap this
963              * recursion at n=10 to avoid too much pain.
964              */
965             nsets = count234(ss->sets);
966             if (nsets <= lenof(setused)) {
967                 /*
968                  * Doing this with actual recursive function calls
969                  * would get fiddly because a load of local
970                  * variables from this function would have to be
971                  * passed down through the recursion. So instead
972                  * I'm going to use a virtual recursion within this
973                  * function. The way this works is:
974                  * 
975                  *  - we have an array `setused', such that
976                  *    setused[n] is 0 or 1 depending on whether set
977                  *    n is currently in the union we are
978                  *    considering.
979                  * 
980                  *  - we have a value `cursor' which indicates how
981                  *    much of `setused' we have so far filled in.
982                  *    It's conceptually the recursion depth.
983                  * 
984                  * We begin by setting `cursor' to zero. Then:
985                  * 
986                  *  - if cursor can advance, we advance it by one.
987                  *    We set the value in `setused' that it went
988                  *    past to 1 if that set is disjoint from
989                  *    anything else currently in `setused', or to 0
990                  *    otherwise.
991                  * 
992                  *  - If cursor cannot advance because it has
993                  *    reached the end of the setused list, then we
994                  *    have a maximal disjoint union. Check to see
995                  *    whether its mine count has any useful
996                  *    properties. If so, mark all the squares not
997                  *    in the union as known and terminate.
998                  * 
999                  *  - If cursor has reached the end of setused and
1000                  *    the algorithm _hasn't_ terminated, back
1001                  *    cursor up to the nearest 1, turn it into a 0
1002                  *    and advance cursor just past it.
1003                  * 
1004                  *  - If we attempt to back up to the nearest 1 and
1005                  *    there isn't one at all, then we have gone
1006                  *    through all disjoint unions of sets in the
1007                  *    list and none of them has been helpful, so we
1008                  *    give up.
1009                  */
1010                 struct set *sets[lenof(setused)];
1011                 for (i = 0; i < nsets; i++)
1012                     sets[i] = index234(ss->sets, i);
1013
1014                 cursor = 0;
1015                 while (1) {
1016
1017                     if (cursor < nsets) {
1018                         int ok = TRUE;
1019
1020                         /* See if any existing set overlaps this one. */
1021                         for (i = 0; i < cursor; i++)
1022                             if (setused[i] &&
1023                                 setmunge(sets[cursor]->x,
1024                                          sets[cursor]->y,
1025                                          sets[cursor]->mask,
1026                                          sets[i]->x, sets[i]->y, sets[i]->mask,
1027                                          FALSE)) {
1028                                 ok = FALSE;
1029                                 break;
1030                             }
1031
1032                         if (ok) {
1033                             /*
1034                              * We're adding this set to our union,
1035                              * so adjust minesleft and squaresleft
1036                              * appropriately.
1037                              */
1038                             minesleft -= sets[cursor]->mines;
1039                             squaresleft -= bitcount16(sets[cursor]->mask);
1040                         }
1041
1042                         setused[cursor++] = ok;
1043                     } else {
1044 #ifdef SOLVER_DIAGNOSTICS
1045                         printf("trying a set combination with %d %d\n",
1046                                squaresleft, minesleft);
1047 #endif /* SOLVER_DIAGNOSTICS */
1048
1049                         /*
1050                          * We've reached the end. See if we've got
1051                          * anything interesting.
1052                          */
1053                         if (squaresleft > 0 &&
1054                             (minesleft == 0 || minesleft == squaresleft)) {
1055                             /*
1056                              * We have! There is at least one
1057                              * square not contained within the set
1058                              * union we've just found, and we can
1059                              * deduce that either all such squares
1060                              * are mines or all are not (depending
1061                              * on whether minesleft==0). So now all
1062                              * we have to do is actually go through
1063                              * the grid, find those squares, and
1064                              * mark them.
1065                              */
1066                             for (i = 0; i < w*h; i++)
1067                                 if (grid[i] == -2) {
1068                                     int outside = TRUE;
1069                                     y = i / w;
1070                                     x = i % w;
1071                                     for (j = 0; j < nsets; j++)
1072                                         if (setused[j] &&
1073                                             setmunge(sets[j]->x, sets[j]->y,
1074                                                      sets[j]->mask, x, y, 1,
1075                                                      FALSE)) {
1076                                             outside = FALSE;
1077                                             break;
1078                                         }
1079                                     if (outside)
1080                                         known_squares(w, h, std, grid,
1081                                                       open, ctx,
1082                                                       x, y, 1, minesleft != 0);
1083                                 }
1084
1085                             done_something = TRUE;
1086                             break;     /* return to main deductive loop */
1087                         }
1088
1089                         /*
1090                          * If we reach here, then this union hasn't
1091                          * done us any good, so move on to the
1092                          * next. Backtrack cursor to the nearest 1,
1093                          * change it to a 0 and continue.
1094                          */
1095                         while (--cursor >= 0 && !setused[cursor]);
1096                         if (cursor >= 0) {
1097                             assert(setused[cursor]);
1098
1099                             /*
1100                              * We're removing this set from our
1101                              * union, so re-increment minesleft and
1102                              * squaresleft.
1103                              */
1104                             minesleft += sets[cursor]->mines;
1105                             squaresleft += bitcount16(sets[cursor]->mask);
1106
1107                             setused[cursor++] = 0;
1108                         } else {
1109                             /*
1110                              * We've backtracked all the way to the
1111                              * start without finding a single 1,
1112                              * which means that our virtual
1113                              * recursion is complete and nothing
1114                              * helped.
1115                              */
1116                             break;
1117                         }
1118                     }
1119
1120                 }
1121
1122             }
1123         }
1124
1125         if (done_something)
1126             continue;
1127
1128 #ifdef SOLVER_DIAGNOSTICS
1129         /*
1130          * Dump the current known state of the grid.
1131          */
1132         printf("solver ran out of steam, ret=%d, grid:\n", nperturbs);
1133         for (y = 0; y < h; y++) {
1134             for (x = 0; x < w; x++) {
1135                 int v = grid[y*w+x];
1136                 if (v == -1)
1137                     putchar('*');
1138                 else if (v == -2)
1139                     putchar('?');
1140                 else if (v == 0)
1141                     putchar('-');
1142                 else
1143                     putchar('0' + v);
1144             }
1145             putchar('\n');
1146         }
1147
1148         {
1149             struct set *s;
1150
1151             for (i = 0; (s = index234(ss->sets, i)) != NULL; i++)
1152                 printf("remaining set: %d,%d %03x %d\n", s->x, s->y, s->mask, s->mines);
1153         }
1154 #endif
1155
1156         /*
1157          * Now we really are at our wits' end as far as solving
1158          * this grid goes. Our only remaining option is to call
1159          * a perturb function and ask it to modify the grid to
1160          * make it easier.
1161          */
1162         if (perturb) {
1163             struct perturbations *ret;
1164             struct set *s;
1165
1166             nperturbs++;
1167
1168             /*
1169              * Choose a set at random from the current selection,
1170              * and ask the perturb function to either fill or empty
1171              * it.
1172              * 
1173              * If we have no sets at all, we must give up.
1174              */
1175             if (count234(ss->sets) == 0) {
1176 #ifdef SOLVER_DIAGNOSTICS
1177                 printf("perturbing on entire unknown set\n");
1178 #endif
1179                 ret = perturb(ctx, grid, 0, 0, 0);
1180             } else {
1181                 s = index234(ss->sets, random_upto(rs, count234(ss->sets)));
1182 #ifdef SOLVER_DIAGNOSTICS
1183                 printf("perturbing on set %d,%d %03x\n", s->x, s->y, s->mask);
1184 #endif
1185                 ret = perturb(ctx, grid, s->x, s->y, s->mask);
1186             }
1187
1188             if (ret) {
1189                 assert(ret->n > 0);    /* otherwise should have been NULL */
1190
1191                 /*
1192                  * A number of squares have been fiddled with, and
1193                  * the returned structure tells us which. Adjust
1194                  * the mine count in any set which overlaps one of
1195                  * those squares, and put them back on the to-do
1196                  * list. Also, if the square itself is marked as a
1197                  * known non-mine, put it back on the squares-to-do
1198                  * list.
1199                  */
1200                 for (i = 0; i < ret->n; i++) {
1201 #ifdef SOLVER_DIAGNOSTICS
1202                     printf("perturbation %s mine at %d,%d\n",
1203                            ret->changes[i].delta > 0 ? "added" : "removed",
1204                            ret->changes[i].x, ret->changes[i].y);
1205 #endif
1206
1207                     if (ret->changes[i].delta < 0 &&
1208                         grid[ret->changes[i].y*w+ret->changes[i].x] != -2) {
1209                         std_add(std, ret->changes[i].y*w+ret->changes[i].x);
1210                     }
1211
1212                     list = ss_overlap(ss,
1213                                       ret->changes[i].x, ret->changes[i].y, 1);
1214
1215                     for (j = 0; list[j]; j++) {
1216                         list[j]->mines += ret->changes[i].delta;
1217                         ss_add_todo(ss, list[j]);
1218                     }
1219
1220                     sfree(list);
1221                 }
1222
1223                 /*
1224                  * Now free the returned data.
1225                  */
1226                 sfree(ret->changes);
1227                 sfree(ret);
1228
1229 #ifdef SOLVER_DIAGNOSTICS
1230                 /*
1231                  * Dump the current known state of the grid.
1232                  */
1233                 printf("state after perturbation:\n");
1234                 for (y = 0; y < h; y++) {
1235                     for (x = 0; x < w; x++) {
1236                         int v = grid[y*w+x];
1237                         if (v == -1)
1238                             putchar('*');
1239                         else if (v == -2)
1240                             putchar('?');
1241                         else if (v == 0)
1242                             putchar('-');
1243                         else
1244                             putchar('0' + v);
1245                     }
1246                     putchar('\n');
1247                 }
1248
1249                 {
1250                     struct set *s;
1251
1252                     for (i = 0; (s = index234(ss->sets, i)) != NULL; i++)
1253                         printf("remaining set: %d,%d %03x %d\n", s->x, s->y, s->mask, s->mines);
1254                 }
1255 #endif
1256
1257                 /*
1258                  * And now we can go back round the deductive loop.
1259                  */
1260                 continue;
1261             }
1262         }
1263
1264         /*
1265          * If we get here, even that didn't work (either we didn't
1266          * have a perturb function or it returned failure), so we
1267          * give up entirely.
1268          */
1269         break;
1270     }
1271
1272     /*
1273      * See if we've got any unknown squares left.
1274      */
1275     for (y = 0; y < h; y++)
1276         for (x = 0; x < w; x++)
1277             if (grid[y*w+x] == -2) {
1278                 nperturbs = -1;        /* failed to complete */
1279                 break;
1280             }
1281
1282     /*
1283      * Free the set list and square-todo list.
1284      */
1285     {
1286         struct set *s;
1287         while ((s = delpos234(ss->sets, 0)) != NULL)
1288             sfree(s);
1289         freetree234(ss->sets);
1290         sfree(ss);
1291         sfree(std->next);
1292     }
1293
1294     return nperturbs;
1295 }
1296
1297 /* ----------------------------------------------------------------------
1298  * Grid generator which uses the above solver.
1299  */
1300
1301 struct minectx {
1302     char *grid;
1303     int w, h;
1304     int sx, sy;
1305     int allow_big_perturbs;
1306     random_state *rs;
1307 };
1308
1309 static int mineopen(void *vctx, int x, int y)
1310 {
1311     struct minectx *ctx = (struct minectx *)vctx;
1312     int i, j, n;
1313
1314     assert(x >= 0 && x < ctx->w && y >= 0 && y < ctx->h);
1315     if (ctx->grid[y * ctx->w + x])
1316         return -1;                     /* *bang* */
1317
1318     n = 0;
1319     for (i = -1; i <= +1; i++) {
1320         if (x + i < 0 || x + i >= ctx->w)
1321             continue;
1322         for (j = -1; j <= +1; j++) {
1323             if (y + j < 0 || y + j >= ctx->h)
1324                 continue;
1325             if (i == 0 && j == 0)
1326                 continue;
1327             if (ctx->grid[(y+j) * ctx->w + (x+i)])
1328                 n++;
1329         }
1330     }
1331
1332     return n;
1333 }
1334
1335 /* Structure used internally to mineperturb(). */
1336 struct square {
1337     int x, y, type, random;
1338 };
1339 static int squarecmp(const void *av, const void *bv)
1340 {
1341     const struct square *a = (const struct square *)av;
1342     const struct square *b = (const struct square *)bv;
1343     if (a->type < b->type)
1344         return -1;
1345     else if (a->type > b->type)
1346         return +1;
1347     else if (a->random < b->random)
1348         return -1;
1349     else if (a->random > b->random)
1350         return +1;
1351     else if (a->y < b->y)
1352         return -1;
1353     else if (a->y > b->y)
1354         return +1;
1355     else if (a->x < b->x)
1356         return -1;
1357     else if (a->x > b->x)
1358         return +1;
1359     return 0;
1360 }
1361
1362 /*
1363  * Normally this function is passed an (x,y,mask) set description.
1364  * On occasions, though, there is no _localised_ set being used,
1365  * and the set being perturbed is supposed to be the entirety of
1366  * the unreachable area. This is signified by the special case
1367  * mask==0: in this case, anything labelled -2 in the grid is part
1368  * of the set.
1369  * 
1370  * Allowing perturbation in this special case appears to make it
1371  * guaranteeably possible to generate a workable grid for any mine
1372  * density, but they tend to be a bit boring, with mines packed
1373  * densely into far corners of the grid and the remainder being
1374  * less dense than one might like. Therefore, to improve overall
1375  * grid quality I disable this feature for the first few attempts,
1376  * and fall back to it after no useful grid has been generated.
1377  */
1378 static struct perturbations *mineperturb(void *vctx, signed char *grid,
1379                                          int setx, int sety, int mask)
1380 {
1381     struct minectx *ctx = (struct minectx *)vctx;
1382     struct square *sqlist;
1383     int x, y, dx, dy, i, n, nfull, nempty;
1384     struct square **tofill, **toempty, **todo;
1385     int ntofill, ntoempty, ntodo, dtodo, dset;
1386     struct perturbations *ret;
1387     int *setlist;
1388
1389     if (!mask && !ctx->allow_big_perturbs)
1390         return NULL;
1391
1392     /*
1393      * Make a list of all the squares in the grid which we can
1394      * possibly use. This list should be in preference order, which
1395      * means
1396      * 
1397      *  - first, unknown squares on the boundary of known space
1398      *  - next, unknown squares beyond that boundary
1399      *  - as a very last resort, known squares, but not within one
1400      *    square of the starting position.
1401      * 
1402      * Each of these sections needs to be shuffled independently.
1403      * We do this by preparing list of all squares and then sorting
1404      * it with a random secondary key.
1405      */
1406     sqlist = snewn(ctx->w * ctx->h, struct square);
1407     n = 0;
1408     for (y = 0; y < ctx->h; y++)
1409         for (x = 0; x < ctx->w; x++) {
1410             /*
1411              * If this square is too near the starting position,
1412              * don't put it on the list at all.
1413              */
1414             if (abs(y - ctx->sy) <= 1 && abs(x - ctx->sx) <= 1)
1415                 continue;
1416
1417             /*
1418              * If this square is in the input set, also don't put
1419              * it on the list!
1420              */
1421             if ((mask == 0 && grid[y*ctx->w+x] == -2) ||
1422                 (x >= setx && x < setx + 3 &&
1423                  y >= sety && y < sety + 3 &&
1424                  mask & (1 << ((y-sety)*3+(x-setx)))))
1425                 continue;
1426
1427             sqlist[n].x = x;
1428             sqlist[n].y = y;
1429
1430             if (grid[y*ctx->w+x] != -2) {
1431                 sqlist[n].type = 3;    /* known square */
1432             } else {
1433                 /*
1434                  * Unknown square. Examine everything around it and
1435                  * see if it borders on any known squares. If it
1436                  * does, it's class 1, otherwise it's 2.
1437                  */
1438
1439                 sqlist[n].type = 2;
1440
1441                 for (dy = -1; dy <= +1; dy++)
1442                     for (dx = -1; dx <= +1; dx++)
1443                         if (x+dx >= 0 && x+dx < ctx->w &&
1444                             y+dy >= 0 && y+dy < ctx->h &&
1445                             grid[(y+dy)*ctx->w+(x+dx)] != -2) {
1446                             sqlist[n].type = 1;
1447                             break;
1448                         }
1449             }
1450
1451             /*
1452              * Finally, a random number to cause qsort to
1453              * shuffle within each group.
1454              */
1455             sqlist[n].random = random_bits(ctx->rs, 31);
1456
1457             n++;
1458         }
1459
1460     qsort(sqlist, n, sizeof(struct square), squarecmp);
1461
1462     /*
1463      * Now count up the number of full and empty squares in the set
1464      * we've been provided.
1465      */
1466     nfull = nempty = 0;
1467     if (mask) {
1468         for (dy = 0; dy < 3; dy++)
1469             for (dx = 0; dx < 3; dx++)
1470                 if (mask & (1 << (dy*3+dx))) {
1471                     assert(setx+dx <= ctx->w);
1472                     assert(sety+dy <= ctx->h);
1473                     if (ctx->grid[(sety+dy)*ctx->w+(setx+dx)])
1474                         nfull++;
1475                     else
1476                         nempty++;
1477                 }
1478     } else {
1479         for (y = 0; y < ctx->h; y++)
1480             for (x = 0; x < ctx->w; x++)
1481                 if (grid[y*ctx->w+x] == -2) {
1482                     if (ctx->grid[y*ctx->w+x])
1483                         nfull++;
1484                     else
1485                         nempty++;
1486                 }
1487     }
1488
1489     /*
1490      * Now go through our sorted list until we find either `nfull'
1491      * empty squares, or `nempty' full squares; these will be
1492      * swapped with the appropriate squares in the set to either
1493      * fill or empty the set while keeping the same number of mines
1494      * overall.
1495      */
1496     ntofill = ntoempty = 0;
1497     if (mask) {
1498         tofill = snewn(9, struct square *);
1499         toempty = snewn(9, struct square *);
1500     } else {
1501         tofill = snewn(ctx->w * ctx->h, struct square *);
1502         toempty = snewn(ctx->w * ctx->h, struct square *);
1503     }
1504     for (i = 0; i < n; i++) {
1505         struct square *sq = &sqlist[i];
1506         if (ctx->grid[sq->y * ctx->w + sq->x])
1507             toempty[ntoempty++] = sq;
1508         else
1509             tofill[ntofill++] = sq;
1510         if (ntofill == nfull || ntoempty == nempty)
1511             break;
1512     }
1513
1514     /*
1515      * If we haven't found enough empty squares outside the set to
1516      * empty it into _or_ enough full squares outside it to fill it
1517      * up with, we'll have to settle for doing only a partial job.
1518      * In this case we choose to always _fill_ the set (because
1519      * this case will tend to crop up when we're working with very
1520      * high mine densities and the only way to get a solvable grid
1521      * is going to be to pack most of the mines solidly around the
1522      * edges). So now our job is to make a list of the empty
1523      * squares in the set, and shuffle that list so that we fill a
1524      * random selection of them.
1525      */
1526     if (ntofill != nfull && ntoempty != nempty) {
1527         int k;
1528
1529         assert(ntoempty != 0);
1530
1531         setlist = snewn(ctx->w * ctx->h, int);
1532         i = 0;
1533         if (mask) {
1534             for (dy = 0; dy < 3; dy++)
1535                 for (dx = 0; dx < 3; dx++)
1536                     if (mask & (1 << (dy*3+dx))) {
1537                         assert(setx+dx <= ctx->w);
1538                         assert(sety+dy <= ctx->h);
1539                         if (!ctx->grid[(sety+dy)*ctx->w+(setx+dx)])
1540                             setlist[i++] = (sety+dy)*ctx->w+(setx+dx);
1541                     }
1542         } else {
1543             for (y = 0; y < ctx->h; y++)
1544                 for (x = 0; x < ctx->w; x++)
1545                     if (grid[y*ctx->w+x] == -2) {
1546                         if (!ctx->grid[y*ctx->w+x])
1547                             setlist[i++] = y*ctx->w+x;
1548                     }
1549         }
1550         assert(i > ntoempty);
1551         /*
1552          * Now pick `ntoempty' items at random from the list.
1553          */
1554         for (k = 0; k < ntoempty; k++) {
1555             int index = k + random_upto(ctx->rs, i - k);
1556             int tmp;
1557
1558             tmp = setlist[k];
1559             setlist[k] = setlist[index];
1560             setlist[index] = tmp;
1561         }
1562     } else
1563         setlist = NULL;
1564
1565     /*
1566      * Now we're pretty much there. We need to either
1567      *  (a) put a mine in each of the empty squares in the set, and
1568      *      take one out of each square in `toempty'
1569      *  (b) take a mine out of each of the full squares in the set,
1570      *      and put one in each square in `tofill'
1571      * depending on which one we've found enough squares to do.
1572      * 
1573      * So we start by constructing our list of changes to return to
1574      * the solver, so that it can update its data structures
1575      * efficiently rather than having to rescan the whole grid.
1576      */
1577     ret = snew(struct perturbations);
1578     if (ntofill == nfull) {
1579         todo = tofill;
1580         ntodo = ntofill;
1581         dtodo = +1;
1582         dset = -1;
1583         sfree(toempty);
1584     } else {
1585         /*
1586          * (We also fall into this case if we've constructed a
1587          * setlist.)
1588          */
1589         todo = toempty;
1590         ntodo = ntoempty;
1591         dtodo = -1;
1592         dset = +1;
1593         sfree(tofill);
1594     }
1595     ret->n = 2 * ntodo;
1596     ret->changes = snewn(ret->n, struct perturbation);
1597     for (i = 0; i < ntodo; i++) {
1598         ret->changes[i].x = todo[i]->x;
1599         ret->changes[i].y = todo[i]->y;
1600         ret->changes[i].delta = dtodo;
1601     }
1602     /* now i == ntodo */
1603     if (setlist) {
1604         int j;
1605         assert(todo == toempty);
1606         for (j = 0; j < ntoempty; j++) {
1607             ret->changes[i].x = setlist[j] % ctx->w;
1608             ret->changes[i].y = setlist[j] / ctx->w;
1609             ret->changes[i].delta = dset;
1610             i++;
1611         }
1612         sfree(setlist);
1613     } else if (mask) {
1614         for (dy = 0; dy < 3; dy++)
1615             for (dx = 0; dx < 3; dx++)
1616                 if (mask & (1 << (dy*3+dx))) {
1617                     int currval = (ctx->grid[(sety+dy)*ctx->w+(setx+dx)] ? +1 : -1);
1618                     if (dset == -currval) {
1619                         ret->changes[i].x = setx + dx;
1620                         ret->changes[i].y = sety + dy;
1621                         ret->changes[i].delta = dset;
1622                         i++;
1623                     }
1624                 }
1625     } else {
1626         for (y = 0; y < ctx->h; y++)
1627             for (x = 0; x < ctx->w; x++)
1628                 if (grid[y*ctx->w+x] == -2) {
1629                     int currval = (ctx->grid[y*ctx->w+x] ? +1 : -1);
1630                     if (dset == -currval) {
1631                         ret->changes[i].x = x;
1632                         ret->changes[i].y = y;
1633                         ret->changes[i].delta = dset;
1634                         i++;
1635                     }
1636                 }
1637     }
1638     assert(i == ret->n);
1639
1640     sfree(sqlist);
1641     sfree(todo);
1642
1643     /*
1644      * Having set up the precise list of changes we're going to
1645      * make, we now simply make them and return.
1646      */
1647     for (i = 0; i < ret->n; i++) {
1648         int delta;
1649
1650         x = ret->changes[i].x;
1651         y = ret->changes[i].y;
1652         delta = ret->changes[i].delta;
1653
1654         /*
1655          * Check we're not trying to add an existing mine or remove
1656          * an absent one.
1657          */
1658         assert((delta < 0) ^ (ctx->grid[y*ctx->w+x] == 0));
1659
1660         /*
1661          * Actually make the change.
1662          */
1663         ctx->grid[y*ctx->w+x] = (delta > 0);
1664
1665         /*
1666          * Update any numbers already present in the grid.
1667          */
1668         for (dy = -1; dy <= +1; dy++)
1669             for (dx = -1; dx <= +1; dx++)
1670                 if (x+dx >= 0 && x+dx < ctx->w &&
1671                     y+dy >= 0 && y+dy < ctx->h &&
1672                     grid[(y+dy)*ctx->w+(x+dx)] != -2) {
1673                     if (dx == 0 && dy == 0) {
1674                         /*
1675                          * The square itself is marked as known in
1676                          * the grid. Mark it as a mine if it's a
1677                          * mine, or else work out its number.
1678                          */
1679                         if (delta > 0) {
1680                             grid[y*ctx->w+x] = -1;
1681                         } else {
1682                             int dx2, dy2, minecount = 0;
1683                             for (dy2 = -1; dy2 <= +1; dy2++)
1684                                 for (dx2 = -1; dx2 <= +1; dx2++)
1685                                     if (x+dx2 >= 0 && x+dx2 < ctx->w &&
1686                                         y+dy2 >= 0 && y+dy2 < ctx->h &&
1687                                         ctx->grid[(y+dy2)*ctx->w+(x+dx2)])
1688                                         minecount++;
1689                             grid[y*ctx->w+x] = minecount;
1690                         }
1691                     } else {
1692                         if (grid[(y+dy)*ctx->w+(x+dx)] >= 0)
1693                             grid[(y+dy)*ctx->w+(x+dx)] += delta;
1694                     }
1695                 }
1696     }
1697
1698 #ifdef GENERATION_DIAGNOSTICS
1699     {
1700         int yy, xx;
1701         printf("grid after perturbing:\n");
1702         for (yy = 0; yy < ctx->h; yy++) {
1703             for (xx = 0; xx < ctx->w; xx++) {
1704                 int v = ctx->grid[yy*ctx->w+xx];
1705                 if (yy == ctx->sy && xx == ctx->sx) {
1706                     assert(!v);
1707                     putchar('S');
1708                 } else if (v) {
1709                     putchar('*');
1710                 } else {
1711                     putchar('-');
1712                 }
1713             }
1714             putchar('\n');
1715         }
1716         printf("\n");
1717     }
1718 #endif
1719
1720     return ret;
1721 }
1722
1723 static char *minegen(int w, int h, int n, int x, int y, int unique,
1724                      random_state *rs)
1725 {
1726     char *ret = snewn(w*h, char);
1727     int success;
1728     int ntries = 0;
1729
1730     do {
1731         success = FALSE;
1732         ntries++;
1733
1734         memset(ret, 0, w*h);
1735
1736         /*
1737          * Start by placing n mines, none of which is at x,y or within
1738          * one square of it.
1739          */
1740         {
1741             int *tmp = snewn(w*h, int);
1742             int i, j, k, nn;
1743
1744             /*
1745              * Write down the list of possible mine locations.
1746              */
1747             k = 0;
1748             for (i = 0; i < h; i++)
1749                 for (j = 0; j < w; j++)
1750                     if (abs(i - y) > 1 || abs(j - x) > 1)
1751                         tmp[k++] = i*w+j;
1752
1753             /*
1754              * Now pick n off the list at random.
1755              */
1756             nn = n;
1757             while (nn-- > 0) {
1758                 i = random_upto(rs, k);
1759                 ret[tmp[i]] = 1;
1760                 tmp[i] = tmp[--k];
1761             }
1762
1763             sfree(tmp);
1764         }
1765
1766 #ifdef GENERATION_DIAGNOSTICS
1767         {
1768             int yy, xx;
1769             printf("grid after initial generation:\n");
1770             for (yy = 0; yy < h; yy++) {
1771                 for (xx = 0; xx < w; xx++) {
1772                     int v = ret[yy*w+xx];
1773                     if (yy == y && xx == x) {
1774                         assert(!v);
1775                         putchar('S');
1776                     } else if (v) {
1777                         putchar('*');
1778                     } else {
1779                         putchar('-');
1780                     }
1781                 }
1782                 putchar('\n');
1783             }
1784             printf("\n");
1785         }
1786 #endif
1787
1788         /*
1789          * Now set up a results grid to run the solver in, and a
1790          * context for the solver to open squares. Then run the solver
1791          * repeatedly; if the number of perturb steps ever goes up or
1792          * it ever returns -1, give up completely.
1793          *
1794          * We bypass this bit if we're not after a unique grid.
1795          */
1796         if (unique) {
1797             signed char *solvegrid = snewn(w*h, signed char);
1798             struct minectx actx, *ctx = &actx;
1799             int solveret, prevret = -2;
1800
1801             ctx->grid = ret;
1802             ctx->w = w;
1803             ctx->h = h;
1804             ctx->sx = x;
1805             ctx->sy = y;
1806             ctx->rs = rs;
1807             ctx->allow_big_perturbs = (ntries > 100);
1808
1809             while (1) {
1810                 memset(solvegrid, -2, w*h);
1811                 solvegrid[y*w+x] = mineopen(ctx, x, y);
1812                 assert(solvegrid[y*w+x] == 0); /* by deliberate arrangement */
1813
1814                 solveret =
1815                     minesolve(w, h, n, solvegrid, mineopen, mineperturb, ctx, rs);
1816                 if (solveret < 0 || (prevret >= 0 && solveret >= prevret)) {
1817                     success = FALSE;
1818                     break;
1819                 } else if (solveret == 0) {
1820                     success = TRUE;
1821                     break;
1822                 }
1823             }
1824
1825             sfree(solvegrid);
1826         } else {
1827             success = TRUE;
1828         }
1829
1830     } while (!success);
1831
1832     return ret;
1833 }
1834
1835 static char *describe_layout(char *grid, int area, int x, int y,
1836                              int obfuscate)
1837 {
1838     char *ret, *p;
1839     unsigned char *bmp;
1840     int i;
1841
1842     /*
1843      * Set up the mine bitmap and obfuscate it.
1844      */
1845     bmp = snewn((area + 7) / 8, unsigned char);
1846     memset(bmp, 0, (area + 7) / 8);
1847     for (i = 0; i < area; i++) {
1848         if (grid[i])
1849             bmp[i / 8] |= 0x80 >> (i % 8);
1850     }
1851     if (obfuscate)
1852         obfuscate_bitmap(bmp, area, FALSE);
1853
1854     /*
1855      * Now encode the resulting bitmap in hex. We can work to
1856      * nibble rather than byte granularity, since the obfuscation
1857      * function guarantees to return a bit string of the same
1858      * length as its input.
1859      */
1860     ret = snewn((area+3)/4 + 100, char);
1861     p = ret + sprintf(ret, "%d,%d,%s", x, y,
1862                       obfuscate ? "m" : "u");   /* 'm' == masked */
1863     for (i = 0; i < (area+3)/4; i++) {
1864         int v = bmp[i/2];
1865         if (i % 2 == 0)
1866             v >>= 4;
1867         *p++ = "0123456789abcdef"[v & 0xF];
1868     }
1869     *p = '\0';
1870
1871     sfree(bmp);
1872
1873     return ret;
1874 }
1875
1876 static char *new_mine_layout(int w, int h, int n, int x, int y, int unique,
1877                              random_state *rs, char **game_desc)
1878 {
1879     char *grid;
1880
1881 #ifdef TEST_OBFUSCATION
1882     static int tested_obfuscation = FALSE;
1883     if (!tested_obfuscation) {
1884         /*
1885          * A few simple test vectors for the obfuscator.
1886          * 
1887          * First test: the 28-bit stream 1234567. This divides up
1888          * into 1234 and 567[0]. The SHA of 56 70 30 (appending
1889          * "0") is 15ce8ab946640340bbb99f3f48fd2c45d1a31d30. Thus,
1890          * we XOR the 16-bit string 15CE into the input 1234 to get
1891          * 07FA. Next, we SHA that with "0": the SHA of 07 FA 30 is
1892          * 3370135c5e3da4fed937adc004a79533962b6391. So we XOR the
1893          * 12-bit string 337 into the input 567 to get 650. Thus
1894          * our output is 07FA650.
1895          */
1896         {
1897             unsigned char bmp1[] = "\x12\x34\x56\x70";
1898             obfuscate_bitmap(bmp1, 28, FALSE);
1899             printf("test 1 encode: %s\n",
1900                    memcmp(bmp1, "\x07\xfa\x65\x00", 4) ? "failed" : "passed");
1901             obfuscate_bitmap(bmp1, 28, TRUE);
1902             printf("test 1 decode: %s\n",
1903                    memcmp(bmp1, "\x12\x34\x56\x70", 4) ? "failed" : "passed");
1904         }
1905         /*
1906          * Second test: a long string to make sure we switch from
1907          * one SHA to the next correctly. My input string this time
1908          * is simply fifty bytes of zeroes.
1909          */
1910         {
1911             unsigned char bmp2[50];
1912             unsigned char bmp2a[50];
1913             memset(bmp2, 0, 50);
1914             memset(bmp2a, 0, 50);
1915             obfuscate_bitmap(bmp2, 50 * 8, FALSE);
1916             /*
1917              * SHA of twenty-five zero bytes plus "0" is
1918              * b202c07b990c01f6ff2d544707f60e506019b671. SHA of
1919              * twenty-five zero bytes plus "1" is
1920              * fcb1d8b5a2f6b592fe6780b36aa9d65dd7aa6db9. Thus our
1921              * first half becomes
1922              * b202c07b990c01f6ff2d544707f60e506019b671fcb1d8b5a2.
1923              * 
1924              * SHA of that lot plus "0" is
1925              * 10b0af913db85d37ca27f52a9f78bba3a80030db. SHA of the
1926              * same string plus "1" is
1927              * 3d01d8df78e76d382b8106f480135a1bc751d725. So the
1928              * second half becomes
1929              * 10b0af913db85d37ca27f52a9f78bba3a80030db3d01d8df78.
1930              */
1931             printf("test 2 encode: %s\n",
1932                    memcmp(bmp2, "\xb2\x02\xc0\x7b\x99\x0c\x01\xf6\xff\x2d\x54"
1933                           "\x47\x07\xf6\x0e\x50\x60\x19\xb6\x71\xfc\xb1\xd8"
1934                           "\xb5\xa2\x10\xb0\xaf\x91\x3d\xb8\x5d\x37\xca\x27"
1935                           "\xf5\x2a\x9f\x78\xbb\xa3\xa8\x00\x30\xdb\x3d\x01"
1936                           "\xd8\xdf\x78", 50) ? "failed" : "passed");
1937             obfuscate_bitmap(bmp2, 50 * 8, TRUE);
1938             printf("test 2 decode: %s\n",
1939                    memcmp(bmp2, bmp2a, 50) ? "failed" : "passed");
1940         }
1941     }
1942 #endif
1943
1944     grid = minegen(w, h, n, x, y, unique, rs);
1945
1946     if (game_desc)
1947         *game_desc = describe_layout(grid, w * h, x, y, TRUE);
1948
1949     return grid;
1950 }
1951
1952 static char *new_game_desc(const game_params *params, random_state *rs,
1953                            char **aux, int interactive)
1954 {
1955     /*
1956      * We generate the coordinates of an initial click even if they
1957      * aren't actually used. This has the effect of harmonising the
1958      * random number usage between interactive and batch use: if
1959      * you use `mines --generate' with an explicit random seed, you
1960      * should get exactly the same results as if you type the same
1961      * random seed into the interactive game and click in the same
1962      * initial location. (Of course you won't get the same grid if
1963      * you click in a _different_ initial location, but there's
1964      * nothing to be done about that.)
1965      */
1966     int x = random_upto(rs, params->w);
1967     int y = random_upto(rs, params->h);
1968
1969     if (!interactive) {
1970         /*
1971          * For batch-generated grids, pre-open one square.
1972          */
1973         char *grid;
1974         char *desc;
1975
1976         grid = new_mine_layout(params->w, params->h, params->n,
1977                                x, y, params->unique, rs, &desc);
1978         sfree(grid);
1979         return desc;
1980     } else {
1981         char *rsdesc, *desc;
1982
1983         rsdesc = random_state_encode(rs);
1984         desc = snewn(strlen(rsdesc) + 100, char);
1985         sprintf(desc, "r%d,%c,%s", params->n, (char)(params->unique ? 'u' : 'a'), rsdesc);
1986         sfree(rsdesc);
1987         return desc;
1988     }
1989 }
1990
1991 static const char *validate_desc(const game_params *params, const char *desc)
1992 {
1993     int wh = params->w * params->h;
1994     int x, y;
1995
1996     if (*desc == 'r') {
1997         desc++;
1998         if (!*desc || !isdigit((unsigned char)*desc))
1999             return "No initial mine count in game description";
2000         while (*desc && isdigit((unsigned char)*desc))
2001             desc++;                    /* skip over mine count */
2002         if (*desc != ',')
2003             return "No ',' after initial x-coordinate in game description";
2004         desc++;
2005         if (*desc != 'u' && *desc != 'a')
2006             return "No uniqueness specifier in game description";
2007         desc++;
2008         if (*desc != ',')
2009             return "No ',' after uniqueness specifier in game description";
2010         /* now ignore the rest */
2011     } else {
2012         if (*desc && isdigit((unsigned char)*desc)) {
2013             x = atoi(desc);
2014             if (x < 0 || x >= params->w)
2015                 return "Initial x-coordinate was out of range";
2016             while (*desc && isdigit((unsigned char)*desc))
2017                 desc++;                /* skip over x coordinate */
2018             if (*desc != ',')
2019                 return "No ',' after initial x-coordinate in game description";
2020             desc++;                    /* eat comma */
2021             if (!*desc || !isdigit((unsigned char)*desc))
2022                 return "No initial y-coordinate in game description";
2023             y = atoi(desc);
2024             if (y < 0 || y >= params->h)
2025                 return "Initial y-coordinate was out of range";
2026             while (*desc && isdigit((unsigned char)*desc))
2027                 desc++;                /* skip over y coordinate */
2028             if (*desc != ',')
2029                 return "No ',' after initial y-coordinate in game description";
2030             desc++;                    /* eat comma */
2031         }
2032         /* eat `m' for `masked' or `u' for `unmasked', if present */
2033         if (*desc == 'm' || *desc == 'u')
2034             desc++;
2035         /* now just check length of remainder */
2036         if (strlen(desc) != (wh+3)/4)
2037             return "Game description is wrong length";
2038     }
2039
2040     return NULL;
2041 }
2042
2043 static int open_square(game_state *state, int x, int y)
2044 {
2045     int w = state->w, h = state->h;
2046     int xx, yy, nmines, ncovered;
2047
2048     if (!state->layout->mines) {
2049         /*
2050          * We have a preliminary game in which the mine layout
2051          * hasn't been generated yet. Generate it based on the
2052          * initial click location.
2053          */
2054         char *desc, *privdesc;
2055         state->layout->mines = new_mine_layout(w, h, state->layout->n,
2056                                                x, y, state->layout->unique,
2057                                                state->layout->rs,
2058                                                &desc);
2059         /*
2060          * Find the trailing substring of the game description
2061          * corresponding to just the mine layout; we will use this
2062          * as our second `private' game ID for serialisation.
2063          */
2064         privdesc = desc;
2065         while (*privdesc && isdigit((unsigned char)*privdesc)) privdesc++;
2066         if (*privdesc == ',') privdesc++;
2067         while (*privdesc && isdigit((unsigned char)*privdesc)) privdesc++;
2068         if (*privdesc == ',') privdesc++;
2069         assert(*privdesc == 'm');
2070         midend_supersede_game_desc(state->layout->me, desc, privdesc);
2071         sfree(desc);
2072         random_free(state->layout->rs);
2073         state->layout->rs = NULL;
2074     }
2075
2076     if (state->layout->mines[y*w+x]) {
2077         /*
2078          * The player has landed on a mine. Bad luck. Expose the
2079          * mine that killed them, but not the rest (in case they
2080          * want to Undo and carry on playing).
2081          */
2082         state->dead = TRUE;
2083         state->grid[y*w+x] = 65;
2084         return -1;
2085     }
2086
2087     /*
2088      * Otherwise, the player has opened a safe square. Mark it to-do.
2089      */
2090     state->grid[y*w+x] = -10;          /* `todo' value internal to this func */
2091
2092     /*
2093      * Now go through the grid finding all `todo' values and
2094      * opening them. Every time one of them turns out to have no
2095      * neighbouring mines, we add all its unopened neighbours to
2096      * the list as well.
2097      * 
2098      * FIXME: We really ought to be able to do this better than
2099      * using repeated N^2 scans of the grid.
2100      */
2101     while (1) {
2102         int done_something = FALSE;
2103
2104         for (yy = 0; yy < h; yy++)
2105             for (xx = 0; xx < w; xx++)
2106                 if (state->grid[yy*w+xx] == -10) {
2107                     int dx, dy, v;
2108
2109                     assert(!state->layout->mines[yy*w+xx]);
2110
2111                     v = 0;
2112
2113                     for (dx = -1; dx <= +1; dx++)
2114                         for (dy = -1; dy <= +1; dy++)
2115                             if (xx+dx >= 0 && xx+dx < state->w &&
2116                                 yy+dy >= 0 && yy+dy < state->h &&
2117                                 state->layout->mines[(yy+dy)*w+(xx+dx)])
2118                                 v++;
2119
2120                     state->grid[yy*w+xx] = v;
2121
2122                     if (v == 0) {
2123                         for (dx = -1; dx <= +1; dx++)
2124                             for (dy = -1; dy <= +1; dy++)
2125                                 if (xx+dx >= 0 && xx+dx < state->w &&
2126                                     yy+dy >= 0 && yy+dy < state->h &&
2127                                     state->grid[(yy+dy)*w+(xx+dx)] == -2)
2128                                     state->grid[(yy+dy)*w+(xx+dx)] = -10;
2129                     }
2130
2131                     done_something = TRUE;
2132                 }
2133
2134         if (!done_something)
2135             break;
2136     }
2137
2138     /*
2139      * Finally, scan the grid and see if exactly as many squares
2140      * are still covered as there are mines. If so, set the `won'
2141      * flag and fill in mine markers on all covered squares.
2142      */
2143     nmines = ncovered = 0;
2144     for (yy = 0; yy < h; yy++)
2145         for (xx = 0; xx < w; xx++) {
2146             if (state->grid[yy*w+xx] < 0)
2147                 ncovered++;
2148             if (state->layout->mines[yy*w+xx])
2149                 nmines++;
2150         }
2151     assert(ncovered >= nmines);
2152     if (ncovered == nmines) {
2153         for (yy = 0; yy < h; yy++)
2154             for (xx = 0; xx < w; xx++) {
2155                 if (state->grid[yy*w+xx] < 0)
2156                     state->grid[yy*w+xx] = -1;
2157         }
2158         state->won = TRUE;
2159     }
2160
2161     return 0;
2162 }
2163
2164 static game_state *new_game(midend *me, const game_params *params,
2165                             const char *desc)
2166 {
2167     game_state *state = snew(game_state);
2168     int i, wh, x, y, masked;
2169     unsigned char *bmp;
2170
2171     state->w = params->w;
2172     state->h = params->h;
2173     state->n = params->n;
2174     state->dead = state->won = FALSE;
2175     state->used_solve = FALSE;
2176
2177     wh = state->w * state->h;
2178
2179     state->layout = snew(struct mine_layout);
2180     memset(state->layout, 0, sizeof(struct mine_layout));
2181     state->layout->refcount = 1;
2182
2183     state->grid = snewn(wh, signed char);
2184     memset(state->grid, -2, wh);
2185
2186     if (*desc == 'r') {
2187         desc++;
2188         state->layout->n = atoi(desc);
2189         while (*desc && isdigit((unsigned char)*desc))
2190             desc++;                    /* skip over mine count */
2191         if (*desc) desc++;             /* eat comma */
2192         if (*desc == 'a')
2193             state->layout->unique = FALSE;
2194         else
2195             state->layout->unique = TRUE;
2196         desc++;
2197         if (*desc) desc++;             /* eat comma */
2198
2199         state->layout->mines = NULL;
2200         state->layout->rs = random_state_decode(desc);
2201         state->layout->me = me;
2202
2203     } else {
2204         state->layout->rs = NULL;
2205         state->layout->me = NULL;
2206         state->layout->mines = snewn(wh, char);
2207
2208         if (*desc && isdigit((unsigned char)*desc)) {
2209             x = atoi(desc);
2210             while (*desc && isdigit((unsigned char)*desc))
2211                 desc++;                /* skip over x coordinate */
2212             if (*desc) desc++;         /* eat comma */
2213             y = atoi(desc);
2214             while (*desc && isdigit((unsigned char)*desc))
2215                 desc++;                /* skip over y coordinate */
2216             if (*desc) desc++;         /* eat comma */
2217         } else {
2218             x = y = -1;
2219         }
2220
2221         if (*desc == 'm') {
2222             masked = TRUE;
2223             desc++;
2224         } else {
2225             if (*desc == 'u')
2226                 desc++;
2227             /*
2228              * We permit game IDs to be entered by hand without the
2229              * masking transformation.
2230              */
2231             masked = FALSE;
2232         }
2233
2234         bmp = snewn((wh + 7) / 8, unsigned char);
2235         memset(bmp, 0, (wh + 7) / 8);
2236         for (i = 0; i < (wh+3)/4; i++) {
2237             int c = desc[i];
2238             int v;
2239
2240             assert(c != 0);            /* validate_desc should have caught */
2241             if (c >= '0' && c <= '9')
2242                 v = c - '0';
2243             else if (c >= 'a' && c <= 'f')
2244                 v = c - 'a' + 10;
2245             else if (c >= 'A' && c <= 'F')
2246                 v = c - 'A' + 10;
2247             else
2248                 v = 0;
2249
2250             bmp[i / 2] |= v << (4 * (1 - (i % 2)));
2251         }
2252
2253         if (masked)
2254             obfuscate_bitmap(bmp, wh, TRUE);
2255
2256         memset(state->layout->mines, 0, wh);
2257         for (i = 0; i < wh; i++) {
2258             if (bmp[i / 8] & (0x80 >> (i % 8)))
2259                 state->layout->mines[i] = 1;
2260         }
2261
2262         if (x >= 0 && y >= 0)
2263             open_square(state, x, y);
2264         sfree(bmp);
2265     }
2266
2267     return state;
2268 }
2269
2270 static game_state *dup_game(const game_state *state)
2271 {
2272     game_state *ret = snew(game_state);
2273
2274     ret->w = state->w;
2275     ret->h = state->h;
2276     ret->n = state->n;
2277     ret->dead = state->dead;
2278     ret->won = state->won;
2279     ret->used_solve = state->used_solve;
2280     ret->layout = state->layout;
2281     ret->layout->refcount++;
2282     ret->grid = snewn(ret->w * ret->h, signed char);
2283     memcpy(ret->grid, state->grid, ret->w * ret->h);
2284
2285     return ret;
2286 }
2287
2288 static void free_game(game_state *state)
2289 {
2290     if (--state->layout->refcount <= 0) {
2291         sfree(state->layout->mines);
2292         if (state->layout->rs)
2293             random_free(state->layout->rs);
2294         sfree(state->layout);
2295     }
2296     sfree(state->grid);
2297     sfree(state);
2298 }
2299
2300 static char *solve_game(const game_state *state, const game_state *currstate,
2301                         const char *aux, const char **error)
2302 {
2303     if (!state->layout->mines) {
2304         *error = "Game has not been started yet";
2305         return NULL;
2306     }
2307
2308     return dupstr("S");
2309 }
2310
2311 static int game_can_format_as_text_now(const game_params *params)
2312 {
2313     return TRUE;
2314 }
2315
2316 static char *game_text_format(const game_state *state)
2317 {
2318     char *ret;
2319     int x, y;
2320
2321     ret = snewn((state->w + 1) * state->h + 1, char);
2322     for (y = 0; y < state->h; y++) {
2323         for (x = 0; x < state->w; x++) {
2324             int v = state->grid[y*state->w+x];
2325             if (v == 0)
2326                 v = '-';
2327             else if (v >= 1 && v <= 8)
2328                 v = '0' + v;
2329             else if (v == -1)
2330                 v = '*';
2331             else if (v == -2 || v == -3)
2332                 v = '?';
2333             else if (v >= 64)
2334                 v = '!';
2335             ret[y * (state->w+1) + x] = v;
2336         }
2337         ret[y * (state->w+1) + state->w] = '\n';
2338     }
2339     ret[(state->w + 1) * state->h] = '\0';
2340
2341     return ret;
2342 }
2343
2344 struct game_ui {
2345     int hx, hy, hradius;               /* for mouse-down highlights */
2346     int validradius;
2347     int flash_is_death;
2348     int deaths, completed;
2349     int cur_x, cur_y, cur_visible;
2350 };
2351
2352 static game_ui *new_ui(const game_state *state)
2353 {
2354     game_ui *ui = snew(game_ui);
2355     ui->hx = ui->hy = -1;
2356     ui->hradius = ui->validradius = 0;
2357     ui->deaths = 0;
2358     ui->completed = FALSE;
2359     ui->flash_is_death = FALSE;        /* *shrug* */
2360     ui->cur_x = ui->cur_y = ui->cur_visible = 0;
2361     return ui;
2362 }
2363
2364 static void free_ui(game_ui *ui)
2365 {
2366     sfree(ui);
2367 }
2368
2369 static char *encode_ui(const game_ui *ui)
2370 {
2371     char buf[80];
2372     /*
2373      * The deaths counter and completion status need preserving
2374      * across a serialisation.
2375      */
2376     sprintf(buf, "D%d", ui->deaths);
2377     if (ui->completed)
2378         strcat(buf, "C");
2379     return dupstr(buf);
2380 }
2381
2382 static void decode_ui(game_ui *ui, const char *encoding)
2383 {
2384     int p= 0;
2385     sscanf(encoding, "D%d%n", &ui->deaths, &p);
2386     if (encoding[p] == 'C')
2387         ui->completed = TRUE;
2388 }
2389
2390 static void game_changed_state(game_ui *ui, const game_state *oldstate,
2391                                const game_state *newstate)
2392 {
2393     if (newstate->won)
2394         ui->completed = TRUE;
2395 }
2396
2397 struct game_drawstate {
2398     int w, h, started, tilesize, bg;
2399     signed char *grid;
2400     /*
2401      * Items in this `grid' array have all the same values as in
2402      * the game_state grid, and in addition:
2403      * 
2404      *  - -10 means the tile was drawn `specially' as a result of a
2405      *    flash, so it will always need redrawing.
2406      * 
2407      *  - -22 and -23 mean the tile is highlighted for a possible
2408      *    click.
2409      */
2410     int cur_x, cur_y; /* -1, -1 for no cursor displayed. */
2411 };
2412
2413 static char *interpret_move(const game_state *from, game_ui *ui,
2414                             const game_drawstate *ds,
2415                             int x, int y, int button)
2416 {
2417     int cx, cy;
2418     char buf[256];
2419
2420     if (from->dead || from->won)
2421         return NULL;                   /* no further moves permitted */
2422
2423     cx = FROMCOORD(x);
2424     cy = FROMCOORD(y);
2425
2426     if (IS_CURSOR_MOVE(button)) {
2427         move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, 0);
2428         ui->cur_visible = 1;
2429         return UI_UPDATE;
2430     }
2431     if (IS_CURSOR_SELECT(button)) {
2432         int v = from->grid[ui->cur_y * from->w + ui->cur_x];
2433
2434         if (!ui->cur_visible) {
2435             ui->cur_visible = 1;
2436             return UI_UPDATE;
2437         }
2438         if (button == CURSOR_SELECT2) {
2439             /* As for RIGHT_BUTTON; only works on covered square. */
2440             if (v != -2 && v != -1)
2441                 return NULL;
2442             sprintf(buf, "F%d,%d", ui->cur_x, ui->cur_y);
2443             return dupstr(buf);
2444         }
2445         /* Otherwise, treat as LEFT_BUTTON, for a single square. */
2446         if (v == -2 || v == -3) {
2447             if (from->layout->mines &&
2448                 from->layout->mines[ui->cur_y * from->w + ui->cur_x])
2449                 ui->deaths++;
2450
2451             sprintf(buf, "O%d,%d", ui->cur_x, ui->cur_y);
2452             return dupstr(buf);
2453         }
2454         cx = ui->cur_x; cy = ui->cur_y;
2455         ui->validradius = 1;
2456         goto uncover;
2457     }
2458
2459     if (button == LEFT_BUTTON || button == LEFT_DRAG ||
2460         button == MIDDLE_BUTTON || button == MIDDLE_DRAG) {
2461         if (cx < 0 || cx >= from->w || cy < 0 || cy >= from->h)
2462             return NULL;
2463
2464         /*
2465          * Mouse-downs and mouse-drags just cause highlighting
2466          * updates.
2467          */
2468         ui->hx = cx;
2469         ui->hy = cy;
2470         ui->hradius = (from->grid[cy*from->w+cx] >= 0 ? 1 : 0);
2471         if (button == LEFT_BUTTON)
2472             ui->validradius = ui->hradius;
2473         else if (button == MIDDLE_BUTTON)
2474             ui->validradius = 1;
2475         ui->cur_visible = 0;
2476         return UI_UPDATE;
2477     }
2478
2479     if (button == RIGHT_BUTTON) {
2480         if (cx < 0 || cx >= from->w || cy < 0 || cy >= from->h)
2481             return NULL;
2482
2483         /*
2484          * Right-clicking only works on a covered square, and it
2485          * toggles between -1 (marked as mine) and -2 (not marked
2486          * as mine).
2487          *
2488          * FIXME: question marks.
2489          */
2490         if (from->grid[cy * from->w + cx] != -2 &&
2491             from->grid[cy * from->w + cx] != -1)
2492             return NULL;
2493
2494         sprintf(buf, "F%d,%d", cx, cy);
2495         return dupstr(buf);
2496     }
2497
2498     if (button == LEFT_RELEASE || button == MIDDLE_RELEASE) {
2499         ui->hx = ui->hy = -1;
2500         ui->hradius = 0;
2501
2502         /*
2503          * At this stage we must never return NULL: we have adjusted
2504          * the ui, so at worst we return UI_UPDATE.
2505          */
2506         if (cx < 0 || cx >= from->w || cy < 0 || cy >= from->h)
2507             return UI_UPDATE;
2508
2509         /*
2510          * Left-clicking on a covered square opens a tile. Not
2511          * permitted if the tile is marked as a mine, for safety.
2512          * (Unmark it and _then_ open it.)
2513          */
2514         if (button == LEFT_RELEASE &&
2515             (from->grid[cy * from->w + cx] == -2 ||
2516              from->grid[cy * from->w + cx] == -3) &&
2517             ui->validradius == 0) {
2518             /* Check if you've killed yourself. */
2519             if (from->layout->mines && from->layout->mines[cy * from->w + cx])
2520                 ui->deaths++;
2521
2522             sprintf(buf, "O%d,%d", cx, cy);
2523             return dupstr(buf);
2524         }
2525         goto uncover;
2526     }
2527     return NULL;
2528
2529 uncover:
2530     {
2531         /*
2532          * Left-clicking or middle-clicking on an uncovered tile:
2533          * first we check to see if the number of mine markers
2534          * surrounding the tile is equal to its mine count, and if
2535          * so then we open all other surrounding squares.
2536          */
2537         if (from->grid[cy * from->w + cx] > 0 && ui->validradius == 1) {
2538             int dy, dx, n;
2539
2540             /* Count mine markers. */
2541             n = 0;
2542             for (dy = -1; dy <= +1; dy++)
2543                 for (dx = -1; dx <= +1; dx++)
2544                     if (cx+dx >= 0 && cx+dx < from->w &&
2545                         cy+dy >= 0 && cy+dy < from->h) {
2546                         if (from->grid[(cy+dy)*from->w+(cx+dx)] == -1)
2547                             n++;
2548                     }
2549
2550             if (n == from->grid[cy * from->w + cx]) {
2551
2552                 /*
2553                  * Now see if any of the squares we're clearing
2554                  * contains a mine (which will happen iff you've
2555                  * incorrectly marked the mines around the clicked
2556                  * square). If so, we open _just_ those squares, to
2557                  * reveal as little additional information as we
2558                  * can.
2559                  */
2560                 char *p = buf;
2561                 const char *sep = "";
2562
2563                 for (dy = -1; dy <= +1; dy++)
2564                     for (dx = -1; dx <= +1; dx++)
2565                         if (cx+dx >= 0 && cx+dx < from->w &&
2566                             cy+dy >= 0 && cy+dy < from->h) {
2567                             if (from->grid[(cy+dy)*from->w+(cx+dx)] != -1 &&
2568                                 from->layout->mines &&
2569                                 from->layout->mines[(cy+dy)*from->w+(cx+dx)]) {
2570                                 p += sprintf(p, "%sO%d,%d", sep, cx+dx, cy+dy);
2571                                 sep = ";";
2572                             }
2573                         }
2574
2575                 if (p > buf) {
2576                     ui->deaths++;
2577                 } else {
2578                     sprintf(buf, "C%d,%d", cx, cy);
2579                 }
2580
2581                 return dupstr(buf);
2582             }
2583         }
2584
2585         return UI_UPDATE;
2586     }
2587 }
2588
2589 static game_state *execute_move(const game_state *from, const char *move)
2590 {
2591     int cy, cx;
2592     game_state *ret;
2593
2594     if (!strcmp(move, "S")) {
2595         int yy, xx;
2596
2597         ret = dup_game(from);
2598         if (!ret->dead) {
2599             /*
2600              * If the player is still alive at the moment of pressing
2601              * Solve, expose the entire grid as if it were a completed
2602              * solution.
2603              */
2604             for (yy = 0; yy < ret->h; yy++)
2605                 for (xx = 0; xx < ret->w; xx++) {
2606
2607                     if (ret->layout->mines[yy*ret->w+xx]) {
2608                         ret->grid[yy*ret->w+xx] = -1;
2609                     } else {
2610                         int dx, dy, v;
2611
2612                         v = 0;
2613
2614                         for (dx = -1; dx <= +1; dx++)
2615                             for (dy = -1; dy <= +1; dy++)
2616                                 if (xx+dx >= 0 && xx+dx < ret->w &&
2617                                     yy+dy >= 0 && yy+dy < ret->h &&
2618                                     ret->layout->mines[(yy+dy)*ret->w+(xx+dx)])
2619                                     v++;
2620
2621                         ret->grid[yy*ret->w+xx] = v;
2622                     }
2623                 }
2624         } else {
2625             /*
2626              * If the player pressed Solve _after dying_, show a full
2627              * corrections grid in the style of standard Minesweeper.
2628              * Players who don't like Mines's behaviour on death of
2629              * only showing the mine that killed you (so that in case
2630              * of a typo you can undo and carry on without the rest of
2631              * the grid being spoiled) can use this to get the display
2632              * that ordinary Minesweeper would have given them.
2633              */
2634             for (yy = 0; yy < ret->h; yy++)
2635                 for (xx = 0; xx < ret->w; xx++) {
2636                     int pos = yy*ret->w+xx;
2637                     if ((ret->grid[pos] == -2 || ret->grid[pos] == -3) &&
2638                         ret->layout->mines[pos]) {
2639                         ret->grid[pos] = 64;
2640                     } else if (ret->grid[pos] == -1 &&
2641                                !ret->layout->mines[pos]) {
2642                         ret->grid[pos] = 66;
2643                     }
2644                 }
2645         }
2646         ret->used_solve = TRUE;
2647
2648         return ret;
2649     } else {
2650         ret = dup_game(from);
2651
2652         while (*move) {
2653             if (move[0] == 'F' &&
2654                 sscanf(move+1, "%d,%d", &cx, &cy) == 2 &&
2655                 cx >= 0 && cx < from->w && cy >= 0 && cy < from->h) {
2656                 ret->grid[cy * from->w + cx] ^= (-2 ^ -1);
2657             } else if (move[0] == 'O' &&
2658                        sscanf(move+1, "%d,%d", &cx, &cy) == 2 &&
2659                        cx >= 0 && cx < from->w && cy >= 0 && cy < from->h) {
2660                 open_square(ret, cx, cy);
2661             } else if (move[0] == 'C' &&
2662                        sscanf(move+1, "%d,%d", &cx, &cy) == 2 &&
2663                        cx >= 0 && cx < from->w && cy >= 0 && cy < from->h) {
2664                 int dx, dy;
2665
2666                 for (dy = -1; dy <= +1; dy++)
2667                     for (dx = -1; dx <= +1; dx++)
2668                         if (cx+dx >= 0 && cx+dx < ret->w &&
2669                             cy+dy >= 0 && cy+dy < ret->h &&
2670                             (ret->grid[(cy+dy)*ret->w+(cx+dx)] == -2 ||
2671                              ret->grid[(cy+dy)*ret->w+(cx+dx)] == -3))
2672                             open_square(ret, cx+dx, cy+dy);
2673             } else {
2674                 free_game(ret);
2675                 return NULL;
2676             }
2677
2678             while (*move && *move != ';') move++;
2679             if (*move) move++;
2680         }
2681
2682         return ret;
2683     }
2684 }
2685
2686 /* ----------------------------------------------------------------------
2687  * Drawing routines.
2688  */
2689
2690 static void game_compute_size(const game_params *params, int tilesize,
2691                               int *x, int *y)
2692 {
2693     /* Ick: fake up `ds->tilesize' for macro expansion purposes */
2694     struct { int tilesize; } ads, *ds = &ads;
2695     ads.tilesize = tilesize;
2696
2697     *x = BORDER * 2 + TILE_SIZE * params->w;
2698     *y = BORDER * 2 + TILE_SIZE * params->h;
2699 }
2700
2701 static void game_set_size(drawing *dr, game_drawstate *ds,
2702                           const game_params *params, int tilesize)
2703 {
2704     ds->tilesize = tilesize;
2705 }
2706
2707 static float *game_colours(frontend *fe, int *ncolours)
2708 {
2709     float *ret = snewn(3 * NCOLOURS, float);
2710
2711     frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
2712
2713     ret[COL_BACKGROUND2 * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 19.0F / 20.0F;
2714     ret[COL_BACKGROUND2 * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 19.0F / 20.0F;
2715     ret[COL_BACKGROUND2 * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 19.0F / 20.0F;
2716
2717     ret[COL_1 * 3 + 0] = 0.0F;
2718     ret[COL_1 * 3 + 1] = 0.0F;
2719     ret[COL_1 * 3 + 2] = 1.0F;
2720
2721     ret[COL_2 * 3 + 0] = 0.0F;
2722     ret[COL_2 * 3 + 1] = 0.5F;
2723     ret[COL_2 * 3 + 2] = 0.0F;
2724
2725     ret[COL_3 * 3 + 0] = 1.0F;
2726     ret[COL_3 * 3 + 1] = 0.0F;
2727     ret[COL_3 * 3 + 2] = 0.0F;
2728
2729     ret[COL_4 * 3 + 0] = 0.0F;
2730     ret[COL_4 * 3 + 1] = 0.0F;
2731     ret[COL_4 * 3 + 2] = 0.5F;
2732
2733     ret[COL_5 * 3 + 0] = 0.5F;
2734     ret[COL_5 * 3 + 1] = 0.0F;
2735     ret[COL_5 * 3 + 2] = 0.0F;
2736
2737     ret[COL_6 * 3 + 0] = 0.0F;
2738     ret[COL_6 * 3 + 1] = 0.5F;
2739     ret[COL_6 * 3 + 2] = 0.5F;
2740
2741     ret[COL_7 * 3 + 0] = 0.0F;
2742     ret[COL_7 * 3 + 1] = 0.0F;
2743     ret[COL_7 * 3 + 2] = 0.0F;
2744
2745     ret[COL_8 * 3 + 0] = 0.5F;
2746     ret[COL_8 * 3 + 1] = 0.5F;
2747     ret[COL_8 * 3 + 2] = 0.5F;
2748
2749     ret[COL_MINE * 3 + 0] = 0.0F;
2750     ret[COL_MINE * 3 + 1] = 0.0F;
2751     ret[COL_MINE * 3 + 2] = 0.0F;
2752
2753     ret[COL_BANG * 3 + 0] = 1.0F;
2754     ret[COL_BANG * 3 + 1] = 0.0F;
2755     ret[COL_BANG * 3 + 2] = 0.0F;
2756
2757     ret[COL_CROSS * 3 + 0] = 1.0F;
2758     ret[COL_CROSS * 3 + 1] = 0.0F;
2759     ret[COL_CROSS * 3 + 2] = 0.0F;
2760
2761     ret[COL_FLAG * 3 + 0] = 1.0F;
2762     ret[COL_FLAG * 3 + 1] = 0.0F;
2763     ret[COL_FLAG * 3 + 2] = 0.0F;
2764
2765     ret[COL_FLAGBASE * 3 + 0] = 0.0F;
2766     ret[COL_FLAGBASE * 3 + 1] = 0.0F;
2767     ret[COL_FLAGBASE * 3 + 2] = 0.0F;
2768
2769     ret[COL_QUERY * 3 + 0] = 0.0F;
2770     ret[COL_QUERY * 3 + 1] = 0.0F;
2771     ret[COL_QUERY * 3 + 2] = 0.0F;
2772
2773     ret[COL_HIGHLIGHT * 3 + 0] = 1.0F;
2774     ret[COL_HIGHLIGHT * 3 + 1] = 1.0F;
2775     ret[COL_HIGHLIGHT * 3 + 2] = 1.0F;
2776
2777     ret[COL_LOWLIGHT * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 2.0F / 3.0F;
2778     ret[COL_LOWLIGHT * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 2.0F / 3.0F;
2779     ret[COL_LOWLIGHT * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 2.0F / 3.0F;
2780
2781     ret[COL_WRONGNUMBER * 3 + 0] = 1.0F;
2782     ret[COL_WRONGNUMBER * 3 + 1] = 0.6F;
2783     ret[COL_WRONGNUMBER * 3 + 2] = 0.6F;
2784
2785     /* Red tinge to a light colour, for the cursor. */
2786     ret[COL_CURSOR * 3 + 0] = ret[COL_HIGHLIGHT * 3 + 0];
2787     ret[COL_CURSOR * 3 + 1] = ret[COL_HIGHLIGHT * 3 + 0] / 2.0F;
2788     ret[COL_CURSOR * 3 + 2] = ret[COL_HIGHLIGHT * 3 + 0] / 2.0F;
2789
2790     *ncolours = NCOLOURS;
2791     return ret;
2792 }
2793
2794 static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
2795 {
2796     struct game_drawstate *ds = snew(struct game_drawstate);
2797
2798     ds->w = state->w;
2799     ds->h = state->h;
2800     ds->started = FALSE;
2801     ds->tilesize = 0;                  /* not decided yet */
2802     ds->grid = snewn(ds->w * ds->h, signed char);
2803     ds->bg = -1;
2804     ds->cur_x = ds->cur_y = -1;
2805
2806     memset(ds->grid, -99, ds->w * ds->h);
2807
2808     return ds;
2809 }
2810
2811 static void game_free_drawstate(drawing *dr, game_drawstate *ds)
2812 {
2813     sfree(ds->grid);
2814     sfree(ds);
2815 }
2816
2817 static void draw_tile(drawing *dr, game_drawstate *ds,
2818                       int x, int y, int v, int bg)
2819 {
2820     if (v < 0) {
2821         int coords[12];
2822         int hl = 0;
2823
2824         if (v == -22 || v == -23) {
2825             v += 20;
2826
2827             /*
2828              * Omit the highlights in this case.
2829              */
2830             draw_rect(dr, x, y, TILE_SIZE, TILE_SIZE,
2831                       bg == COL_BACKGROUND ? COL_BACKGROUND2 : bg);
2832             draw_line(dr, x, y, x + TILE_SIZE - 1, y, COL_LOWLIGHT);
2833             draw_line(dr, x, y, x, y + TILE_SIZE - 1, COL_LOWLIGHT);
2834         } else {
2835             /*
2836              * Draw highlights to indicate the square is covered.
2837              */
2838             coords[0] = x + TILE_SIZE - 1;
2839             coords[1] = y + TILE_SIZE - 1;
2840             coords[2] = x + TILE_SIZE - 1;
2841             coords[3] = y;
2842             coords[4] = x;
2843             coords[5] = y + TILE_SIZE - 1;
2844             draw_polygon(dr, coords, 3, COL_LOWLIGHT ^ hl, COL_LOWLIGHT ^ hl);
2845
2846             coords[0] = x;
2847             coords[1] = y;
2848             draw_polygon(dr, coords, 3, COL_HIGHLIGHT ^ hl,
2849                          COL_HIGHLIGHT ^ hl);
2850
2851             draw_rect(dr, x + HIGHLIGHT_WIDTH, y + HIGHLIGHT_WIDTH,
2852                       TILE_SIZE - 2*HIGHLIGHT_WIDTH, TILE_SIZE - 2*HIGHLIGHT_WIDTH,
2853                       bg);
2854         }
2855
2856         if (v == -1) {
2857             /*
2858              * Draw a flag.
2859              */
2860 #define SETCOORD(n, dx, dy) do { \
2861     coords[(n)*2+0] = x + (int)(TILE_SIZE * (dx)); \
2862     coords[(n)*2+1] = y + (int)(TILE_SIZE * (dy)); \
2863 } while (0)
2864             SETCOORD(0, 0.6F,  0.35F);
2865             SETCOORD(1, 0.6F,  0.7F);
2866             SETCOORD(2, 0.8F,  0.8F);
2867             SETCOORD(3, 0.25F, 0.8F);
2868             SETCOORD(4, 0.55F, 0.7F);
2869             SETCOORD(5, 0.55F, 0.35F);
2870             draw_polygon(dr, coords, 6, COL_FLAGBASE, COL_FLAGBASE);
2871
2872             SETCOORD(0, 0.6F, 0.2F);
2873             SETCOORD(1, 0.6F, 0.5F);
2874             SETCOORD(2, 0.2F, 0.35F);
2875             draw_polygon(dr, coords, 3, COL_FLAG, COL_FLAG);
2876 #undef SETCOORD
2877
2878         } else if (v == -3) {
2879             /*
2880              * Draw a question mark.
2881              */
2882             draw_text(dr, x + TILE_SIZE / 2, y + TILE_SIZE / 2,
2883                       FONT_VARIABLE, TILE_SIZE * 6 / 8,
2884                       ALIGN_VCENTRE | ALIGN_HCENTRE,
2885                       COL_QUERY, "?");
2886         }
2887     } else {
2888         /*
2889          * Clear the square to the background colour, and draw thin
2890          * grid lines along the top and left.
2891          * 
2892          * Exception is that for value 65 (mine we've just trodden
2893          * on), we clear the square to COL_BANG.
2894          */
2895         if (v & 32) {
2896             bg = COL_WRONGNUMBER;
2897             v &= ~32;
2898         }
2899         draw_rect(dr, x, y, TILE_SIZE, TILE_SIZE,
2900                   (v == 65 ? COL_BANG :
2901                    bg == COL_BACKGROUND ? COL_BACKGROUND2 : bg));
2902         draw_line(dr, x, y, x + TILE_SIZE - 1, y, COL_LOWLIGHT);
2903         draw_line(dr, x, y, x, y + TILE_SIZE - 1, COL_LOWLIGHT);
2904
2905         if (v > 0 && v <= 8) {
2906             /*
2907              * Mark a number.
2908              */
2909             char str[2];
2910             str[0] = v + '0';
2911             str[1] = '\0';
2912             draw_text(dr, x + TILE_SIZE / 2, y + TILE_SIZE / 2,
2913                       FONT_VARIABLE, TILE_SIZE * 7 / 8,
2914                       ALIGN_VCENTRE | ALIGN_HCENTRE,
2915                       (COL_1 - 1) + v, str);
2916
2917         } else if (v >= 64) {
2918             /*
2919              * Mark a mine.
2920              */
2921             {
2922                 int cx = x + TILE_SIZE / 2;
2923                 int cy = y + TILE_SIZE / 2;
2924                 int r = TILE_SIZE / 2 - 3;
2925
2926                 draw_circle(dr, cx, cy, 5*r/6, COL_MINE, COL_MINE);
2927                 draw_rect(dr, cx - r/6, cy - r, 2*(r/6)+1, 2*r+1, COL_MINE);
2928                 draw_rect(dr, cx - r, cy - r/6, 2*r+1, 2*(r/6)+1, COL_MINE);
2929                 draw_rect(dr, cx-r/3, cy-r/3, r/3, r/4, COL_HIGHLIGHT);
2930             }
2931
2932             if (v == 66) {
2933                 /*
2934                  * Cross through the mine.
2935                  */
2936                 int dx;
2937                 for (dx = -1; dx <= +1; dx++) {
2938                     draw_line(dr, x + 3 + dx, y + 2,
2939                               x + TILE_SIZE - 3 + dx,
2940                               y + TILE_SIZE - 2, COL_CROSS);
2941                     draw_line(dr, x + TILE_SIZE - 3 + dx, y + 2,
2942                               x + 3 + dx, y + TILE_SIZE - 2,
2943                               COL_CROSS);
2944                 }
2945             }
2946         }
2947     }
2948
2949     draw_update(dr, x, y, TILE_SIZE, TILE_SIZE);
2950 }
2951
2952 static void game_redraw(drawing *dr, game_drawstate *ds,
2953                         const game_state *oldstate, const game_state *state,
2954                         int dir, const game_ui *ui,
2955                         float animtime, float flashtime)
2956 {
2957     int x, y;
2958     int mines, markers, closed, bg;
2959     int cx = -1, cy = -1, cmoved;
2960
2961     if (flashtime) {
2962         int frame = (int)(flashtime / FLASH_FRAME);
2963         if (frame % 2)
2964             bg = (ui->flash_is_death ? COL_BACKGROUND : COL_LOWLIGHT);
2965         else
2966             bg = (ui->flash_is_death ? COL_BANG : COL_HIGHLIGHT);
2967     } else
2968         bg = COL_BACKGROUND;
2969
2970     if (!ds->started) {
2971         int coords[10];
2972
2973         draw_rect(dr, 0, 0,
2974                   TILE_SIZE * state->w + 2 * BORDER,
2975                   TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND);
2976         draw_update(dr, 0, 0,
2977                     TILE_SIZE * state->w + 2 * BORDER,
2978                     TILE_SIZE * state->h + 2 * BORDER);
2979
2980         /*
2981          * Recessed area containing the whole puzzle.
2982          */
2983         coords[0] = COORD(state->w) + OUTER_HIGHLIGHT_WIDTH - 1;
2984         coords[1] = COORD(state->h) + OUTER_HIGHLIGHT_WIDTH - 1;
2985         coords[2] = COORD(state->w) + OUTER_HIGHLIGHT_WIDTH - 1;
2986         coords[3] = COORD(0) - OUTER_HIGHLIGHT_WIDTH;
2987         coords[4] = coords[2] - TILE_SIZE;
2988         coords[5] = coords[3] + TILE_SIZE;
2989         coords[8] = COORD(0) - OUTER_HIGHLIGHT_WIDTH;
2990         coords[9] = COORD(state->h) + OUTER_HIGHLIGHT_WIDTH - 1;
2991         coords[6] = coords[8] + TILE_SIZE;
2992         coords[7] = coords[9] - TILE_SIZE;
2993         draw_polygon(dr, coords, 5, COL_HIGHLIGHT, COL_HIGHLIGHT);
2994
2995         coords[1] = COORD(0) - OUTER_HIGHLIGHT_WIDTH;
2996         coords[0] = COORD(0) - OUTER_HIGHLIGHT_WIDTH;
2997         draw_polygon(dr, coords, 5, COL_LOWLIGHT, COL_LOWLIGHT);
2998
2999         ds->started = TRUE;
3000     }
3001
3002     if (ui->cur_visible) cx = ui->cur_x;
3003     if (ui->cur_visible) cy = ui->cur_y;
3004     cmoved = (cx != ds->cur_x || cy != ds->cur_y);
3005
3006     /*
3007      * Now draw the tiles. Also in this loop, count up the number
3008      * of mines, mine markers, and closed squares.
3009      */
3010     mines = markers = closed = 0;
3011     for (y = 0; y < ds->h; y++)
3012         for (x = 0; x < ds->w; x++) {
3013             int v = state->grid[y*ds->w+x], cc = 0;
3014
3015             if (v < 0)
3016                 closed++;
3017             if (v == -1)
3018                 markers++;
3019             if (state->layout->mines && state->layout->mines[y*ds->w+x])
3020                 mines++;
3021
3022             if (v >= 0 && v <= 8) {
3023                 /*
3024                  * Count up the flags around this tile, and if
3025                  * there are too _many_, highlight the tile.
3026                  */
3027                 int dx, dy, flags = 0;
3028
3029                 for (dy = -1; dy <= +1; dy++)
3030                     for (dx = -1; dx <= +1; dx++) {
3031                         int nx = x+dx, ny = y+dy;
3032                         if (nx >= 0 && nx < ds->w &&
3033                             ny >= 0 && ny < ds->h &&
3034                             state->grid[ny*ds->w+nx] == -1)
3035                             flags++;
3036                     }
3037
3038                 if (flags > v)
3039                     v |= 32;
3040             }
3041
3042             if ((v == -2 || v == -3) &&
3043                 (abs(x-ui->hx) <= ui->hradius && abs(y-ui->hy) <= ui->hradius))
3044                 v -= 20;
3045
3046             if (cmoved && /* if cursor has moved, force redraw of curr and prev pos */
3047                 ((x == cx && y == cy) || (x == ds->cur_x && y == ds->cur_y)))
3048               cc = 1;
3049
3050             if (ds->grid[y*ds->w+x] != v || bg != ds->bg || cc) {
3051                 draw_tile(dr, ds, COORD(x), COORD(y), v,
3052                           (x == cx && y == cy) ? COL_CURSOR : bg);
3053                 ds->grid[y*ds->w+x] = v;
3054             }
3055         }
3056     ds->bg = bg;
3057     ds->cur_x = cx; ds->cur_y = cy;
3058
3059     if (!state->layout->mines)
3060         mines = state->layout->n;
3061
3062     /*
3063      * Update the status bar.
3064      */
3065     {
3066         char statusbar[512];
3067         if (state->dead) {
3068             sprintf(statusbar, "DEAD!");
3069         } else if (state->won) {
3070             if (state->used_solve)
3071                 sprintf(statusbar, "Auto-solved.");
3072             else
3073                 sprintf(statusbar, "COMPLETED!");
3074         } else {
3075             int safe_closed = closed - mines;
3076             sprintf(statusbar, "Marked: %d / %d", markers, mines);
3077             if (safe_closed > 0 && safe_closed <= 9) {
3078                 /*
3079                  * In the situation where there's a very small number
3080                  * of _non_-mine squares left unopened, it's helpful
3081                  * to mention that number in the status line, to save
3082                  * the player from having to count it up
3083                  * painstakingly. This is particularly important if
3084                  * the player has turned up the mine density to the
3085                  * point where game generation resorts to its weird
3086                  * pathological fallback of a very dense mine area
3087                  * with a clearing in the middle, because that often
3088                  * leads to a deduction you can only make by knowing
3089                  * that there is (say) exactly one non-mine square to
3090                  * find, and it's a real pain to have to count up two
3091                  * large numbers of squares and subtract them to get
3092                  * that value of 1.
3093                  *
3094                  * The threshold value of 8 for displaying this
3095                  * information is because that's the largest number of
3096                  * non-mine squares that might conceivably fit around
3097                  * a single central square, and the most likely way to
3098                  * _use_ this information is to observe that if all
3099                  * the remaining safe squares are adjacent to _this_
3100                  * square then everything else can be immediately
3101                  * flagged as a mine.
3102                  */
3103                 if (safe_closed == 1) {
3104                     sprintf(statusbar + strlen(statusbar),
3105                             " (1 safe square remains)");
3106                 } else {
3107                     sprintf(statusbar + strlen(statusbar),
3108                             " (%d safe squares remain)", safe_closed);
3109                 }
3110             }
3111         }
3112         if (ui->deaths)
3113             sprintf(statusbar + strlen(statusbar),
3114                     "  Deaths: %d", ui->deaths);
3115         status_bar(dr, statusbar);
3116     }
3117 }
3118
3119 static float game_anim_length(const game_state *oldstate,
3120                               const game_state *newstate, int dir, game_ui *ui)
3121 {
3122     return 0.0F;
3123 }
3124
3125 static float game_flash_length(const game_state *oldstate,
3126                                const game_state *newstate, int dir, game_ui *ui)
3127 {
3128     if (oldstate->used_solve || newstate->used_solve)
3129         return 0.0F;
3130
3131     if (dir > 0 && !oldstate->dead && !oldstate->won) {
3132         if (newstate->dead) {
3133             ui->flash_is_death = TRUE;
3134             return 3 * FLASH_FRAME;
3135         }
3136         if (newstate->won) {
3137             ui->flash_is_death = FALSE;
3138             return 2 * FLASH_FRAME;
3139         }
3140     }
3141     return 0.0F;
3142 }
3143
3144 static int game_status(const game_state *state)
3145 {
3146     /*
3147      * We report the game as lost only if the player has used the
3148      * Solve function to reveal all the mines. Otherwise, we assume
3149      * they'll undo and continue play.
3150      */
3151     return state->won ? (state->used_solve ? -1 : +1) : 0;
3152 }
3153
3154 static int game_timing_state(const game_state *state, game_ui *ui)
3155 {
3156     if (state->dead || state->won || ui->completed || !state->layout->mines)
3157         return FALSE;
3158     return TRUE;
3159 }
3160
3161 static void game_print_size(const game_params *params, float *x, float *y)
3162 {
3163 }
3164
3165 static void game_print(drawing *dr, const game_state *state, int tilesize)
3166 {
3167 }
3168
3169 #ifdef COMBINED
3170 #define thegame mines
3171 #endif
3172
3173 const struct game thegame = {
3174     "Mines", "games.mines", "mines",
3175     default_params,
3176     game_fetch_preset, NULL,
3177     decode_params,
3178     encode_params,
3179     free_params,
3180     dup_params,
3181     TRUE, game_configure, custom_params,
3182     validate_params,
3183     new_game_desc,
3184     validate_desc,
3185     new_game,
3186     dup_game,
3187     free_game,
3188     TRUE, solve_game,
3189     TRUE, game_can_format_as_text_now, game_text_format,
3190     new_ui,
3191     free_ui,
3192     encode_ui,
3193     decode_ui,
3194     game_changed_state,
3195     interpret_move,
3196     execute_move,
3197     PREFERRED_TILE_SIZE, game_compute_size, game_set_size,
3198     game_colours,
3199     game_new_drawstate,
3200     game_free_drawstate,
3201     game_redraw,
3202     game_anim_length,
3203     game_flash_length,
3204     game_status,
3205     FALSE, FALSE, game_print_size, game_print,
3206     TRUE,                              /* wants_statusbar */
3207     TRUE, game_timing_state,
3208     BUTTON_BEATS(LEFT_BUTTON, RIGHT_BUTTON) | REQUIRE_RBUTTON,
3209 };
3210
3211 #ifdef STANDALONE_OBFUSCATOR
3212
3213 /*
3214  * Vaguely useful stand-alone program which translates between
3215  * obfuscated and clear Mines game descriptions. Pass in a game
3216  * description on the command line, and if it's clear it will be
3217  * obfuscated and vice versa. The output text should also be a
3218  * valid game ID describing the same game. Like this:
3219  *
3220  * $ ./mineobfusc 9x9:4,4,mb071b49fbd1cb6a0d5868
3221  * 9x9:4,4,004000007c00010022080
3222  * $ ./mineobfusc 9x9:4,4,004000007c00010022080
3223  * 9x9:4,4,mb071b49fbd1cb6a0d5868
3224  */
3225
3226 int main(int argc, char **argv)
3227 {
3228     game_params *p;
3229     game_state *s;
3230     char *id = NULL, *desc;
3231     const char *err;
3232     int y, x;
3233
3234     while (--argc > 0) {
3235         char *p = *++argv;
3236         if (*p == '-') {
3237             fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
3238             return 1;
3239         } else {
3240             id = p;
3241         }
3242     }
3243
3244     if (!id) {
3245         fprintf(stderr, "usage: %s <game_id>\n", argv[0]);
3246         return 1;
3247     }
3248
3249     desc = strchr(id, ':');
3250     if (!desc) {
3251         fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
3252         return 1;
3253     }
3254     *desc++ = '\0';
3255
3256     p = default_params();
3257     decode_params(p, id);
3258     err = validate_desc(p, desc);
3259     if (err) {
3260         fprintf(stderr, "%s: %s\n", argv[0], err);
3261         return 1;
3262     }
3263     s = new_game(NULL, p, desc);
3264
3265     x = atoi(desc);
3266     while (*desc && *desc != ',') desc++;
3267     if (*desc) desc++;
3268     y = atoi(desc);
3269     while (*desc && *desc != ',') desc++;
3270     if (*desc) desc++;
3271
3272     printf("%s:%s\n", id, describe_layout(s->layout->mines,
3273                                           p->w * p->h,
3274                                           x, y,
3275                                           (*desc != 'm')));
3276
3277     return 0;
3278 }
3279
3280 #endif
3281
3282 /* vim: set shiftwidth=4 tabstop=8: */