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