chiark / gitweb /
Terribly cunning approach to making the pencil marks look nicer,
[sgt-puzzles.git] / map.c
1 /*
2  * map.c: Game involving four-colouring a map.
3  */
4
5 /*
6  * TODO:
7  * 
8  *  - clue marking
9  *  - better four-colouring algorithm?
10  *  - ability to drag a set of pencil marks?
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <assert.h>
17 #include <ctype.h>
18 #include <math.h>
19
20 #include "puzzles.h"
21
22 /*
23  * In standalone solver mode, `verbose' is a variable which can be
24  * set by command-line option; in debugging mode it's simply always
25  * true.
26  */
27 #if defined STANDALONE_SOLVER
28 #define SOLVER_DIAGNOSTICS
29 int verbose = FALSE;
30 #elif defined SOLVER_DIAGNOSTICS
31 #define verbose TRUE
32 #endif
33
34 /*
35  * I don't seriously anticipate wanting to change the number of
36  * colours used in this game, but it doesn't cost much to use a
37  * #define just in case :-)
38  */
39 #define FOUR 4
40 #define THREE (FOUR-1)
41 #define FIVE (FOUR+1)
42 #define SIX (FOUR+2)
43
44 /*
45  * Ghastly run-time configuration option, just for Gareth (again).
46  */
47 static int flash_type = -1;
48 static float flash_length;
49
50 /*
51  * Difficulty levels. I do some macro ickery here to ensure that my
52  * enum and the various forms of my name list always match up.
53  */
54 #define DIFFLIST(A) \
55     A(EASY,Easy,e) \
56     A(NORMAL,Normal,n) \
57     A(HARD,Hard,h) \
58     A(RECURSE,Unreasonable,u)
59 #define ENUM(upper,title,lower) DIFF_ ## upper,
60 #define TITLE(upper,title,lower) #title,
61 #define ENCODE(upper,title,lower) #lower
62 #define CONFIG(upper,title,lower) ":" #title
63 enum { DIFFLIST(ENUM) DIFFCOUNT };
64 static char const *const map_diffnames[] = { DIFFLIST(TITLE) };
65 static char const map_diffchars[] = DIFFLIST(ENCODE);
66 #define DIFFCONFIG DIFFLIST(CONFIG)
67
68 enum { TE, BE, LE, RE };               /* top/bottom/left/right edges */
69
70 enum {
71     COL_BACKGROUND,
72     COL_GRID,
73     COL_0, COL_1, COL_2, COL_3,
74     COL_ERROR, COL_ERRTEXT,
75     NCOLOURS
76 };
77
78 struct game_params {
79     int w, h, n, diff;
80 };
81
82 struct map {
83     int refcount;
84     int *map;
85     int *graph;
86     int n;
87     int ngraph;
88     int *immutable;
89     int *edgex, *edgey;                /* position of a point on each edge */
90     int *regionx, *regiony;            /* position of a point in each region */
91 };
92
93 struct game_state {
94     game_params p;
95     struct map *map;
96     int *colouring, *pencil;
97     int completed, cheated;
98 };
99
100 static game_params *default_params(void)
101 {
102     game_params *ret = snew(game_params);
103
104     ret->w = 20;
105     ret->h = 15;
106     ret->n = 30;
107     ret->diff = DIFF_NORMAL;
108
109     return ret;
110 }
111
112 static const struct game_params map_presets[] = {
113     {20, 15, 30, DIFF_EASY},
114     {20, 15, 30, DIFF_NORMAL},
115     {20, 15, 30, DIFF_HARD},
116     {20, 15, 30, DIFF_RECURSE},
117     {30, 25, 75, DIFF_NORMAL},
118     {30, 25, 75, DIFF_HARD},
119 };
120
121 static int game_fetch_preset(int i, char **name, game_params **params)
122 {
123     game_params *ret;
124     char str[80];
125
126     if (i < 0 || i >= lenof(map_presets))
127         return FALSE;
128
129     ret = snew(game_params);
130     *ret = map_presets[i];
131
132     sprintf(str, "%dx%d, %d regions, %s", ret->w, ret->h, ret->n,
133             map_diffnames[ret->diff]);
134
135     *name = dupstr(str);
136     *params = ret;
137     return TRUE;
138 }
139
140 static void free_params(game_params *params)
141 {
142     sfree(params);
143 }
144
145 static game_params *dup_params(game_params *params)
146 {
147     game_params *ret = snew(game_params);
148     *ret = *params;                    /* structure copy */
149     return ret;
150 }
151
152 static void decode_params(game_params *params, char const *string)
153 {
154     char const *p = string;
155
156     params->w = atoi(p);
157     while (*p && isdigit((unsigned char)*p)) p++;
158     if (*p == 'x') {
159         p++;
160         params->h = atoi(p);
161         while (*p && isdigit((unsigned char)*p)) p++;
162     } else {
163         params->h = params->w;
164     }
165     if (*p == 'n') {
166         p++;
167         params->n = atoi(p);
168         while (*p && (*p == '.' || isdigit((unsigned char)*p))) p++;
169     } else {
170         params->n = params->w * params->h / 8;
171     }
172     if (*p == 'd') {
173         int i;
174         p++;
175         for (i = 0; i < DIFFCOUNT; i++)
176             if (*p == map_diffchars[i])
177                 params->diff = i;
178         if (*p) p++;
179     }
180 }
181
182 static char *encode_params(game_params *params, int full)
183 {
184     char ret[400];
185
186     sprintf(ret, "%dx%dn%d", params->w, params->h, params->n);
187     if (full)
188         sprintf(ret + strlen(ret), "d%c", map_diffchars[params->diff]);
189
190     return dupstr(ret);
191 }
192
193 static config_item *game_configure(game_params *params)
194 {
195     config_item *ret;
196     char buf[80];
197
198     ret = snewn(5, config_item);
199
200     ret[0].name = "Width";
201     ret[0].type = C_STRING;
202     sprintf(buf, "%d", params->w);
203     ret[0].sval = dupstr(buf);
204     ret[0].ival = 0;
205
206     ret[1].name = "Height";
207     ret[1].type = C_STRING;
208     sprintf(buf, "%d", params->h);
209     ret[1].sval = dupstr(buf);
210     ret[1].ival = 0;
211
212     ret[2].name = "Regions";
213     ret[2].type = C_STRING;
214     sprintf(buf, "%d", params->n);
215     ret[2].sval = dupstr(buf);
216     ret[2].ival = 0;
217
218     ret[3].name = "Difficulty";
219     ret[3].type = C_CHOICES;
220     ret[3].sval = DIFFCONFIG;
221     ret[3].ival = params->diff;
222
223     ret[4].name = NULL;
224     ret[4].type = C_END;
225     ret[4].sval = NULL;
226     ret[4].ival = 0;
227
228     return ret;
229 }
230
231 static game_params *custom_params(config_item *cfg)
232 {
233     game_params *ret = snew(game_params);
234
235     ret->w = atoi(cfg[0].sval);
236     ret->h = atoi(cfg[1].sval);
237     ret->n = atoi(cfg[2].sval);
238     ret->diff = cfg[3].ival;
239
240     return ret;
241 }
242
243 static char *validate_params(game_params *params, int full)
244 {
245     if (params->w < 2 || params->h < 2)
246         return "Width and height must be at least two";
247     if (params->n < 5)
248         return "Must have at least five regions";
249     if (params->n > params->w * params->h)
250         return "Too many regions to fit in grid";
251     return NULL;
252 }
253
254 /* ----------------------------------------------------------------------
255  * Cumulative frequency table functions.
256  */
257
258 /*
259  * Initialise a cumulative frequency table. (Hardly worth writing
260  * this function; all it does is to initialise everything in the
261  * array to zero.)
262  */
263 static void cf_init(int *table, int n)
264 {
265     int i;
266
267     for (i = 0; i < n; i++)
268         table[i] = 0;
269 }
270
271 /*
272  * Increment the count of symbol `sym' by `count'.
273  */
274 static void cf_add(int *table, int n, int sym, int count)
275 {
276     int bit;
277
278     bit = 1;
279     while (sym != 0) {
280         if (sym & bit) {
281             table[sym] += count;
282             sym &= ~bit;
283         }
284         bit <<= 1;
285     }
286
287     table[0] += count;
288 }
289
290 /*
291  * Cumulative frequency lookup: return the total count of symbols
292  * with value less than `sym'.
293  */
294 static int cf_clookup(int *table, int n, int sym)
295 {
296     int bit, index, limit, count;
297
298     if (sym == 0)
299         return 0;
300
301     assert(0 < sym && sym <= n);
302
303     count = table[0];                  /* start with the whole table size */
304
305     bit = 1;
306     while (bit < n)
307         bit <<= 1;
308
309     limit = n;
310
311     while (bit > 0) {
312         /*
313          * Find the least number with its lowest set bit in this
314          * position which is greater than or equal to sym.
315          */
316         index = ((sym + bit - 1) &~ (bit * 2 - 1)) + bit;
317
318         if (index < limit) {
319             count -= table[index];
320             limit = index;
321         }
322
323         bit >>= 1;
324     }
325
326     return count;
327 }
328
329 /*
330  * Single frequency lookup: return the count of symbol `sym'.
331  */
332 static int cf_slookup(int *table, int n, int sym)
333 {
334     int count, bit;
335
336     assert(0 <= sym && sym < n);
337
338     count = table[sym];
339
340     for (bit = 1; sym+bit < n && !(sym & bit); bit <<= 1)
341         count -= table[sym+bit];
342
343     return count;
344 }
345
346 /*
347  * Return the largest symbol index such that the cumulative
348  * frequency up to that symbol is less than _or equal to_ count.
349  */
350 static int cf_whichsym(int *table, int n, int count) {
351     int bit, sym, top;
352
353     assert(count >= 0 && count < table[0]);
354
355     bit = 1;
356     while (bit < n)
357         bit <<= 1;
358
359     sym = 0;
360     top = table[0];
361
362     while (bit > 0) {
363         if (sym+bit < n) {
364             if (count >= top - table[sym+bit])
365                 sym += bit;
366             else
367                 top -= table[sym+bit];
368         }
369
370         bit >>= 1;
371     }
372
373     return sym;
374 }
375
376 /* ----------------------------------------------------------------------
377  * Map generation.
378  * 
379  * FIXME: this isn't entirely optimal at present, because it
380  * inherently prioritises growing the largest region since there
381  * are more squares adjacent to it. This acts as a destabilising
382  * influence leading to a few large regions and mostly small ones.
383  * It might be better to do it some other way.
384  */
385
386 #define WEIGHT_INCREASED 2             /* for increased perimeter */
387 #define WEIGHT_DECREASED 4             /* for decreased perimeter */
388 #define WEIGHT_UNCHANGED 3             /* for unchanged perimeter */
389
390 /*
391  * Look at a square and decide which colours can be extended into
392  * it.
393  * 
394  * If called with index < 0, it adds together one of
395  * WEIGHT_INCREASED, WEIGHT_DECREASED or WEIGHT_UNCHANGED for each
396  * colour that has a valid extension (according to the effect that
397  * it would have on the perimeter of the region being extended) and
398  * returns the overall total.
399  * 
400  * If called with index >= 0, it returns one of the possible
401  * colours depending on the value of index, in such a way that the
402  * number of possible inputs which would give rise to a given
403  * return value correspond to the weight of that value.
404  */
405 static int extend_options(int w, int h, int n, int *map,
406                           int x, int y, int index)
407 {
408     int c, i, dx, dy;
409     int col[8];
410     int total = 0;
411
412     if (map[y*w+x] >= 0) {
413         assert(index < 0);
414         return 0;                      /* can't do this square at all */
415     }
416
417     /*
418      * Fetch the eight neighbours of this square, in order around
419      * the square.
420      */
421     for (dy = -1; dy <= +1; dy++)
422         for (dx = -1; dx <= +1; dx++) {
423             int index = (dy < 0 ? 6-dx : dy > 0 ? 2+dx : 2*(1+dx));
424             if (x+dx >= 0 && x+dx < w && y+dy >= 0 && y+dy < h)
425                 col[index] = map[(y+dy)*w+(x+dx)];
426             else
427                 col[index] = -1;
428         }
429
430     /*
431      * Iterate over each colour that might be feasible.
432      * 
433      * FIXME: this routine currently has O(n) running time. We
434      * could turn it into O(FOUR) by only bothering to iterate over
435      * the colours mentioned in the four neighbouring squares.
436      */
437
438     for (c = 0; c < n; c++) {
439         int count, neighbours, runs;
440
441         /*
442          * One of the even indices of col (representing the
443          * orthogonal neighbours of this square) must be equal to
444          * c, or else this square is not adjacent to region c and
445          * obviously cannot become an extension of it at this time.
446          */
447         neighbours = 0;
448         for (i = 0; i < 8; i += 2)
449             if (col[i] == c)
450                 neighbours++;
451         if (!neighbours)
452             continue;
453
454         /*
455          * Now we know this square is adjacent to region c. The
456          * next question is, would extending it cause the region to
457          * become non-simply-connected? If so, we mustn't do it.
458          * 
459          * We determine this by looking around col to see if we can
460          * find more than one separate run of colour c.
461          */
462         runs = 0;
463         for (i = 0; i < 8; i++)
464             if (col[i] == c && col[(i+1) & 7] != c)
465                 runs++;
466         if (runs > 1)
467             continue;
468
469         assert(runs == 1);
470
471         /*
472          * This square is a possibility. Determine its effect on
473          * the region's perimeter (computed from the number of
474          * orthogonal neighbours - 1 means a perimeter increase, 3
475          * a decrease, 2 no change; 4 is impossible because the
476          * region would already not be simply connected) and we're
477          * done.
478          */
479         assert(neighbours > 0 && neighbours < 4);
480         count = (neighbours == 1 ? WEIGHT_INCREASED :
481                  neighbours == 2 ? WEIGHT_UNCHANGED : WEIGHT_DECREASED);
482
483         total += count;
484         if (index >= 0 && index < count)
485             return c;
486         else
487             index -= count;
488     }
489
490     assert(index < 0);
491
492     return total;
493 }
494
495 static void genmap(int w, int h, int n, int *map, random_state *rs)
496 {
497     int wh = w*h;
498     int x, y, i, k;
499     int *tmp;
500
501     assert(n <= wh);
502     tmp = snewn(wh, int);
503
504     /*
505      * Clear the map, and set up `tmp' as a list of grid indices.
506      */
507     for (i = 0; i < wh; i++) {
508         map[i] = -1;
509         tmp[i] = i;
510     }
511
512     /*
513      * Place the region seeds by selecting n members from `tmp'.
514      */
515     k = wh;
516     for (i = 0; i < n; i++) {
517         int j = random_upto(rs, k);
518         map[tmp[j]] = i;
519         tmp[j] = tmp[--k];
520     }
521
522     /*
523      * Re-initialise `tmp' as a cumulative frequency table. This
524      * will store the number of possible region colours we can
525      * extend into each square.
526      */
527     cf_init(tmp, wh);
528
529     /*
530      * Go through the grid and set up the initial cumulative
531      * frequencies.
532      */
533     for (y = 0; y < h; y++)
534         for (x = 0; x < w; x++)
535             cf_add(tmp, wh, y*w+x,
536                    extend_options(w, h, n, map, x, y, -1));
537
538     /*
539      * Now repeatedly choose a square we can extend a region into,
540      * and do so.
541      */
542     while (tmp[0] > 0) {
543         int k = random_upto(rs, tmp[0]);
544         int sq;
545         int colour;
546         int xx, yy;
547
548         sq = cf_whichsym(tmp, wh, k);
549         k -= cf_clookup(tmp, wh, sq);
550         x = sq % w;
551         y = sq / w;
552         colour = extend_options(w, h, n, map, x, y, k);
553
554         map[sq] = colour;
555
556         /*
557          * Re-scan the nine cells around the one we've just
558          * modified.
559          */
560         for (yy = max(y-1, 0); yy < min(y+2, h); yy++)
561             for (xx = max(x-1, 0); xx < min(x+2, w); xx++) {
562                 cf_add(tmp, wh, yy*w+xx,
563                        -cf_slookup(tmp, wh, yy*w+xx) +
564                        extend_options(w, h, n, map, xx, yy, -1));
565             }
566     }
567
568     /*
569      * Finally, go through and normalise the region labels into
570      * order, meaning that indistinguishable maps are actually
571      * identical.
572      */
573     for (i = 0; i < n; i++)
574         tmp[i] = -1;
575     k = 0;
576     for (i = 0; i < wh; i++) {
577         assert(map[i] >= 0);
578         if (tmp[map[i]] < 0)
579             tmp[map[i]] = k++;
580         map[i] = tmp[map[i]];
581     }
582
583     sfree(tmp);
584 }
585
586 /* ----------------------------------------------------------------------
587  * Functions to handle graphs.
588  */
589
590 /*
591  * Having got a map in a square grid, convert it into a graph
592  * representation.
593  */
594 static int gengraph(int w, int h, int n, int *map, int *graph)
595 {
596     int i, j, x, y;
597
598     /*
599      * Start by setting the graph up as an adjacency matrix. We'll
600      * turn it into a list later.
601      */
602     for (i = 0; i < n*n; i++)
603         graph[i] = 0;
604
605     /*
606      * Iterate over the map looking for all adjacencies.
607      */
608     for (y = 0; y < h; y++)
609         for (x = 0; x < w; x++) {
610             int v, vx, vy;
611             v = map[y*w+x];
612             if (x+1 < w && (vx = map[y*w+(x+1)]) != v)
613                 graph[v*n+vx] = graph[vx*n+v] = 1;
614             if (y+1 < h && (vy = map[(y+1)*w+x]) != v)
615                 graph[v*n+vy] = graph[vy*n+v] = 1;
616         }
617
618     /*
619      * Turn the matrix into a list.
620      */
621     for (i = j = 0; i < n*n; i++)
622         if (graph[i])
623             graph[j++] = i;
624
625     return j;
626 }
627
628 static int graph_edge_index(int *graph, int n, int ngraph, int i, int j)
629 {
630     int v = i*n+j;
631     int top, bot, mid;
632
633     bot = -1;
634     top = ngraph;
635     while (top - bot > 1) {
636         mid = (top + bot) / 2;
637         if (graph[mid] == v)
638             return mid;
639         else if (graph[mid] < v)
640             bot = mid;
641         else
642             top = mid;
643     }
644     return -1;
645 }
646
647 #define graph_adjacent(graph, n, ngraph, i, j) \
648     (graph_edge_index((graph), (n), (ngraph), (i), (j)) >= 0)
649
650 static int graph_vertex_start(int *graph, int n, int ngraph, int i)
651 {
652     int v = i*n;
653     int top, bot, mid;
654
655     bot = -1;
656     top = ngraph;
657     while (top - bot > 1) {
658         mid = (top + bot) / 2;
659         if (graph[mid] < v)
660             bot = mid;
661         else
662             top = mid;
663     }
664     return top;
665 }
666
667 /* ----------------------------------------------------------------------
668  * Generate a four-colouring of a graph.
669  *
670  * FIXME: it would be nice if we could convert this recursion into
671  * pseudo-recursion using some sort of explicit stack array, for
672  * the sake of the Palm port and its limited stack.
673  */
674
675 static int fourcolour_recurse(int *graph, int n, int ngraph,
676                               int *colouring, int *scratch, random_state *rs)
677 {
678     int nfree, nvert, start, i, j, k, c, ci;
679     int cs[FOUR];
680
681     /*
682      * Find the smallest number of free colours in any uncoloured
683      * vertex, and count the number of such vertices.
684      */
685
686     nfree = FIVE;                      /* start off bigger than FOUR! */
687     nvert = 0;
688     for (i = 0; i < n; i++)
689         if (colouring[i] < 0 && scratch[i*FIVE+FOUR] <= nfree) {
690             if (nfree > scratch[i*FIVE+FOUR]) {
691                 nfree = scratch[i*FIVE+FOUR];
692                 nvert = 0;
693             }
694             nvert++;
695         }
696
697     /*
698      * If there aren't any uncoloured vertices at all, we're done.
699      */
700     if (nvert == 0)
701         return TRUE;                   /* we've got a colouring! */
702
703     /*
704      * Pick a random vertex in that set.
705      */
706     j = random_upto(rs, nvert);
707     for (i = 0; i < n; i++)
708         if (colouring[i] < 0 && scratch[i*FIVE+FOUR] == nfree)
709             if (j-- == 0)
710                 break;
711     assert(i < n);
712     start = graph_vertex_start(graph, n, ngraph, i);
713
714     /*
715      * Loop over the possible colours for i, and recurse for each
716      * one.
717      */
718     ci = 0;
719     for (c = 0; c < FOUR; c++)
720         if (scratch[i*FIVE+c] == 0)
721             cs[ci++] = c;
722     shuffle(cs, ci, sizeof(*cs), rs);
723
724     while (ci-- > 0) {
725         c = cs[ci];
726
727         /*
728          * Fill in this colour.
729          */
730         colouring[i] = c;
731
732         /*
733          * Update the scratch space to reflect a new neighbour
734          * of this colour for each neighbour of vertex i.
735          */
736         for (j = start; j < ngraph && graph[j] < n*(i+1); j++) {
737             k = graph[j] - i*n;
738             if (scratch[k*FIVE+c] == 0)
739                 scratch[k*FIVE+FOUR]--;
740             scratch[k*FIVE+c]++;
741         }
742
743         /*
744          * Recurse.
745          */
746         if (fourcolour_recurse(graph, n, ngraph, colouring, scratch, rs))
747             return TRUE;               /* got one! */
748
749         /*
750          * If that didn't work, clean up and try again with a
751          * different colour.
752          */
753         for (j = start; j < ngraph && graph[j] < n*(i+1); j++) {
754             k = graph[j] - i*n;
755             scratch[k*FIVE+c]--;
756             if (scratch[k*FIVE+c] == 0)
757                 scratch[k*FIVE+FOUR]++;
758         }
759         colouring[i] = -1;
760     }
761
762     /*
763      * If we reach here, we were unable to find a colouring at all.
764      * (This doesn't necessarily mean the Four Colour Theorem is
765      * violated; it might just mean we've gone down a dead end and
766      * need to back up and look somewhere else. It's only an FCT
767      * violation if we get all the way back up to the top level and
768      * still fail.)
769      */
770     return FALSE;
771 }
772
773 static void fourcolour(int *graph, int n, int ngraph, int *colouring,
774                        random_state *rs)
775 {
776     int *scratch;
777     int i;
778
779     /*
780      * For each vertex and each colour, we store the number of
781      * neighbours that have that colour. Also, we store the number
782      * of free colours for the vertex.
783      */
784     scratch = snewn(n * FIVE, int);
785     for (i = 0; i < n * FIVE; i++)
786         scratch[i] = (i % FIVE == FOUR ? FOUR : 0);
787
788     /*
789      * Clear the colouring to start with.
790      */
791     for (i = 0; i < n; i++)
792         colouring[i] = -1;
793
794     i = fourcolour_recurse(graph, n, ngraph, colouring, scratch, rs);
795     assert(i);                         /* by the Four Colour Theorem :-) */
796
797     sfree(scratch);
798 }
799
800 /* ----------------------------------------------------------------------
801  * Non-recursive solver.
802  */
803
804 struct solver_scratch {
805     unsigned char *possible;           /* bitmap of colours for each region */
806
807     int *graph;
808     int n;
809     int ngraph;
810
811     int *bfsqueue;
812     int *bfscolour;
813 #ifdef SOLVER_DIAGNOSTICS
814     int *bfsprev;
815 #endif
816
817     int depth;
818 };
819
820 static struct solver_scratch *new_scratch(int *graph, int n, int ngraph)
821 {
822     struct solver_scratch *sc;
823
824     sc = snew(struct solver_scratch);
825     sc->graph = graph;
826     sc->n = n;
827     sc->ngraph = ngraph;
828     sc->possible = snewn(n, unsigned char);
829     sc->depth = 0;
830     sc->bfsqueue = snewn(n, int);
831     sc->bfscolour = snewn(n, int);
832 #ifdef SOLVER_DIAGNOSTICS
833     sc->bfsprev = snewn(n, int);
834 #endif
835
836     return sc;
837 }
838
839 static void free_scratch(struct solver_scratch *sc)
840 {
841     sfree(sc->possible);
842     sfree(sc->bfsqueue);
843     sfree(sc->bfscolour);
844 #ifdef SOLVER_DIAGNOSTICS
845     sfree(sc->bfsprev);
846 #endif
847     sfree(sc);
848 }
849
850 /*
851  * Count the bits in a word. Only needs to cope with FOUR bits.
852  */
853 static int bitcount(int word)
854 {
855     assert(FOUR <= 4);                 /* or this needs changing */
856     word = ((word & 0xA) >> 1) + (word & 0x5);
857     word = ((word & 0xC) >> 2) + (word & 0x3);
858     return word;
859 }
860
861 #ifdef SOLVER_DIAGNOSTICS
862 static const char colnames[FOUR] = { 'R', 'Y', 'G', 'B' };
863 #endif
864
865 static int place_colour(struct solver_scratch *sc,
866                         int *colouring, int index, int colour
867 #ifdef SOLVER_DIAGNOSTICS
868                         , char *verb
869 #endif
870                         )
871 {
872     int *graph = sc->graph, n = sc->n, ngraph = sc->ngraph;
873     int j, k;
874
875     if (!(sc->possible[index] & (1 << colour))) {
876 #ifdef SOLVER_DIAGNOSTICS
877         if (verbose)
878             printf("%*scannot place %c in region %d\n", 2*sc->depth, "",
879                    colnames[colour], index);
880 #endif
881         return FALSE;                  /* can't do it */
882     }
883
884     sc->possible[index] = 1 << colour;
885     colouring[index] = colour;
886
887 #ifdef SOLVER_DIAGNOSTICS
888     if (verbose)
889         printf("%*s%s %c in region %d\n", 2*sc->depth, "",
890                verb, colnames[colour], index);
891 #endif
892
893     /*
894      * Rule out this colour from all the region's neighbours.
895      */
896     for (j = graph_vertex_start(graph, n, ngraph, index);
897          j < ngraph && graph[j] < n*(index+1); j++) {
898         k = graph[j] - index*n;
899 #ifdef SOLVER_DIAGNOSTICS
900         if (verbose && (sc->possible[k] & (1 << colour)))
901             printf("%*s  ruling out %c in region %d\n", 2*sc->depth, "",
902                    colnames[colour], k);
903 #endif
904         sc->possible[k] &= ~(1 << colour);
905     }
906
907     return TRUE;
908 }
909
910 #ifdef SOLVER_DIAGNOSTICS
911 static char *colourset(char *buf, int set)
912 {
913     int i;
914     char *p = buf;
915     char *sep = "";
916
917     for (i = 0; i < FOUR; i++)
918         if (set & (1 << i)) {
919             p += sprintf(p, "%s%c", sep, colnames[i]);
920             sep = ",";
921         }
922
923     return buf;
924 }
925 #endif
926
927 /*
928  * Returns 0 for impossible, 1 for success, 2 for failure to
929  * converge (i.e. puzzle is either ambiguous or just too
930  * difficult).
931  */
932 static int map_solver(struct solver_scratch *sc,
933                       int *graph, int n, int ngraph, int *colouring,
934                       int difficulty)
935 {
936     int i;
937
938     if (sc->depth == 0) {
939         /*
940          * Initialise scratch space.
941          */
942         for (i = 0; i < n; i++)
943             sc->possible[i] = (1 << FOUR) - 1;
944
945         /*
946          * Place clues.
947          */
948         for (i = 0; i < n; i++)
949             if (colouring[i] >= 0) {
950                 if (!place_colour(sc, colouring, i, colouring[i]
951 #ifdef SOLVER_DIAGNOSTICS
952                                   , "initial clue:"
953 #endif
954                                   )) {
955 #ifdef SOLVER_DIAGNOSTICS
956                     if (verbose)
957                         printf("%*sinitial clue set is inconsistent\n",
958                                2*sc->depth, "");
959 #endif
960                     return 0;          /* the clues aren't even consistent! */
961                 }
962             }
963     }
964
965     /*
966      * Now repeatedly loop until we find nothing further to do.
967      */
968     while (1) {
969         int done_something = FALSE;
970
971         if (difficulty < DIFF_EASY)
972             break;                     /* can't do anything at all! */
973
974         /*
975          * Simplest possible deduction: find a region with only one
976          * possible colour.
977          */
978         for (i = 0; i < n; i++) if (colouring[i] < 0) {
979             int p = sc->possible[i];
980
981             if (p == 0) {
982 #ifdef SOLVER_DIAGNOSTICS
983                 if (verbose)
984                     printf("%*sregion %d has no possible colours left\n",
985                            2*sc->depth, "", i);
986 #endif
987                 return 0;              /* puzzle is inconsistent */
988             }
989
990             if ((p & (p-1)) == 0) {    /* p is a power of two */
991                 int c, ret;
992                 for (c = 0; c < FOUR; c++)
993                     if (p == (1 << c))
994                         break;
995                 assert(c < FOUR);
996                 ret = place_colour(sc, colouring, i, c
997 #ifdef SOLVER_DIAGNOSTICS
998                                    , "placing"
999 #endif
1000                                    );
1001                 /*
1002                  * place_colour() can only fail if colour c was not
1003                  * even a _possibility_ for region i, and we're
1004                  * pretty sure it was because we checked before
1005                  * calling place_colour(). So we can safely assert
1006                  * here rather than having to return a nice
1007                  * friendly error code.
1008                  */
1009                 assert(ret);
1010                 done_something = TRUE;
1011             }
1012         }
1013
1014         if (done_something)
1015             continue;
1016
1017         if (difficulty < DIFF_NORMAL)
1018             break;                     /* can't do anything harder */
1019
1020         /*
1021          * Failing that, go up one level. Look for pairs of regions
1022          * which (a) both have the same pair of possible colours,
1023          * (b) are adjacent to one another, (c) are adjacent to the
1024          * same region, and (d) that region still thinks it has one
1025          * or both of those possible colours.
1026          * 
1027          * Simplest way to do this is by going through the graph
1028          * edge by edge, so that we start with property (b) and
1029          * then look for (a) and finally (c) and (d).
1030          */
1031         for (i = 0; i < ngraph; i++) {
1032             int j1 = graph[i] / n, j2 = graph[i] % n;
1033             int j, k, v, v2;
1034 #ifdef SOLVER_DIAGNOSTICS
1035             int started = FALSE;
1036 #endif
1037
1038             if (j1 > j2)
1039                 continue;              /* done it already, other way round */
1040
1041             if (colouring[j1] >= 0 || colouring[j2] >= 0)
1042                 continue;              /* they're not undecided */
1043
1044             if (sc->possible[j1] != sc->possible[j2])
1045                 continue;              /* they don't have the same possibles */
1046
1047             v = sc->possible[j1];
1048             /*
1049              * See if v contains exactly two set bits.
1050              */
1051             v2 = v & -v;           /* find lowest set bit */
1052             v2 = v & ~v2;          /* clear it */
1053             if (v2 == 0 || (v2 & (v2-1)) != 0)   /* not power of 2 */
1054                 continue;
1055
1056             /*
1057              * We've found regions j1 and j2 satisfying properties
1058              * (a) and (b): they have two possible colours between
1059              * them, and since they're adjacent to one another they
1060              * must use _both_ those colours between them.
1061              * Therefore, if they are both adjacent to any other
1062              * region then that region cannot be either colour.
1063              * 
1064              * Go through the neighbours of j1 and see if any are
1065              * shared with j2.
1066              */
1067             for (j = graph_vertex_start(graph, n, ngraph, j1);
1068                  j < ngraph && graph[j] < n*(j1+1); j++) {
1069                 k = graph[j] - j1*n;
1070                 if (graph_adjacent(graph, n, ngraph, k, j2) &&
1071                     (sc->possible[k] & v)) {
1072 #ifdef SOLVER_DIAGNOSTICS
1073                     if (verbose) {
1074                         char buf[80];
1075                         if (!started)
1076                             printf("%*sadjacent regions %d,%d share colours"
1077                                    " %s\n", 2*sc->depth, "", j1, j2,
1078                                    colourset(buf, v));
1079                         started = TRUE;
1080                         printf("%*s  ruling out %s in region %d\n",2*sc->depth,
1081                                "", colourset(buf, sc->possible[k] & v), k);
1082                     }
1083 #endif
1084                     sc->possible[k] &= ~v;
1085                     done_something = TRUE;
1086                 }
1087             }
1088         }
1089
1090         if (done_something)
1091             continue;
1092
1093         if (difficulty < DIFF_HARD)
1094             break;                     /* can't do anything harder */
1095
1096         /*
1097          * Right; now we get creative. Now we're going to look for
1098          * `forcing chains'. A forcing chain is a path through the
1099          * graph with the following properties:
1100          * 
1101          *  (a) Each vertex on the path has precisely two possible
1102          *      colours.
1103          * 
1104          *  (b) Each pair of vertices which are adjacent on the
1105          *      path share at least one possible colour in common.
1106          * 
1107          *  (c) Each vertex in the middle of the path shares _both_
1108          *      of its colours with at least one of its neighbours
1109          *      (not the same one with both neighbours).
1110          * 
1111          * These together imply that at least one of the possible
1112          * colour choices at one end of the path forces _all_ the
1113          * rest of the colours along the path. In order to make
1114          * real use of this, we need further properties:
1115          * 
1116          *  (c) Ruling out some colour C from the vertex at one end
1117          *      of the path forces the vertex at the other end to
1118          *      take colour C.
1119          * 
1120          *  (d) The two end vertices are mutually adjacent to some
1121          *      third vertex.
1122          * 
1123          *  (e) That third vertex currently has C as a possibility.
1124          * 
1125          * If we can find all of that lot, we can deduce that at
1126          * least one of the two ends of the forcing chain has
1127          * colour C, and that therefore the mutually adjacent third
1128          * vertex does not.
1129          * 
1130          * To find forcing chains, we're going to start a bfs at
1131          * each suitable vertex of the graph, once for each of its
1132          * two possible colours.
1133          */
1134         for (i = 0; i < n; i++) {
1135             int c;
1136
1137             if (colouring[i] >= 0 || bitcount(sc->possible[i]) != 2)
1138                 continue;
1139
1140             for (c = 0; c < FOUR; c++)
1141                 if (sc->possible[i] & (1 << c)) {
1142                     int j, k, gi, origc, currc, head, tail;
1143                     /*
1144                      * Try a bfs from this vertex, ruling out
1145                      * colour c.
1146                      * 
1147                      * Within this loop, we work in colour bitmaps
1148                      * rather than actual colours, because
1149                      * converting back and forth is a needless
1150                      * computational expense.
1151                      */
1152
1153                     origc = 1 << c;
1154
1155                     for (j = 0; j < n; j++) {
1156                         sc->bfscolour[j] = -1;
1157 #ifdef SOLVER_DIAGNOSTICS
1158                         sc->bfsprev[j] = -1;
1159 #endif
1160                     }
1161                     head = tail = 0;
1162                     sc->bfsqueue[tail++] = i;
1163                     sc->bfscolour[i] = sc->possible[i] &~ origc;
1164
1165                     while (head < tail) {
1166                         j = sc->bfsqueue[head++];
1167                         currc = sc->bfscolour[j];
1168
1169                         /*
1170                          * Try neighbours of j.
1171                          */
1172                         for (gi = graph_vertex_start(graph, n, ngraph, j);
1173                              gi < ngraph && graph[gi] < n*(j+1); gi++) {
1174                             k = graph[gi] - j*n;
1175
1176                             /*
1177                              * To continue with the bfs in vertex
1178                              * k, we need k to be
1179                              *  (a) not already visited
1180                              *  (b) have two possible colours
1181                              *  (c) those colours include currc.
1182                              */
1183
1184                             if (sc->bfscolour[k] < 0 &&
1185                                 colouring[k] < 0 &&
1186                                 bitcount(sc->possible[k]) == 2 &&
1187                                 (sc->possible[k] & currc)) {
1188                                 sc->bfsqueue[tail++] = k;
1189                                 sc->bfscolour[k] =
1190                                     sc->possible[k] &~ currc;
1191 #ifdef SOLVER_DIAGNOSTICS
1192                                 sc->bfsprev[k] = j;
1193 #endif
1194                             }
1195
1196                             /*
1197                              * One other possibility is that k
1198                              * might be the region in which we can
1199                              * make a real deduction: if it's
1200                              * adjacent to i, contains currc as a
1201                              * possibility, and currc is equal to
1202                              * the original colour we ruled out.
1203                              */
1204                             if (currc == origc &&
1205                                 graph_adjacent(graph, n, ngraph, k, i) &&
1206                                 (sc->possible[k] & currc)) {
1207 #ifdef SOLVER_DIAGNOSTICS
1208                                 if (verbose) {
1209                                     char buf[80], *sep = "";
1210                                     int r;
1211
1212                                     printf("%*sforcing chain, colour %s, ",
1213                                            2*sc->depth, "",
1214                                            colourset(buf, origc));
1215                                     for (r = j; r != -1; r = sc->bfsprev[r]) {
1216                                         printf("%s%d", sep, r);
1217                                         sep = "-";
1218                                     }
1219                                     printf("\n%*s  ruling out %s in region"
1220                                            " %d\n", 2*sc->depth, "",
1221                                            colourset(buf, origc), k);
1222                                 }
1223 #endif
1224                                 sc->possible[k] &= ~origc;
1225                                 done_something = TRUE;
1226                             }
1227                         }
1228                     }
1229
1230                     assert(tail <= n);
1231                 }
1232         }
1233
1234         if (!done_something)
1235             break;
1236     }
1237
1238     /*
1239      * See if we've got a complete solution, and return if so.
1240      */
1241     for (i = 0; i < n; i++)
1242         if (colouring[i] < 0)
1243             break;
1244     if (i == n) {
1245 #ifdef SOLVER_DIAGNOSTICS
1246         if (verbose)
1247             printf("%*sone solution found\n", 2*sc->depth, "");
1248 #endif
1249         return 1;                      /* success! */
1250     }
1251
1252     /*
1253      * If recursion is not permissible, we now give up.
1254      */
1255     if (difficulty < DIFF_RECURSE) {
1256 #ifdef SOLVER_DIAGNOSTICS
1257         if (verbose)
1258             printf("%*sunable to proceed further without recursion\n",
1259                    2*sc->depth, "");
1260 #endif
1261         return 2;                      /* unable to complete */
1262     }
1263
1264     /*
1265      * Now we've got to do something recursive. So first hunt for a
1266      * currently-most-constrained region.
1267      */
1268     {
1269         int best, bestc;
1270         struct solver_scratch *rsc;
1271         int *subcolouring, *origcolouring;
1272         int ret, subret;
1273         int we_already_got_one;
1274
1275         best = -1;
1276         bestc = FIVE;
1277
1278         for (i = 0; i < n; i++) if (colouring[i] < 0) {
1279             int p = sc->possible[i];
1280             enum { compile_time_assertion = 1 / (FOUR <= 4) };
1281             int c;
1282
1283             /* Count the set bits. */
1284             c = (p & 5) + ((p >> 1) & 5);
1285             c = (c & 3) + ((c >> 2) & 3);
1286             assert(c > 1);             /* or colouring[i] would be >= 0 */
1287
1288             if (c < bestc) {
1289                 best = i;
1290                 bestc = c;
1291             }
1292         }
1293
1294         assert(best >= 0);             /* or we'd be solved already */
1295
1296 #ifdef SOLVER_DIAGNOSTICS
1297         if (verbose)
1298             printf("%*srecursing on region %d\n", 2*sc->depth, "", best);
1299 #endif
1300
1301         /*
1302          * Now iterate over the possible colours for this region.
1303          */
1304         rsc = new_scratch(graph, n, ngraph);
1305         rsc->depth = sc->depth + 1;
1306         origcolouring = snewn(n, int);
1307         memcpy(origcolouring, colouring, n * sizeof(int));
1308         subcolouring = snewn(n, int);
1309         we_already_got_one = FALSE;
1310         ret = 0;
1311
1312         for (i = 0; i < FOUR; i++) {
1313             if (!(sc->possible[best] & (1 << i)))
1314                 continue;
1315
1316             memcpy(rsc->possible, sc->possible, n);
1317             memcpy(subcolouring, origcolouring, n * sizeof(int));
1318
1319             place_colour(rsc, subcolouring, best, i
1320 #ifdef SOLVER_DIAGNOSTICS
1321                          , "trying"
1322 #endif
1323                          );
1324
1325             subret = map_solver(rsc, graph, n, ngraph,
1326                                 subcolouring, difficulty);
1327
1328 #ifdef SOLVER_DIAGNOSTICS
1329             if (verbose) {
1330                 printf("%*sretracting %c in region %d; found %s\n",
1331                        2*sc->depth, "", colnames[i], best,
1332                        subret == 0 ? "no solutions" :
1333                        subret == 1 ? "one solution" : "multiple solutions");
1334             }
1335 #endif
1336
1337             /*
1338              * If this possibility turned up more than one valid
1339              * solution, or if it turned up one and we already had
1340              * one, we're definitely ambiguous.
1341              */
1342             if (subret == 2 || (subret == 1 && we_already_got_one)) {
1343                 ret = 2;
1344                 break;
1345             }
1346
1347             /*
1348              * If this possibility turned up one valid solution and
1349              * it's the first we've seen, copy it into the output.
1350              */
1351             if (subret == 1) {
1352                 memcpy(colouring, subcolouring, n * sizeof(int));
1353                 we_already_got_one = TRUE;
1354                 ret = 1;
1355             }
1356
1357             /*
1358              * Otherwise, this guess led to a contradiction, so we
1359              * do nothing.
1360              */
1361         }
1362
1363         sfree(subcolouring);
1364         free_scratch(rsc);
1365
1366 #ifdef SOLVER_DIAGNOSTICS
1367         if (verbose && sc->depth == 0) {
1368             printf("%*s%s found\n",
1369                    2*sc->depth, "",
1370                    ret == 0 ? "no solutions" :
1371                    ret == 1 ? "one solution" : "multiple solutions");
1372         }
1373 #endif
1374         return ret;
1375     }
1376 }
1377
1378 /* ----------------------------------------------------------------------
1379  * Game generation main function.
1380  */
1381
1382 static char *new_game_desc(game_params *params, random_state *rs,
1383                            char **aux, int interactive)
1384 {
1385     struct solver_scratch *sc = NULL;
1386     int *map, *graph, ngraph, *colouring, *colouring2, *regions;
1387     int i, j, w, h, n, solveret, cfreq[FOUR];
1388     int wh;
1389     int mindiff, tries;
1390 #ifdef GENERATION_DIAGNOSTICS
1391     int x, y;
1392 #endif
1393     char *ret, buf[80];
1394     int retlen, retsize;
1395
1396     w = params->w;
1397     h = params->h;
1398     n = params->n;
1399     wh = w*h;
1400
1401     *aux = NULL;
1402
1403     map = snewn(wh, int);
1404     graph = snewn(n*n, int);
1405     colouring = snewn(n, int);
1406     colouring2 = snewn(n, int);
1407     regions = snewn(n, int);
1408
1409     /*
1410      * This is the minimum difficulty below which we'll completely
1411      * reject a map design. Normally we set this to one below the
1412      * requested difficulty, ensuring that we have the right
1413      * result. However, for particularly dense maps or maps with
1414      * particularly few regions it might not be possible to get the
1415      * desired difficulty, so we will eventually drop this down to
1416      * -1 to indicate that any old map will do.
1417      */
1418     mindiff = params->diff;
1419     tries = 50;
1420
1421     while (1) {
1422
1423         /*
1424          * Create the map.
1425          */
1426         genmap(w, h, n, map, rs);
1427
1428 #ifdef GENERATION_DIAGNOSTICS
1429         for (y = 0; y < h; y++) {
1430             for (x = 0; x < w; x++) {
1431                 int v = map[y*w+x];
1432                 if (v >= 62)
1433                     putchar('!');
1434                 else if (v >= 36)
1435                     putchar('a' + v-36);
1436                 else if (v >= 10)
1437                     putchar('A' + v-10);
1438                 else
1439                     putchar('0' + v);
1440             }
1441             putchar('\n');
1442         }
1443 #endif
1444
1445         /*
1446          * Convert the map into a graph.
1447          */
1448         ngraph = gengraph(w, h, n, map, graph);
1449
1450 #ifdef GENERATION_DIAGNOSTICS
1451         for (i = 0; i < ngraph; i++)
1452             printf("%d-%d\n", graph[i]/n, graph[i]%n);
1453 #endif
1454
1455         /*
1456          * Colour the map.
1457          */
1458         fourcolour(graph, n, ngraph, colouring, rs);
1459
1460 #ifdef GENERATION_DIAGNOSTICS
1461         for (i = 0; i < n; i++)
1462             printf("%d: %d\n", i, colouring[i]);
1463
1464         for (y = 0; y < h; y++) {
1465             for (x = 0; x < w; x++) {
1466                 int v = colouring[map[y*w+x]];
1467                 if (v >= 36)
1468                     putchar('a' + v-36);
1469                 else if (v >= 10)
1470                     putchar('A' + v-10);
1471                 else
1472                     putchar('0' + v);
1473             }
1474             putchar('\n');
1475         }
1476 #endif
1477
1478         /*
1479          * Encode the solution as an aux string.
1480          */
1481         if (*aux)                      /* in case we've come round again */
1482             sfree(*aux);
1483         retlen = retsize = 0;
1484         ret = NULL;
1485         for (i = 0; i < n; i++) {
1486             int len;
1487
1488             if (colouring[i] < 0)
1489                 continue;
1490
1491             len = sprintf(buf, "%s%d:%d", i ? ";" : "S;", colouring[i], i);
1492             if (retlen + len >= retsize) {
1493                 retsize = retlen + len + 256;
1494                 ret = sresize(ret, retsize, char);
1495             }
1496             strcpy(ret + retlen, buf);
1497             retlen += len;
1498         }
1499         *aux = ret;
1500
1501         /*
1502          * Remove the region colours one by one, keeping
1503          * solubility. Also ensure that there always remains at
1504          * least one region of every colour, so that the user can
1505          * drag from somewhere.
1506          */
1507         for (i = 0; i < FOUR; i++)
1508             cfreq[i] = 0;
1509         for (i = 0; i < n; i++) {
1510             regions[i] = i;
1511             cfreq[colouring[i]]++;
1512         }
1513         for (i = 0; i < FOUR; i++)
1514             if (cfreq[i] == 0)
1515                 continue;
1516
1517         shuffle(regions, n, sizeof(*regions), rs);
1518
1519         if (sc) free_scratch(sc);
1520         sc = new_scratch(graph, n, ngraph);
1521
1522         for (i = 0; i < n; i++) {
1523             j = regions[i];
1524
1525             if (cfreq[colouring[j]] == 1)
1526                 continue;              /* can't remove last region of colour */
1527
1528             memcpy(colouring2, colouring, n*sizeof(int));
1529             colouring2[j] = -1;
1530             solveret = map_solver(sc, graph, n, ngraph, colouring2,
1531                                   params->diff);
1532             assert(solveret >= 0);             /* mustn't be impossible! */
1533             if (solveret == 1) {
1534                 cfreq[colouring[j]]--;
1535                 colouring[j] = -1;
1536             }
1537         }
1538
1539 #ifdef GENERATION_DIAGNOSTICS
1540         for (i = 0; i < n; i++)
1541             if (colouring[i] >= 0) {
1542                 if (i >= 62)
1543                     putchar('!');
1544                 else if (i >= 36)
1545                     putchar('a' + i-36);
1546                 else if (i >= 10)
1547                     putchar('A' + i-10);
1548                 else
1549                     putchar('0' + i);
1550                 printf(": %d\n", colouring[i]);
1551             }
1552 #endif
1553
1554         /*
1555          * Finally, check that the puzzle is _at least_ as hard as
1556          * required, and indeed that it isn't already solved.
1557          * (Calling map_solver with negative difficulty ensures the
1558          * latter - if a solver which _does nothing_ can solve it,
1559          * it's too easy!)
1560          */
1561         memcpy(colouring2, colouring, n*sizeof(int));
1562         if (map_solver(sc, graph, n, ngraph, colouring2,
1563                        mindiff - 1) == 1) {
1564             /*
1565              * Drop minimum difficulty if necessary.
1566              */
1567             if (mindiff > 0 && (n < 9 || n > 2*wh/3)) {
1568                 if (tries-- <= 0)
1569                     mindiff = 0;       /* give up and go for Easy */
1570             }
1571             continue;
1572         }
1573
1574         break;
1575     }
1576
1577     /*
1578      * Encode as a game ID. We do this by:
1579      * 
1580      *  - first going along the horizontal edges row by row, and
1581      *    then the vertical edges column by column
1582      *  - encoding the lengths of runs of edges and runs of
1583      *    non-edges
1584      *  - the decoder will reconstitute the region boundaries from
1585      *    this and automatically number them the same way we did
1586      *  - then we encode the initial region colours in a Slant-like
1587      *    fashion (digits 0-3 interspersed with letters giving
1588      *    lengths of runs of empty spaces).
1589      */
1590     retlen = retsize = 0;
1591     ret = NULL;
1592
1593     {
1594         int run, pv;
1595
1596         /*
1597          * Start with a notional non-edge, so that there'll be an
1598          * explicit `a' to distinguish the case where we start with
1599          * an edge.
1600          */
1601         run = 1;
1602         pv = 0;
1603
1604         for (i = 0; i < w*(h-1) + (w-1)*h; i++) {
1605             int x, y, dx, dy, v;
1606
1607             if (i < w*(h-1)) {
1608                 /* Horizontal edge. */
1609                 y = i / w;
1610                 x = i % w;
1611                 dx = 0;
1612                 dy = 1;
1613             } else {
1614                 /* Vertical edge. */
1615                 x = (i - w*(h-1)) / h;
1616                 y = (i - w*(h-1)) % h;
1617                 dx = 1;
1618                 dy = 0;
1619             }
1620
1621             if (retlen + 10 >= retsize) {
1622                 retsize = retlen + 256;
1623                 ret = sresize(ret, retsize, char);
1624             }
1625
1626             v = (map[y*w+x] != map[(y+dy)*w+(x+dx)]);
1627
1628             if (pv != v) {
1629                 ret[retlen++] = 'a'-1 + run;
1630                 run = 1;
1631                 pv = v;
1632             } else {
1633                 /*
1634                  * 'z' is a special case in this encoding. Rather
1635                  * than meaning a run of 26 and a state switch, it
1636                  * means a run of 25 and _no_ state switch, because
1637                  * otherwise there'd be no way to encode runs of
1638                  * more than 26.
1639                  */
1640                 if (run == 25) {
1641                     ret[retlen++] = 'z';
1642                     run = 0;
1643                 }
1644                 run++;
1645             }
1646         }
1647
1648         ret[retlen++] = 'a'-1 + run;
1649         ret[retlen++] = ',';
1650
1651         run = 0;
1652         for (i = 0; i < n; i++) {
1653             if (retlen + 10 >= retsize) {
1654                 retsize = retlen + 256;
1655                 ret = sresize(ret, retsize, char);
1656             }
1657
1658             if (colouring[i] < 0) {
1659                 /*
1660                  * In _this_ encoding, 'z' is a run of 26, since
1661                  * there's no implicit state switch after each run.
1662                  * Confusingly different, but more compact.
1663                  */
1664                 if (run == 26) {
1665                     ret[retlen++] = 'z';
1666                     run = 0;
1667                 }
1668                 run++;
1669             } else {
1670                 if (run > 0)
1671                     ret[retlen++] = 'a'-1 + run;
1672                 ret[retlen++] = '0' + colouring[i];
1673                 run = 0;
1674             }
1675         }
1676         if (run > 0)
1677             ret[retlen++] = 'a'-1 + run;
1678         ret[retlen] = '\0';
1679
1680         assert(retlen < retsize);
1681     }
1682
1683     free_scratch(sc);
1684     sfree(regions);
1685     sfree(colouring2);
1686     sfree(colouring);
1687     sfree(graph);
1688     sfree(map);
1689
1690     return ret;
1691 }
1692
1693 static char *parse_edge_list(game_params *params, char **desc, int *map)
1694 {
1695     int w = params->w, h = params->h, wh = w*h, n = params->n;
1696     int i, k, pos, state;
1697     char *p = *desc;
1698
1699     for (i = 0; i < wh; i++)
1700         map[wh+i] = i;
1701
1702     pos = -1;
1703     state = 0;
1704
1705     /*
1706      * Parse the game description to get the list of edges, and
1707      * build up a disjoint set forest as we go (by identifying
1708      * pairs of squares whenever the edge list shows a non-edge).
1709      */
1710     while (*p && *p != ',') {
1711         if (*p < 'a' || *p > 'z')
1712             return "Unexpected character in edge list";
1713         if (*p == 'z')
1714             k = 25;
1715         else
1716             k = *p - 'a' + 1;
1717         while (k-- > 0) {
1718             int x, y, dx, dy;
1719
1720             if (pos < 0) {
1721                 pos++;
1722                 continue;
1723             } else if (pos < w*(h-1)) {
1724                 /* Horizontal edge. */
1725                 y = pos / w;
1726                 x = pos % w;
1727                 dx = 0;
1728                 dy = 1;
1729             } else if (pos < 2*wh-w-h) {
1730                 /* Vertical edge. */
1731                 x = (pos - w*(h-1)) / h;
1732                 y = (pos - w*(h-1)) % h;
1733                 dx = 1;
1734                 dy = 0;
1735             } else
1736                 return "Too much data in edge list";
1737             if (!state)
1738                 dsf_merge(map+wh, y*w+x, (y+dy)*w+(x+dx));
1739
1740             pos++;
1741         }
1742         if (*p != 'z')
1743             state = !state;
1744         p++;
1745     }
1746     assert(pos <= 2*wh-w-h);
1747     if (pos < 2*wh-w-h)
1748         return "Too little data in edge list";
1749
1750     /*
1751      * Now go through again and allocate region numbers.
1752      */
1753     pos = 0;
1754     for (i = 0; i < wh; i++)
1755         map[i] = -1;
1756     for (i = 0; i < wh; i++) {
1757         k = dsf_canonify(map+wh, i);
1758         if (map[k] < 0)
1759             map[k] = pos++;
1760         map[i] = map[k];
1761     }
1762     if (pos != n)
1763         return "Edge list defines the wrong number of regions";
1764
1765     *desc = p;
1766
1767     return NULL;
1768 }
1769
1770 static char *validate_desc(game_params *params, char *desc)
1771 {
1772     int w = params->w, h = params->h, wh = w*h, n = params->n;
1773     int area;
1774     int *map;
1775     char *ret;
1776
1777     map = snewn(2*wh, int);
1778     ret = parse_edge_list(params, &desc, map);
1779     if (ret)
1780         return ret;
1781     sfree(map);
1782
1783     if (*desc != ',')
1784         return "Expected comma before clue list";
1785     desc++;                            /* eat comma */
1786
1787     area = 0;
1788     while (*desc) {
1789         if (*desc >= '0' && *desc < '0'+FOUR)
1790             area++;
1791         else if (*desc >= 'a' && *desc <= 'z')
1792             area += *desc - 'a' + 1;
1793         else
1794             return "Unexpected character in clue list";
1795         desc++;
1796     }
1797     if (area < n)
1798         return "Too little data in clue list";
1799     else if (area > n)
1800         return "Too much data in clue list";
1801
1802     return NULL;
1803 }
1804
1805 static game_state *new_game(midend *me, game_params *params, char *desc)
1806 {
1807     int w = params->w, h = params->h, wh = w*h, n = params->n;
1808     int i, pos;
1809     char *p;
1810     game_state *state = snew(game_state);
1811
1812     state->p = *params;
1813     state->colouring = snewn(n, int);
1814     for (i = 0; i < n; i++)
1815         state->colouring[i] = -1;
1816     state->pencil = snewn(n, int);
1817     for (i = 0; i < n; i++)
1818         state->pencil[i] = 0;
1819
1820     state->completed = state->cheated = FALSE;
1821
1822     state->map = snew(struct map);
1823     state->map->refcount = 1;
1824     state->map->map = snewn(wh*4, int);
1825     state->map->graph = snewn(n*n, int);
1826     state->map->n = n;
1827     state->map->immutable = snewn(n, int);
1828     for (i = 0; i < n; i++)
1829         state->map->immutable[i] = FALSE;
1830
1831     p = desc;
1832
1833     {
1834         char *ret;
1835         ret = parse_edge_list(params, &p, state->map->map);
1836         assert(!ret);
1837     }
1838
1839     /*
1840      * Set up the other three quadrants in `map'.
1841      */
1842     for (i = wh; i < 4*wh; i++)
1843         state->map->map[i] = state->map->map[i % wh];
1844
1845     assert(*p == ',');
1846     p++;
1847
1848     /*
1849      * Now process the clue list.
1850      */
1851     pos = 0;
1852     while (*p) {
1853         if (*p >= '0' && *p < '0'+FOUR) {
1854             state->colouring[pos] = *p - '0';
1855             state->map->immutable[pos] = TRUE;
1856             pos++;
1857         } else {
1858             assert(*p >= 'a' && *p <= 'z');
1859             pos += *p - 'a' + 1;
1860         }
1861         p++;
1862     }
1863     assert(pos == n);
1864
1865     state->map->ngraph = gengraph(w, h, n, state->map->map, state->map->graph);
1866
1867     /*
1868      * Attempt to smooth out some of the more jagged region
1869      * outlines by the judicious use of diagonally divided squares.
1870      */
1871     {
1872         random_state *rs = random_init(desc, strlen(desc));
1873         int *squares = snewn(wh, int);
1874         int done_something;
1875
1876         for (i = 0; i < wh; i++)
1877             squares[i] = i;
1878         shuffle(squares, wh, sizeof(*squares), rs);
1879
1880         do {
1881             done_something = FALSE;
1882             for (i = 0; i < wh; i++) {
1883                 int y = squares[i] / w, x = squares[i] % w;
1884                 int c = state->map->map[y*w+x];
1885                 int tc, bc, lc, rc;
1886
1887                 if (x == 0 || x == w-1 || y == 0 || y == h-1)
1888                     continue;
1889
1890                 if (state->map->map[TE * wh + y*w+x] !=
1891                     state->map->map[BE * wh + y*w+x])
1892                     continue;
1893
1894                 tc = state->map->map[BE * wh + (y-1)*w+x];
1895                 bc = state->map->map[TE * wh + (y+1)*w+x];
1896                 lc = state->map->map[RE * wh + y*w+(x-1)];
1897                 rc = state->map->map[LE * wh + y*w+(x+1)];
1898
1899                 /*
1900                  * If this square is adjacent on two sides to one
1901                  * region and on the other two sides to the other
1902                  * region, and is itself one of the two regions, we can
1903                  * adjust it so that it's a diagonal.
1904                  */
1905                 if (tc != bc && (tc == c || bc == c)) {
1906                     if ((lc == tc && rc == bc) ||
1907                         (lc == bc && rc == tc)) {
1908                         state->map->map[TE * wh + y*w+x] = tc;
1909                         state->map->map[BE * wh + y*w+x] = bc;
1910                         state->map->map[LE * wh + y*w+x] = lc;
1911                         state->map->map[RE * wh + y*w+x] = rc;
1912                         done_something = TRUE;
1913                     }
1914                 }
1915             }
1916         } while (done_something);
1917         sfree(squares);
1918         random_free(rs);
1919     }
1920
1921     /*
1922      * Analyse the map to find a canonical line segment
1923      * corresponding to each edge, and a canonical point
1924      * corresponding to each region. The former are where we'll
1925      * eventually put error markers; the latter are where we'll put
1926      * per-region flags such as numbers (when in diagnostic mode).
1927      */
1928     {
1929         int *bestx, *besty, *an, pass;
1930         float *ax, *ay, *best;
1931
1932         ax = snewn(state->map->ngraph + n, float);
1933         ay = snewn(state->map->ngraph + n, float);
1934         an = snewn(state->map->ngraph + n, int);
1935         bestx = snewn(state->map->ngraph + n, int);
1936         besty = snewn(state->map->ngraph + n, int);
1937         best = snewn(state->map->ngraph + n, float);
1938
1939         for (i = 0; i < state->map->ngraph + n; i++) {
1940             bestx[i] = besty[i] = -1;
1941             best[i] = 2*(w+h)+1;
1942             ax[i] = ay[i] = 0.0F;
1943             an[i] = 0;
1944         }
1945
1946         /*
1947          * We make two passes over the map, finding all the line
1948          * segments separating regions and all the suitable points
1949          * within regions. In the first pass, we compute the
1950          * _average_ x and y coordinate of all the points in a
1951          * given class; in the second pass, for each such average
1952          * point, we find the candidate closest to it and call that
1953          * canonical.
1954          * 
1955          * Line segments are considered to have coordinates in
1956          * their centre. Thus, at least one coordinate for any line
1957          * segment is always something-and-a-half; so we store our
1958          * coordinates as twice their normal value.
1959          */
1960         for (pass = 0; pass < 2; pass++) {
1961             int x, y;
1962
1963             for (y = 0; y < h; y++)
1964                 for (x = 0; x < w; x++) {
1965                     int ex[4], ey[4], ea[4], eb[4], en = 0;
1966
1967                     /*
1968                      * Look for an edge to the right of this
1969                      * square, an edge below it, and an edge in the
1970                      * middle of it. Also look to see if the point
1971                      * at the bottom right of this square is on an
1972                      * edge (and isn't a place where more than two
1973                      * regions meet).
1974                      */
1975                     if (x+1 < w) {
1976                         /* right edge */
1977                         ea[en] = state->map->map[RE * wh + y*w+x];
1978                         eb[en] = state->map->map[LE * wh + y*w+(x+1)];
1979                         ex[en] = (x+1)*2;
1980                         ey[en] = y*2+1;
1981                         en++;
1982                     }
1983                     if (y+1 < h) {
1984                         /* bottom edge */
1985                         ea[en] = state->map->map[BE * wh + y*w+x];
1986                         eb[en] = state->map->map[TE * wh + (y+1)*w+x];
1987                         ex[en] = x*2+1;
1988                         ey[en] = (y+1)*2;
1989                         en++;
1990                     }
1991                     /* diagonal edge */
1992                     ea[en] = state->map->map[TE * wh + y*w+x];
1993                     eb[en] = state->map->map[BE * wh + y*w+x];
1994                     ex[en] = x*2+1;
1995                     ey[en] = y*2+1;
1996                     en++;
1997
1998                     if (x+1 < w && y+1 < h) {
1999                         /* bottom right corner */
2000                         int oct[8], othercol, nchanges;
2001                         oct[0] = state->map->map[RE * wh + y*w+x];
2002                         oct[1] = state->map->map[LE * wh + y*w+(x+1)];
2003                         oct[2] = state->map->map[BE * wh + y*w+(x+1)];
2004                         oct[3] = state->map->map[TE * wh + (y+1)*w+(x+1)];
2005                         oct[4] = state->map->map[LE * wh + (y+1)*w+(x+1)];
2006                         oct[5] = state->map->map[RE * wh + (y+1)*w+x];
2007                         oct[6] = state->map->map[TE * wh + (y+1)*w+x];
2008                         oct[7] = state->map->map[BE * wh + y*w+x];
2009
2010                         othercol = -1;
2011                         nchanges = 0;
2012                         for (i = 0; i < 8; i++) {
2013                             if (oct[i] != oct[0]) {
2014                                 if (othercol < 0)
2015                                     othercol = oct[i];
2016                                 else if (othercol != oct[i])
2017                                     break;   /* three colours at this point */
2018                             }
2019                             if (oct[i] != oct[(i+1) & 7])
2020                                 nchanges++;
2021                         }
2022
2023                         /*
2024                          * Now if there are exactly two regions at
2025                          * this point (not one, and not three or
2026                          * more), and only two changes around the
2027                          * loop, then this is a valid place to put
2028                          * an error marker.
2029                          */
2030                         if (i == 8 && othercol >= 0 && nchanges == 2) {
2031                             ea[en] = oct[0];
2032                             eb[en] = othercol;
2033                             ex[en] = (x+1)*2;
2034                             ey[en] = (y+1)*2;
2035                             en++;
2036                         }
2037
2038                         /*
2039                          * If there's exactly _one_ region at this
2040                          * point, on the other hand, it's a valid
2041                          * place to put a region centre.
2042                          */
2043                         if (othercol < 0) {
2044                             ea[en] = eb[en] = oct[0];
2045                             ex[en] = (x+1)*2;
2046                             ey[en] = (y+1)*2;
2047                             en++;
2048                         }
2049                     }
2050
2051                     /*
2052                      * Now process the points we've found, one by
2053                      * one.
2054                      */
2055                     for (i = 0; i < en; i++) {
2056                         int emin = min(ea[i], eb[i]);
2057                         int emax = max(ea[i], eb[i]);
2058                         int gindex;
2059
2060                         if (emin != emax) {
2061                             /* Graph edge */
2062                             gindex =
2063                                 graph_edge_index(state->map->graph, n,
2064                                                  state->map->ngraph, emin,
2065                                                  emax);
2066                         } else {
2067                             /* Region number */
2068                             gindex = state->map->ngraph + emin;
2069                         }
2070
2071                         assert(gindex >= 0);
2072
2073                         if (pass == 0) {
2074                             /*
2075                              * In pass 0, accumulate the values
2076                              * we'll use to compute the average
2077                              * positions.
2078                              */
2079                             ax[gindex] += ex[i];
2080                             ay[gindex] += ey[i];
2081                             an[gindex] += 1.0F;
2082                         } else {
2083                             /*
2084                              * In pass 1, work out whether this
2085                              * point is closer to the average than
2086                              * the last one we've seen.
2087                              */
2088                             float dx, dy, d;
2089
2090                             assert(an[gindex] > 0);
2091                             dx = ex[i] - ax[gindex];
2092                             dy = ey[i] - ay[gindex];
2093                             d = sqrt(dx*dx + dy*dy);
2094                             if (d < best[gindex]) {
2095                                 best[gindex] = d;
2096                                 bestx[gindex] = ex[i];
2097                                 besty[gindex] = ey[i];
2098                             }
2099                         }
2100                     }
2101                 }
2102
2103             if (pass == 0) {
2104                 for (i = 0; i < state->map->ngraph + n; i++)
2105                     if (an[i] > 0) {
2106                         ax[i] /= an[i];
2107                         ay[i] /= an[i];
2108                     }
2109             }
2110         }
2111
2112         state->map->edgex = snewn(state->map->ngraph, int);
2113         state->map->edgey = snewn(state->map->ngraph, int);
2114         memcpy(state->map->edgex, bestx, state->map->ngraph * sizeof(int));
2115         memcpy(state->map->edgey, besty, state->map->ngraph * sizeof(int));
2116
2117         state->map->regionx = snewn(n, int);
2118         state->map->regiony = snewn(n, int);
2119         memcpy(state->map->regionx, bestx + state->map->ngraph, n*sizeof(int));
2120         memcpy(state->map->regiony, besty + state->map->ngraph, n*sizeof(int));
2121
2122         for (i = 0; i < state->map->ngraph; i++)
2123             if (state->map->edgex[i] < 0) {
2124                 /* Find the other representation of this edge. */
2125                 int e = state->map->graph[i];
2126                 int iprime = graph_edge_index(state->map->graph, n,
2127                                               state->map->ngraph, e%n, e/n);
2128                 assert(state->map->edgex[iprime] >= 0);
2129                 state->map->edgex[i] = state->map->edgex[iprime];
2130                 state->map->edgey[i] = state->map->edgey[iprime];
2131             }
2132
2133         sfree(ax);
2134         sfree(ay);
2135         sfree(an);
2136         sfree(best);
2137         sfree(bestx);
2138         sfree(besty);
2139     }
2140
2141     return state;
2142 }
2143
2144 static game_state *dup_game(game_state *state)
2145 {
2146     game_state *ret = snew(game_state);
2147
2148     ret->p = state->p;
2149     ret->colouring = snewn(state->p.n, int);
2150     memcpy(ret->colouring, state->colouring, state->p.n * sizeof(int));
2151     ret->pencil = snewn(state->p.n, int);
2152     memcpy(ret->pencil, state->pencil, state->p.n * sizeof(int));
2153     ret->map = state->map;
2154     ret->map->refcount++;
2155     ret->completed = state->completed;
2156     ret->cheated = state->cheated;
2157
2158     return ret;
2159 }
2160
2161 static void free_game(game_state *state)
2162 {
2163     if (--state->map->refcount <= 0) {
2164         sfree(state->map->map);
2165         sfree(state->map->graph);
2166         sfree(state->map->immutable);
2167         sfree(state->map->edgex);
2168         sfree(state->map->edgey);
2169         sfree(state->map->regionx);
2170         sfree(state->map->regiony);
2171         sfree(state->map);
2172     }
2173     sfree(state->colouring);
2174     sfree(state);
2175 }
2176
2177 static char *solve_game(game_state *state, game_state *currstate,
2178                         char *aux, char **error)
2179 {
2180     if (!aux) {
2181         /*
2182          * Use the solver.
2183          */
2184         int *colouring;
2185         struct solver_scratch *sc;
2186         int sret;
2187         int i;
2188         char *ret, buf[80];
2189         int retlen, retsize;
2190
2191         colouring = snewn(state->map->n, int);
2192         memcpy(colouring, state->colouring, state->map->n * sizeof(int));
2193
2194         sc = new_scratch(state->map->graph, state->map->n, state->map->ngraph);
2195         sret = map_solver(sc, state->map->graph, state->map->n,
2196                          state->map->ngraph, colouring, DIFFCOUNT-1);
2197         free_scratch(sc);
2198
2199         if (sret != 1) {
2200             sfree(colouring);
2201             if (sret == 0)
2202                 *error = "Puzzle is inconsistent";
2203             else
2204                 *error = "Unable to find a unique solution for this puzzle";
2205             return NULL;
2206         }
2207
2208         retsize = 64;
2209         ret = snewn(retsize, char);
2210         strcpy(ret, "S");
2211         retlen = 1;
2212
2213         for (i = 0; i < state->map->n; i++) {
2214             int len;
2215
2216             assert(colouring[i] >= 0);
2217             if (colouring[i] == currstate->colouring[i])
2218                 continue;
2219             assert(!state->map->immutable[i]);
2220
2221             len = sprintf(buf, ";%d:%d", colouring[i], i);
2222             if (retlen + len >= retsize) {
2223                 retsize = retlen + len + 256;
2224                 ret = sresize(ret, retsize, char);
2225             }
2226             strcpy(ret + retlen, buf);
2227             retlen += len;
2228         }
2229
2230         sfree(colouring);
2231
2232         return ret;
2233     }
2234     return dupstr(aux);
2235 }
2236
2237 static char *game_text_format(game_state *state)
2238 {
2239     return NULL;
2240 }
2241
2242 struct game_ui {
2243     int drag_colour;                   /* -1 means no drag active */
2244     int dragx, dragy;
2245     int show_numbers;
2246 };
2247
2248 static game_ui *new_ui(game_state *state)
2249 {
2250     game_ui *ui = snew(game_ui);
2251     ui->dragx = ui->dragy = -1;
2252     ui->drag_colour = -2;
2253     ui->show_numbers = FALSE;
2254     return ui;
2255 }
2256
2257 static void free_ui(game_ui *ui)
2258 {
2259     sfree(ui);
2260 }
2261
2262 static char *encode_ui(game_ui *ui)
2263 {
2264     return NULL;
2265 }
2266
2267 static void decode_ui(game_ui *ui, char *encoding)
2268 {
2269 }
2270
2271 static void game_changed_state(game_ui *ui, game_state *oldstate,
2272                                game_state *newstate)
2273 {
2274 }
2275
2276 struct game_drawstate {
2277     int tilesize;
2278     unsigned long *drawn, *todraw;
2279     int started;
2280     int dragx, dragy, drag_visible;
2281     blitter *bl;
2282 };
2283
2284 /* Flags in `drawn'. */
2285 #define ERR_BASE      0x00800000L
2286 #define ERR_MASK      0xFF800000L
2287 #define PENCIL_T_BASE 0x00080000L
2288 #define PENCIL_T_MASK 0x00780000L
2289 #define PENCIL_B_BASE 0x00008000L
2290 #define PENCIL_B_MASK 0x00078000L
2291 #define PENCIL_MASK   0x007F8000L
2292 #define SHOW_NUMBERS  0x00004000L
2293
2294 #define TILESIZE (ds->tilesize)
2295 #define BORDER (TILESIZE)
2296 #define COORD(x)  ( (x) * TILESIZE + BORDER )
2297 #define FROMCOORD(x)  ( ((x) - BORDER + TILESIZE) / TILESIZE - 1 )
2298
2299 static int region_from_coords(game_state *state, game_drawstate *ds,
2300                               int x, int y)
2301 {
2302     int w = state->p.w, h = state->p.h, wh = w*h /*, n = state->p.n */;
2303     int tx = FROMCOORD(x), ty = FROMCOORD(y);
2304     int dx = x - COORD(tx), dy = y - COORD(ty);
2305     int quadrant;
2306
2307     if (tx < 0 || tx >= w || ty < 0 || ty >= h)
2308         return -1;                     /* border */
2309
2310     quadrant = 2 * (dx > dy) + (TILESIZE - dx > dy);
2311     quadrant = (quadrant == 0 ? BE :
2312                 quadrant == 1 ? LE :
2313                 quadrant == 2 ? RE : TE);
2314
2315     return state->map->map[quadrant * wh + ty*w+tx];
2316 }
2317
2318 static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
2319                             int x, int y, int button)
2320 {
2321     char buf[80];
2322
2323     /*
2324      * Enable or disable numeric labels on regions.
2325      */
2326     if (button == 'l' || button == 'L') {
2327         ui->show_numbers = !ui->show_numbers;
2328         return "";
2329     }
2330
2331     if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
2332         int r = region_from_coords(state, ds, x, y);
2333
2334         if (r >= 0)
2335             ui->drag_colour = state->colouring[r];
2336         else
2337             ui->drag_colour = -1;
2338         ui->dragx = x;
2339         ui->dragy = y;
2340         return "";
2341     }
2342
2343     if ((button == LEFT_DRAG || button == RIGHT_DRAG) &&
2344         ui->drag_colour > -2) {
2345         ui->dragx = x;
2346         ui->dragy = y;
2347         return "";
2348     }
2349
2350     if ((button == LEFT_RELEASE || button == RIGHT_RELEASE) &&
2351         ui->drag_colour > -2) {
2352         int r = region_from_coords(state, ds, x, y);
2353         int c = ui->drag_colour;
2354
2355         /*
2356          * Cancel the drag, whatever happens.
2357          */
2358         ui->drag_colour = -2;
2359         ui->dragx = ui->dragy = -1;
2360
2361         if (r < 0)
2362             return "";                 /* drag into border; do nothing else */
2363
2364         if (state->map->immutable[r])
2365             return "";                 /* can't change this region */
2366
2367         if (state->colouring[r] == c)
2368             return "";                 /* don't _need_ to change this region */
2369
2370         if (button == RIGHT_RELEASE && state->colouring[r] >= 0)
2371             return "";                 /* can't pencil on a coloured region */
2372
2373         sprintf(buf, "%s%c:%d", (button == RIGHT_RELEASE ? "p" : ""),
2374                 (int)(c < 0 ? 'C' : '0' + c), r);
2375         return dupstr(buf);
2376     }
2377
2378     return NULL;
2379 }
2380
2381 static game_state *execute_move(game_state *state, char *move)
2382 {
2383     int n = state->p.n;
2384     game_state *ret = dup_game(state);
2385     int c, k, adv, i;
2386
2387     while (*move) {
2388         int pencil = FALSE;
2389
2390         c = *move;
2391         if (c == 'p') {
2392             pencil = TRUE;
2393             c = *++move;
2394         }
2395         if ((c == 'C' || (c >= '0' && c < '0'+FOUR)) &&
2396             sscanf(move+1, ":%d%n", &k, &adv) == 1 &&
2397             k >= 0 && k < state->p.n) {
2398             move += 1 + adv;
2399             if (pencil) {
2400                 if (ret->colouring[k] >= 0) {
2401                     free_game(ret);
2402                     return NULL;
2403                 }
2404                 if (c == 'C')
2405                     ret->pencil[k] = 0;
2406                 else
2407                     ret->pencil[k] ^= 1 << (c - '0');
2408             } else {
2409                 ret->colouring[k] = (c == 'C' ? -1 : c - '0');
2410                 ret->pencil[k] = 0;
2411             }
2412         } else if (*move == 'S') {
2413             move++;
2414             ret->cheated = TRUE;
2415         } else {
2416             free_game(ret);
2417             return NULL;
2418         }
2419
2420         if (*move && *move != ';') {
2421             free_game(ret);
2422             return NULL;
2423         }
2424         if (*move)
2425             move++;
2426     }
2427
2428     /*
2429      * Check for completion.
2430      */
2431     if (!ret->completed) {
2432         int ok = TRUE;
2433
2434         for (i = 0; i < n; i++)
2435             if (ret->colouring[i] < 0) {
2436                 ok = FALSE;
2437                 break;
2438             }
2439
2440         if (ok) {
2441             for (i = 0; i < ret->map->ngraph; i++) {
2442                 int j = ret->map->graph[i] / n;
2443                 int k = ret->map->graph[i] % n;
2444                 if (ret->colouring[j] == ret->colouring[k]) {
2445                     ok = FALSE;
2446                     break;
2447                 }
2448             }
2449         }
2450
2451         if (ok)
2452             ret->completed = TRUE;
2453     }
2454
2455     return ret;
2456 }
2457
2458 /* ----------------------------------------------------------------------
2459  * Drawing routines.
2460  */
2461
2462 static void game_compute_size(game_params *params, int tilesize,
2463                               int *x, int *y)
2464 {
2465     /* Ick: fake up `ds->tilesize' for macro expansion purposes */
2466     struct { int tilesize; } ads, *ds = &ads;
2467     ads.tilesize = tilesize;
2468
2469     *x = params->w * TILESIZE + 2 * BORDER + 1;
2470     *y = params->h * TILESIZE + 2 * BORDER + 1;
2471 }
2472
2473 static void game_set_size(drawing *dr, game_drawstate *ds,
2474                           game_params *params, int tilesize)
2475 {
2476     ds->tilesize = tilesize;
2477
2478     if (ds->bl)
2479         blitter_free(dr, ds->bl);
2480     ds->bl = blitter_new(dr, TILESIZE+3, TILESIZE+3);
2481 }
2482
2483 const float map_colours[FOUR][3] = {
2484     {0.7F, 0.5F, 0.4F},
2485     {0.8F, 0.7F, 0.4F},
2486     {0.5F, 0.6F, 0.4F},
2487     {0.55F, 0.45F, 0.35F},
2488 };
2489 const int map_hatching[FOUR] = {
2490     HATCH_VERT, HATCH_SLASH, HATCH_HORIZ, HATCH_BACKSLASH
2491 };
2492
2493 static float *game_colours(frontend *fe, game_state *state, int *ncolours)
2494 {
2495     float *ret = snewn(3 * NCOLOURS, float);
2496
2497     frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
2498
2499     ret[COL_GRID * 3 + 0] = 0.0F;
2500     ret[COL_GRID * 3 + 1] = 0.0F;
2501     ret[COL_GRID * 3 + 2] = 0.0F;
2502
2503     memcpy(ret + COL_0 * 3, map_colours[0], 3 * sizeof(float));
2504     memcpy(ret + COL_1 * 3, map_colours[1], 3 * sizeof(float));
2505     memcpy(ret + COL_2 * 3, map_colours[2], 3 * sizeof(float));
2506     memcpy(ret + COL_3 * 3, map_colours[3], 3 * sizeof(float));
2507
2508     ret[COL_ERROR * 3 + 0] = 1.0F;
2509     ret[COL_ERROR * 3 + 1] = 0.0F;
2510     ret[COL_ERROR * 3 + 2] = 0.0F;
2511
2512     ret[COL_ERRTEXT * 3 + 0] = 1.0F;
2513     ret[COL_ERRTEXT * 3 + 1] = 1.0F;
2514     ret[COL_ERRTEXT * 3 + 2] = 1.0F;
2515
2516     *ncolours = NCOLOURS;
2517     return ret;
2518 }
2519
2520 static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
2521 {
2522     struct game_drawstate *ds = snew(struct game_drawstate);
2523     int i;
2524
2525     ds->tilesize = 0;
2526     ds->drawn = snewn(state->p.w * state->p.h, unsigned long);
2527     for (i = 0; i < state->p.w * state->p.h; i++)
2528         ds->drawn[i] = 0xFFFFL;
2529     ds->todraw = snewn(state->p.w * state->p.h, unsigned long);
2530     ds->started = FALSE;
2531     ds->bl = NULL;
2532     ds->drag_visible = FALSE;
2533     ds->dragx = ds->dragy = -1;
2534
2535     return ds;
2536 }
2537
2538 static void game_free_drawstate(drawing *dr, game_drawstate *ds)
2539 {
2540     sfree(ds->drawn);
2541     sfree(ds->todraw);
2542     if (ds->bl)
2543         blitter_free(dr, ds->bl);
2544     sfree(ds);
2545 }
2546
2547 static void draw_error(drawing *dr, game_drawstate *ds, int x, int y)
2548 {
2549     int coords[8];
2550     int yext, xext;
2551
2552     /*
2553      * Draw a diamond.
2554      */
2555     coords[0] = x - TILESIZE*2/5;
2556     coords[1] = y;
2557     coords[2] = x;
2558     coords[3] = y - TILESIZE*2/5;
2559     coords[4] = x + TILESIZE*2/5;
2560     coords[5] = y;
2561     coords[6] = x;
2562     coords[7] = y + TILESIZE*2/5;
2563     draw_polygon(dr, coords, 4, COL_ERROR, COL_GRID);
2564
2565     /*
2566      * Draw an exclamation mark in the diamond. This turns out to
2567      * look unpleasantly off-centre if done via draw_text, so I do
2568      * it by hand on the basis that exclamation marks aren't that
2569      * difficult to draw...
2570      */
2571     xext = TILESIZE/16;
2572     yext = TILESIZE*2/5 - (xext*2+2);
2573     draw_rect(dr, x-xext, y-yext, xext*2+1, yext*2+1 - (xext*3),
2574               COL_ERRTEXT);
2575     draw_rect(dr, x-xext, y+yext-xext*2+1, xext*2+1, xext*2, COL_ERRTEXT);
2576 }
2577
2578 static void draw_square(drawing *dr, game_drawstate *ds,
2579                         game_params *params, struct map *map,
2580                         int x, int y, int v)
2581 {
2582     int w = params->w, h = params->h, wh = w*h;
2583     int tv, bv, xo, yo, errs, pencil, i, j, oldj;
2584     int show_numbers;
2585
2586     errs = v & ERR_MASK;
2587     v &= ~ERR_MASK;
2588     pencil = v & PENCIL_MASK;
2589     v &= ~PENCIL_MASK;
2590     show_numbers = v & SHOW_NUMBERS;
2591     v &= ~SHOW_NUMBERS;
2592     tv = v / FIVE;
2593     bv = v % FIVE;
2594
2595     clip(dr, COORD(x), COORD(y), TILESIZE, TILESIZE);
2596
2597     /*
2598      * Draw the region colour.
2599      */
2600     draw_rect(dr, COORD(x), COORD(y), TILESIZE, TILESIZE,
2601               (tv == FOUR ? COL_BACKGROUND : COL_0 + tv));
2602     /*
2603      * Draw the second region colour, if this is a diagonally
2604      * divided square.
2605      */
2606     if (map->map[TE * wh + y*w+x] != map->map[BE * wh + y*w+x]) {
2607         int coords[6];
2608         coords[0] = COORD(x)-1;
2609         coords[1] = COORD(y+1)+1;
2610         if (map->map[LE * wh + y*w+x] == map->map[TE * wh + y*w+x])
2611             coords[2] = COORD(x+1)+1;
2612         else
2613             coords[2] = COORD(x)-1;
2614         coords[3] = COORD(y)-1;
2615         coords[4] = COORD(x+1)+1;
2616         coords[5] = COORD(y+1)+1;
2617         draw_polygon(dr, coords, 3,
2618                      (bv == FOUR ? COL_BACKGROUND : COL_0 + bv), COL_GRID);
2619     }
2620
2621     /*
2622      * Draw `pencil marks'. Currently we arrange these in a square
2623      * formation, which means we may be in trouble if the value of
2624      * FOUR changes later...
2625      */
2626     assert(FOUR == 4);
2627     for (yo = 0; yo < 4; yo++)
2628         for (xo = 0; xo < 4; xo++) {
2629             int te = map->map[TE * wh + y*w+x];
2630             int e, ee, c;
2631
2632             e = (yo < xo && yo < 3-xo ? TE :
2633                  yo > xo && yo > 3-xo ? BE :
2634                  xo < 2 ? LE : RE);
2635             ee = map->map[e * wh + y*w+x];
2636
2637             if (xo != (yo * 2 + 1) % 5)
2638                 continue;
2639             c = yo;
2640
2641             if (!(pencil & ((ee == te ? PENCIL_T_BASE : PENCIL_B_BASE) << c)))
2642                 continue;
2643
2644             if (yo == xo &&
2645                 (map->map[TE * wh + y*w+x] != map->map[LE * wh + y*w+x]))
2646                 continue;              /* avoid TL-BR diagonal line */
2647             if (yo == 3-xo &&
2648                 (map->map[TE * wh + y*w+x] != map->map[RE * wh + y*w+x]))
2649                 continue;              /* avoid BL-TR diagonal line */
2650
2651             draw_circle(dr, COORD(x) + (xo+1)*TILESIZE/5,
2652                         COORD(y) + (yo+1)*TILESIZE/5,
2653                         TILESIZE/8, COL_0 + c, COL_0 + c);
2654         }
2655
2656     /*
2657      * Draw the grid lines, if required.
2658      */
2659     if (x <= 0 || map->map[RE*wh+y*w+(x-1)] != map->map[LE*wh+y*w+x])
2660         draw_rect(dr, COORD(x), COORD(y), 1, TILESIZE, COL_GRID);
2661     if (y <= 0 || map->map[BE*wh+(y-1)*w+x] != map->map[TE*wh+y*w+x])
2662         draw_rect(dr, COORD(x), COORD(y), TILESIZE, 1, COL_GRID);
2663     if (x <= 0 || y <= 0 ||
2664         map->map[RE*wh+(y-1)*w+(x-1)] != map->map[TE*wh+y*w+x] ||
2665         map->map[BE*wh+(y-1)*w+(x-1)] != map->map[LE*wh+y*w+x])
2666         draw_rect(dr, COORD(x), COORD(y), 1, 1, COL_GRID);
2667
2668     /*
2669      * Draw error markers.
2670      */
2671     for (yo = 0; yo < 3; yo++)
2672         for (xo = 0; xo < 3; xo++)
2673             if (errs & (ERR_BASE << (yo*3+xo)))
2674                 draw_error(dr, ds,
2675                            (COORD(x)*2+TILESIZE*xo)/2,
2676                            (COORD(y)*2+TILESIZE*yo)/2);
2677
2678     /*
2679      * Draw region numbers, if desired.
2680      */
2681     if (show_numbers) {
2682         oldj = -1;
2683         for (i = 0; i < 2; i++) {
2684             j = map->map[(i?BE:TE)*wh+y*w+x];
2685             if (oldj == j)
2686                 continue;
2687             oldj = j;
2688
2689             xo = map->regionx[j] - 2*x;
2690             yo = map->regiony[j] - 2*y;
2691             if (xo >= 0 && xo <= 2 && yo >= 0 && yo <= 2) {
2692                 char buf[80];
2693                 sprintf(buf, "%d", j);
2694                 draw_text(dr, (COORD(x)*2+TILESIZE*xo)/2,
2695                           (COORD(y)*2+TILESIZE*yo)/2,
2696                           FONT_VARIABLE, 3*TILESIZE/5,
2697                           ALIGN_HCENTRE|ALIGN_VCENTRE,
2698                           COL_GRID, buf);
2699             }
2700         }
2701     }
2702
2703     unclip(dr);
2704
2705     draw_update(dr, COORD(x), COORD(y), TILESIZE, TILESIZE);
2706 }
2707
2708 static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
2709                         game_state *state, int dir, game_ui *ui,
2710                         float animtime, float flashtime)
2711 {
2712     int w = state->p.w, h = state->p.h, wh = w*h, n = state->p.n;
2713     int x, y, i;
2714     int flash;
2715
2716     if (ds->drag_visible) {
2717         blitter_load(dr, ds->bl, ds->dragx, ds->dragy);
2718         draw_update(dr, ds->dragx, ds->dragy, TILESIZE + 3, TILESIZE + 3);
2719         ds->drag_visible = FALSE;
2720     }
2721
2722     /*
2723      * The initial contents of the window are not guaranteed and
2724      * can vary with front ends. To be on the safe side, all games
2725      * should start by drawing a big background-colour rectangle
2726      * covering the whole window.
2727      */
2728     if (!ds->started) {
2729         int ww, wh;
2730
2731         game_compute_size(&state->p, TILESIZE, &ww, &wh);
2732         draw_rect(dr, 0, 0, ww, wh, COL_BACKGROUND);
2733         draw_rect(dr, COORD(0), COORD(0), w*TILESIZE+1, h*TILESIZE+1,
2734                   COL_GRID);
2735
2736         draw_update(dr, 0, 0, ww, wh);
2737         ds->started = TRUE;
2738     }
2739
2740     if (flashtime) {
2741         if (flash_type == 1)
2742             flash = (int)(flashtime * FOUR / flash_length);
2743         else
2744             flash = 1 + (int)(flashtime * THREE / flash_length);
2745     } else
2746         flash = -1;
2747
2748     /*
2749      * Set up the `todraw' array.
2750      */
2751     for (y = 0; y < h; y++)
2752         for (x = 0; x < w; x++) {
2753             int tv = state->colouring[state->map->map[TE * wh + y*w+x]];
2754             int bv = state->colouring[state->map->map[BE * wh + y*w+x]];
2755             int v;
2756
2757             if (tv < 0)
2758                 tv = FOUR;
2759             if (bv < 0)
2760                 bv = FOUR;
2761
2762             if (flash >= 0) {
2763                 if (flash_type == 1) {
2764                     if (tv == flash)
2765                         tv = FOUR;
2766                     if (bv == flash)
2767                         bv = FOUR;
2768                 } else if (flash_type == 2) {
2769                     if (flash % 2)
2770                         tv = bv = FOUR;
2771                 } else {
2772                     if (tv != FOUR)
2773                         tv = (tv + flash) % FOUR;
2774                     if (bv != FOUR)
2775                         bv = (bv + flash) % FOUR;
2776                 }
2777             }
2778
2779             v = tv * FIVE + bv;
2780
2781             /*
2782              * Add pencil marks.
2783              */
2784             for (i = 0; i < FOUR; i++) {
2785                 if (state->colouring[state->map->map[TE * wh + y*w+x]] < 0 &&
2786                     (state->pencil[state->map->map[TE * wh + y*w+x]] & (1<<i)))
2787                     v |= PENCIL_T_BASE << i;
2788                 if (state->colouring[state->map->map[BE * wh + y*w+x]] < 0 &&
2789                     (state->pencil[state->map->map[BE * wh + y*w+x]] & (1<<i)))
2790                     v |= PENCIL_B_BASE << i;
2791             }
2792
2793             if (ui->show_numbers)
2794                 v |= SHOW_NUMBERS;
2795
2796             ds->todraw[y*w+x] = v;
2797         }
2798
2799     /*
2800      * Add error markers to the `todraw' array.
2801      */
2802     for (i = 0; i < state->map->ngraph; i++) {
2803         int v1 = state->map->graph[i] / n;
2804         int v2 = state->map->graph[i] % n;
2805         int xo, yo;
2806
2807         if (state->colouring[v1] < 0 || state->colouring[v2] < 0)
2808             continue;
2809         if (state->colouring[v1] != state->colouring[v2])
2810             continue;
2811
2812         x = state->map->edgex[i];
2813         y = state->map->edgey[i];
2814
2815         xo = x % 2; x /= 2;
2816         yo = y % 2; y /= 2;
2817
2818         ds->todraw[y*w+x] |= ERR_BASE << (yo*3+xo);
2819         if (xo == 0) {
2820             assert(x > 0);
2821             ds->todraw[y*w+(x-1)] |= ERR_BASE << (yo*3+2);
2822         }
2823         if (yo == 0) {
2824             assert(y > 0);
2825             ds->todraw[(y-1)*w+x] |= ERR_BASE << (2*3+xo);
2826         }
2827         if (xo == 0 && yo == 0) {
2828             assert(x > 0 && y > 0);
2829             ds->todraw[(y-1)*w+(x-1)] |= ERR_BASE << (2*3+2);
2830         }
2831     }
2832
2833     /*
2834      * Now actually draw everything.
2835      */
2836     for (y = 0; y < h; y++)
2837         for (x = 0; x < w; x++) {
2838             int v = ds->todraw[y*w+x];
2839             if (ds->drawn[y*w+x] != v) {
2840                 draw_square(dr, ds, &state->p, state->map, x, y, v);
2841                 ds->drawn[y*w+x] = v;
2842             }
2843         }
2844
2845     /*
2846      * Draw the dragged colour blob if any.
2847      */
2848     if (ui->drag_colour > -2) {
2849         ds->dragx = ui->dragx - TILESIZE/2 - 2;
2850         ds->dragy = ui->dragy - TILESIZE/2 - 2;
2851         blitter_save(dr, ds->bl, ds->dragx, ds->dragy);
2852         draw_circle(dr, ui->dragx, ui->dragy, TILESIZE/2,
2853                     (ui->drag_colour < 0 ? COL_BACKGROUND :
2854                      COL_0 + ui->drag_colour), COL_GRID);
2855         draw_update(dr, ds->dragx, ds->dragy, TILESIZE + 3, TILESIZE + 3);
2856         ds->drag_visible = TRUE;
2857     }
2858 }
2859
2860 static float game_anim_length(game_state *oldstate, game_state *newstate,
2861                               int dir, game_ui *ui)
2862 {
2863     return 0.0F;
2864 }
2865
2866 static float game_flash_length(game_state *oldstate, game_state *newstate,
2867                                int dir, game_ui *ui)
2868 {
2869     if (!oldstate->completed && newstate->completed &&
2870         !oldstate->cheated && !newstate->cheated) {
2871         if (flash_type < 0) {
2872             char *env = getenv("MAP_ALTERNATIVE_FLASH");
2873             if (env)
2874                 flash_type = atoi(env);
2875             else
2876                 flash_type = 0;
2877             flash_length = (flash_type == 1 ? 0.50 : 0.30);
2878         }
2879         return flash_length;
2880     } else
2881         return 0.0F;
2882 }
2883
2884 static int game_wants_statusbar(void)
2885 {
2886     return FALSE;
2887 }
2888
2889 static int game_timing_state(game_state *state, game_ui *ui)
2890 {
2891     return TRUE;
2892 }
2893
2894 static void game_print_size(game_params *params, float *x, float *y)
2895 {
2896     int pw, ph;
2897
2898     /*
2899      * I'll use 4mm squares by default, I think. Simplest way to
2900      * compute this size is to compute the pixel puzzle size at a
2901      * given tile size and then scale.
2902      */
2903     game_compute_size(params, 400, &pw, &ph);
2904     *x = pw / 100.0;
2905     *y = ph / 100.0;
2906 }
2907
2908 static void game_print(drawing *dr, game_state *state, int tilesize)
2909 {
2910     int w = state->p.w, h = state->p.h, wh = w*h, n = state->p.n;
2911     int ink, c[FOUR], i;
2912     int x, y, r;
2913     int *coords, ncoords, coordsize;
2914
2915     /* Ick: fake up `ds->tilesize' for macro expansion purposes */
2916     struct { int tilesize; } ads, *ds = &ads;
2917     ads.tilesize = tilesize;
2918
2919     ink = print_mono_colour(dr, 0);
2920     for (i = 0; i < FOUR; i++)
2921         c[i] = print_rgb_colour(dr, map_hatching[i], map_colours[i][0],
2922                                 map_colours[i][1], map_colours[i][2]);
2923
2924     coordsize = 0;
2925     coords = NULL;
2926
2927     print_line_width(dr, TILESIZE / 16);
2928
2929     /*
2930      * Draw a single filled polygon around each region.
2931      */
2932     for (r = 0; r < n; r++) {
2933         int octants[8], lastdir, d1, d2, ox, oy;
2934
2935         /*
2936          * Start by finding a point on the region boundary. Any
2937          * point will do. To do this, we'll search for a square
2938          * containing the region and then decide which corner of it
2939          * to use.
2940          */
2941         x = w;
2942         for (y = 0; y < h; y++) {
2943             for (x = 0; x < w; x++) {
2944                 if (state->map->map[wh*0+y*w+x] == r ||
2945                     state->map->map[wh*1+y*w+x] == r ||
2946                     state->map->map[wh*2+y*w+x] == r ||
2947                     state->map->map[wh*3+y*w+x] == r)
2948                     break;
2949             }
2950             if (x < w)
2951                 break;
2952         }
2953         assert(y < h && x < w);        /* we must have found one somewhere */
2954         /*
2955          * This is the first square in lexicographic order which
2956          * contains part of this region. Therefore, one of the top
2957          * two corners of the square must be what we're after. The
2958          * only case in which it isn't the top left one is if the
2959          * square is diagonally divided and the region is in the
2960          * bottom right half.
2961          */
2962         if (state->map->map[wh*TE+y*w+x] != r &&
2963             state->map->map[wh*LE+y*w+x] != r)
2964             x++;                       /* could just as well have done y++ */
2965
2966         /*
2967          * Now we have a point on the region boundary. Trace around
2968          * the region until we come back to this point,
2969          * accumulating coordinates for a polygon draw operation as
2970          * we go.
2971          */
2972         lastdir = -1;
2973         ox = x;
2974         oy = y;
2975         ncoords = 0;
2976
2977         do {
2978             /*
2979              * There are eight possible directions we could head in
2980              * from here. We identify them by octant numbers, and
2981              * we also use octant numbers to identify the spaces
2982              * between them:
2983              * 
2984              *   6   7   0
2985              *    \ 7|0 /
2986              *     \ | /
2987              *    6 \|/ 1
2988              * 5-----+-----1
2989              *    5 /|\ 2
2990              *     / | \
2991              *    / 4|3 \
2992              *   4   3   2
2993              */
2994             octants[0] = x<w && y>0 ? state->map->map[wh*LE+(y-1)*w+x] : -1;
2995             octants[1] = x<w && y>0 ? state->map->map[wh*BE+(y-1)*w+x] : -1;
2996             octants[2] = x<w && y<h ? state->map->map[wh*TE+y*w+x] : -1;
2997             octants[3] = x<w && y<h ? state->map->map[wh*LE+y*w+x] : -1;
2998             octants[4] = x>0 && y<h ? state->map->map[wh*RE+y*w+(x-1)] : -1;
2999             octants[5] = x>0 && y<h ? state->map->map[wh*TE+y*w+(x-1)] : -1;
3000             octants[6] = x>0 && y>0 ? state->map->map[wh*BE+(y-1)*w+(x-1)] :-1;
3001             octants[7] = x>0 && y>0 ? state->map->map[wh*RE+(y-1)*w+(x-1)] :-1;
3002
3003             d1 = d2 = -1;
3004             for (i = 0; i < 8; i++)
3005                 if ((octants[i] == r) ^ (octants[(i+1)%8] == r)) {
3006                     assert(d2 == -1);
3007                     if (d1 == -1)
3008                         d1 = i;
3009                     else
3010                         d2 = i;
3011                 }
3012
3013             assert(d1 != -1 && d2 != -1);
3014             if (d1 == lastdir)
3015                 d1 = d2;
3016
3017             /*
3018              * Now we're heading in direction d1. Save the current
3019              * coordinates.
3020              */
3021             if (ncoords + 2 > coordsize) {
3022                 coordsize += 128;
3023                 coords = sresize(coords, coordsize, int);
3024             }
3025             coords[ncoords++] = COORD(x);
3026             coords[ncoords++] = COORD(y);
3027
3028             /*
3029              * Compute the new coordinates.
3030              */
3031             x += (d1 % 4 == 3 ? 0 : d1 < 4 ? +1 : -1);
3032             y += (d1 % 4 == 1 ? 0 : d1 > 1 && d1 < 5 ? +1 : -1);
3033             assert(x >= 0 && x <= w && y >= 0 && y <= h);
3034
3035             lastdir = d1 ^ 4;
3036         } while (x != ox || y != oy);
3037
3038         draw_polygon(dr, coords, ncoords/2,
3039                      state->colouring[r] >= 0 ?
3040                      c[state->colouring[r]] : -1, ink);
3041     }
3042     sfree(coords);
3043 }
3044
3045 #ifdef COMBINED
3046 #define thegame map
3047 #endif
3048
3049 const struct game thegame = {
3050     "Map", "games.map",
3051     default_params,
3052     game_fetch_preset,
3053     decode_params,
3054     encode_params,
3055     free_params,
3056     dup_params,
3057     TRUE, game_configure, custom_params,
3058     validate_params,
3059     new_game_desc,
3060     validate_desc,
3061     new_game,
3062     dup_game,
3063     free_game,
3064     TRUE, solve_game,
3065     FALSE, game_text_format,
3066     new_ui,
3067     free_ui,
3068     encode_ui,
3069     decode_ui,
3070     game_changed_state,
3071     interpret_move,
3072     execute_move,
3073     20, game_compute_size, game_set_size,
3074     game_colours,
3075     game_new_drawstate,
3076     game_free_drawstate,
3077     game_redraw,
3078     game_anim_length,
3079     game_flash_length,
3080     TRUE, TRUE, game_print_size, game_print,
3081     game_wants_statusbar,
3082     FALSE, game_timing_state,
3083     0,                                 /* mouse_priorities */
3084 };
3085
3086 #ifdef STANDALONE_SOLVER
3087
3088 #include <stdarg.h>
3089
3090 void frontend_default_colour(frontend *fe, float *output) {}
3091 void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize,
3092                int align, int colour, char *text) {}
3093 void draw_rect(drawing *dr, int x, int y, int w, int h, int colour) {}
3094 void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour) {}
3095 void draw_polygon(drawing *dr, int *coords, int npoints,
3096                   int fillcolour, int outlinecolour) {}
3097 void draw_circle(drawing *dr, int cx, int cy, int radius,
3098                  int fillcolour, int outlinecolour) {}
3099 void clip(drawing *dr, int x, int y, int w, int h) {}
3100 void unclip(drawing *dr) {}
3101 void start_draw(drawing *dr) {}
3102 void draw_update(drawing *dr, int x, int y, int w, int h) {}
3103 void end_draw(drawing *dr) {}
3104 blitter *blitter_new(drawing *dr, int w, int h) {return NULL;}
3105 void blitter_free(drawing *dr, blitter *bl) {}
3106 void blitter_save(drawing *dr, blitter *bl, int x, int y) {}
3107 void blitter_load(drawing *dr, blitter *bl, int x, int y) {}
3108 int print_mono_colour(drawing *dr, int grey) { return 0; }
3109 int print_rgb_colour(drawing *dr, int hatch, float r, float g, float b)
3110 { return 0; }
3111 void print_line_width(drawing *dr, int width) {}
3112
3113 void fatal(char *fmt, ...)
3114 {
3115     va_list ap;
3116
3117     fprintf(stderr, "fatal error: ");
3118
3119     va_start(ap, fmt);
3120     vfprintf(stderr, fmt, ap);
3121     va_end(ap);
3122
3123     fprintf(stderr, "\n");
3124     exit(1);
3125 }
3126
3127 int main(int argc, char **argv)
3128 {
3129     game_params *p;
3130     game_state *s;
3131     char *id = NULL, *desc, *err;
3132     int grade = FALSE;
3133     int ret, diff, really_verbose = FALSE;
3134     struct solver_scratch *sc;
3135     int i;
3136
3137     while (--argc > 0) {
3138         char *p = *++argv;
3139         if (!strcmp(p, "-v")) {
3140             really_verbose = TRUE;
3141         } else if (!strcmp(p, "-g")) {
3142             grade = TRUE;
3143         } else if (*p == '-') {
3144             fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
3145             return 1;
3146         } else {
3147             id = p;
3148         }
3149     }
3150
3151     if (!id) {
3152         fprintf(stderr, "usage: %s [-g | -v] <game_id>\n", argv[0]);
3153         return 1;
3154     }
3155
3156     desc = strchr(id, ':');
3157     if (!desc) {
3158         fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
3159         return 1;
3160     }
3161     *desc++ = '\0';
3162
3163     p = default_params();
3164     decode_params(p, id);
3165     err = validate_desc(p, desc);
3166     if (err) {
3167         fprintf(stderr, "%s: %s\n", argv[0], err);
3168         return 1;
3169     }
3170     s = new_game(NULL, p, desc);
3171
3172     sc = new_scratch(s->map->graph, s->map->n, s->map->ngraph);
3173
3174     /*
3175      * When solving an Easy puzzle, we don't want to bother the
3176      * user with Hard-level deductions. For this reason, we grade
3177      * the puzzle internally before doing anything else.
3178      */
3179     ret = -1;                          /* placate optimiser */
3180     for (diff = 0; diff < DIFFCOUNT; diff++) {
3181         for (i = 0; i < s->map->n; i++)
3182             if (!s->map->immutable[i])
3183                 s->colouring[i] = -1;
3184         ret = map_solver(sc, s->map->graph, s->map->n, s->map->ngraph,
3185                          s->colouring, diff);
3186         if (ret < 2)
3187             break;
3188     }
3189
3190     if (diff == DIFFCOUNT) {
3191         if (grade)
3192             printf("Difficulty rating: harder than Hard, or ambiguous\n");
3193         else
3194             printf("Unable to find a unique solution\n");
3195     } else {
3196         if (grade) {
3197             if (ret == 0)
3198                 printf("Difficulty rating: impossible (no solution exists)\n");
3199             else if (ret == 1)
3200                 printf("Difficulty rating: %s\n", map_diffnames[diff]);
3201         } else {
3202             verbose = really_verbose;
3203             for (i = 0; i < s->map->n; i++)
3204                 if (!s->map->immutable[i])
3205                     s->colouring[i] = -1;
3206             ret = map_solver(sc, s->map->graph, s->map->n, s->map->ngraph,
3207                              s->colouring, diff);
3208             if (ret == 0)
3209                 printf("Puzzle is inconsistent\n");
3210             else {
3211                 int col = 0;
3212
3213                 for (i = 0; i < s->map->n; i++) {
3214                     printf("%5d <- %c%c", i, colnames[s->colouring[i]],
3215                            (col < 6 && i+1 < s->map->n ? ' ' : '\n'));
3216                     if (++col == 7)
3217                         col = 0;
3218                 }
3219             }
3220         }
3221     }
3222
3223     return 0;
3224 }
3225
3226 #endif