chiark / gitweb /
Command-line solver was dividing up non-square puzzles the wrong way
[sgt-puzzles.git] / solo.c
1 /*
2  * solo.c: the number-placing puzzle most popularly known as `Sudoku'.
3  *
4  * TODO:
5  *
6  *  - can we do anything about nasty centring of text in GTK? It
7  *    seems to be taking ascenders/descenders into account when
8  *    centring. Ick.
9  *
10  *  - it might still be nice to do some prioritisation on the
11  *    removal of numbers from the grid
12  *     + one possibility is to try to minimise the maximum number
13  *       of filled squares in any block, which in particular ought
14  *       to enforce never leaving a completely filled block in the
15  *       puzzle as presented.
16  *     + be careful of being too clever here, though, until after
17  *       I've tried implementing difficulty levels. It's not
18  *       impossible that those might impose much more important
19  *       constraints on this process.
20  *
21  *  - alternative interface modes
22  *     + sudoku.com's Windows program has a palette of possible
23  *       entries; you select a palette entry first and then click
24  *       on the square you want it to go in, thus enabling
25  *       mouse-only play. Useful for PDAs! I don't think it's
26  *       actually incompatible with the current highlight-then-type
27  *       approach: you _either_ highlight a palette entry and then
28  *       click, _or_ you highlight a square and then type. At most
29  *       one thing is ever highlighted at a time, so there's no way
30  *       to confuse the two.
31  *     + `pencil marks' might be useful for more subtle forms of
32  *       deduction, now we can create puzzles that require them.
33  */
34
35 /*
36  * Solo puzzles need to be square overall (since each row and each
37  * column must contain one of every digit), but they need not be
38  * subdivided the same way internally. I am going to adopt a
39  * convention whereby I _always_ refer to `r' as the number of rows
40  * of _big_ divisions, and `c' as the number of columns of _big_
41  * divisions. Thus, a 2c by 3r puzzle looks something like this:
42  *
43  *   4 5 1 | 2 6 3
44  *   6 3 2 | 5 4 1
45  *   ------+------     (Of course, you can't subdivide it the other way
46  *   1 4 5 | 6 3 2     or you'll get clashes; observe that the 4 in the
47  *   3 2 6 | 4 1 5     top left would conflict with the 4 in the second
48  *   ------+------     box down on the left-hand side.)
49  *   5 1 4 | 3 2 6
50  *   2 6 3 | 1 5 4
51  *
52  * The need for a strong naming convention should now be clear:
53  * each small box is two rows of digits by three columns, while the
54  * overall puzzle has three rows of small boxes by two columns. So
55  * I will (hopefully) consistently use `r' to denote the number of
56  * rows _of small boxes_ (here 3), which is also the number of
57  * columns of digits in each small box; and `c' vice versa (here
58  * 2).
59  *
60  * I'm also going to choose arbitrarily to list c first wherever
61  * possible: the above is a 2x3 puzzle, not a 3x2 one.
62  */
63
64 #include <stdio.h>
65 #include <stdlib.h>
66 #include <string.h>
67 #include <assert.h>
68 #include <ctype.h>
69 #include <math.h>
70
71 #ifdef STANDALONE_SOLVER
72 #include <stdarg.h>
73 int solver_show_working;
74 #endif
75
76 #include "puzzles.h"
77
78 #define max(x,y) ((x)>(y)?(x):(y))
79
80 /*
81  * To save space, I store digits internally as unsigned char. This
82  * imposes a hard limit of 255 on the order of the puzzle. Since
83  * even a 5x5 takes unacceptably long to generate, I don't see this
84  * as a serious limitation unless something _really_ impressive
85  * happens in computing technology; but here's a typedef anyway for
86  * general good practice.
87  */
88 typedef unsigned char digit;
89 #define ORDER_MAX 255
90
91 #define TILE_SIZE 32
92 #define BORDER 18
93
94 #define FLASH_TIME 0.4F
95
96 enum { SYMM_NONE, SYMM_ROT2, SYMM_ROT4, SYMM_REF4 };
97
98 enum { DIFF_BLOCK, DIFF_SIMPLE, DIFF_INTERSECT,
99        DIFF_SET, DIFF_RECURSIVE, DIFF_AMBIGUOUS, DIFF_IMPOSSIBLE };
100
101 enum {
102     COL_BACKGROUND,
103     COL_GRID,
104     COL_CLUE,
105     COL_USER,
106     COL_HIGHLIGHT,
107     NCOLOURS
108 };
109
110 struct game_params {
111     int c, r, symm, diff;
112 };
113
114 struct game_state {
115     int c, r;
116     digit *grid;
117     unsigned char *immutable;          /* marks which digits are clues */
118     int completed;
119 };
120
121 static game_params *default_params(void)
122 {
123     game_params *ret = snew(game_params);
124
125     ret->c = ret->r = 3;
126     ret->symm = SYMM_ROT2;             /* a plausible default */
127     ret->diff = DIFF_SIMPLE;           /* so is this */
128
129     return ret;
130 }
131
132 static void free_params(game_params *params)
133 {
134     sfree(params);
135 }
136
137 static game_params *dup_params(game_params *params)
138 {
139     game_params *ret = snew(game_params);
140     *ret = *params;                    /* structure copy */
141     return ret;
142 }
143
144 static int game_fetch_preset(int i, char **name, game_params **params)
145 {
146     static struct {
147         char *title;
148         game_params params;
149     } presets[] = {
150         { "2x2 Trivial", { 2, 2, SYMM_ROT2, DIFF_BLOCK } },
151         { "2x3 Basic", { 2, 3, SYMM_ROT2, DIFF_SIMPLE } },
152         { "3x3 Basic", { 3, 3, SYMM_ROT2, DIFF_SIMPLE } },
153         { "3x3 Intermediate", { 3, 3, SYMM_ROT2, DIFF_INTERSECT } },
154         { "3x3 Advanced", { 3, 3, SYMM_ROT2, DIFF_SET } },
155         { "3x4 Basic", { 3, 4, SYMM_ROT2, DIFF_SIMPLE } },
156         { "4x4 Basic", { 4, 4, SYMM_ROT2, DIFF_SIMPLE } },
157     };
158
159     if (i < 0 || i >= lenof(presets))
160         return FALSE;
161
162     *name = dupstr(presets[i].title);
163     *params = dup_params(&presets[i].params);
164
165     return TRUE;
166 }
167
168 static game_params *decode_params(char const *string)
169 {
170     game_params *ret = default_params();
171
172     ret->c = ret->r = atoi(string);
173     ret->symm = SYMM_ROT2;
174     while (*string && isdigit((unsigned char)*string)) string++;
175     if (*string == 'x') {
176         string++;
177         ret->r = atoi(string);
178         while (*string && isdigit((unsigned char)*string)) string++;
179     }
180     while (*string) {
181         if (*string == 'r' || *string == 'm' || *string == 'a') {
182             int sn, sc;
183             sc = *string++;
184             sn = atoi(string);
185             while (*string && isdigit((unsigned char)*string)) string++;
186             if (sc == 'm' && sn == 4)
187                 ret->symm = SYMM_REF4;
188             if (sc == 'r' && sn == 4)
189                 ret->symm = SYMM_ROT4;
190             if (sc == 'r' && sn == 2)
191                 ret->symm = SYMM_ROT2;
192             if (sc == 'a')
193                 ret->symm = SYMM_NONE;
194         } else if (*string == 'd') {
195             string++;
196             if (*string == 't')        /* trivial */
197                 string++, ret->diff = DIFF_BLOCK;
198             else if (*string == 'b')   /* basic */
199                 string++, ret->diff = DIFF_SIMPLE;
200             else if (*string == 'i')   /* intermediate */
201                 string++, ret->diff = DIFF_INTERSECT;
202             else if (*string == 'a')   /* advanced */
203                 string++, ret->diff = DIFF_SET;
204         } else
205             string++;                  /* eat unknown character */
206     }
207
208     return ret;
209 }
210
211 static char *encode_params(game_params *params)
212 {
213     char str[80];
214
215     /*
216      * Symmetry is a game generation preference and hence is left
217      * out of the encoding. Users can add it back in as they see
218      * fit.
219      */
220     sprintf(str, "%dx%d", params->c, params->r);
221     return dupstr(str);
222 }
223
224 static config_item *game_configure(game_params *params)
225 {
226     config_item *ret;
227     char buf[80];
228
229     ret = snewn(5, config_item);
230
231     ret[0].name = "Columns of sub-blocks";
232     ret[0].type = C_STRING;
233     sprintf(buf, "%d", params->c);
234     ret[0].sval = dupstr(buf);
235     ret[0].ival = 0;
236
237     ret[1].name = "Rows of sub-blocks";
238     ret[1].type = C_STRING;
239     sprintf(buf, "%d", params->r);
240     ret[1].sval = dupstr(buf);
241     ret[1].ival = 0;
242
243     ret[2].name = "Symmetry";
244     ret[2].type = C_CHOICES;
245     ret[2].sval = ":None:2-way rotation:4-way rotation:4-way mirror";
246     ret[2].ival = params->symm;
247
248     ret[3].name = "Difficulty";
249     ret[3].type = C_CHOICES;
250     ret[3].sval = ":Trivial:Basic:Intermediate:Advanced";
251     ret[3].ival = params->diff;
252
253     ret[4].name = NULL;
254     ret[4].type = C_END;
255     ret[4].sval = NULL;
256     ret[4].ival = 0;
257
258     return ret;
259 }
260
261 static game_params *custom_params(config_item *cfg)
262 {
263     game_params *ret = snew(game_params);
264
265     ret->c = atoi(cfg[0].sval);
266     ret->r = atoi(cfg[1].sval);
267     ret->symm = cfg[2].ival;
268     ret->diff = cfg[3].ival;
269
270     return ret;
271 }
272
273 static char *validate_params(game_params *params)
274 {
275     if (params->c < 2 || params->r < 2)
276         return "Both dimensions must be at least 2";
277     if (params->c > ORDER_MAX || params->r > ORDER_MAX)
278         return "Dimensions greater than "STR(ORDER_MAX)" are not supported";
279     return NULL;
280 }
281
282 /* ----------------------------------------------------------------------
283  * Full recursive Solo solver.
284  *
285  * The algorithm for this solver is shamelessly copied from a
286  * Python solver written by Andrew Wilkinson (which is GPLed, but
287  * I've reused only ideas and no code). It mostly just does the
288  * obvious recursive thing: pick an empty square, put one of the
289  * possible digits in it, recurse until all squares are filled,
290  * backtrack and change some choices if necessary.
291  *
292  * The clever bit is that every time it chooses which square to
293  * fill in next, it does so by counting the number of _possible_
294  * numbers that can go in each square, and it prioritises so that
295  * it picks a square with the _lowest_ number of possibilities. The
296  * idea is that filling in lots of the obvious bits (particularly
297  * any squares with only one possibility) will cut down on the list
298  * of possibilities for other squares and hence reduce the enormous
299  * search space as much as possible as early as possible.
300  *
301  * In practice the algorithm appeared to work very well; run on
302  * sample problems from the Times it completed in well under a
303  * second on my G5 even when written in Python, and given an empty
304  * grid (so that in principle it would enumerate _all_ solved
305  * grids!) it found the first valid solution just as quickly. So
306  * with a bit more randomisation I see no reason not to use this as
307  * my grid generator.
308  */
309
310 /*
311  * Internal data structure used in solver to keep track of
312  * progress.
313  */
314 struct rsolve_coord { int x, y, r; };
315 struct rsolve_usage {
316     int c, r, cr;                      /* cr == c*r */
317     /* grid is a copy of the input grid, modified as we go along */
318     digit *grid;
319     /* row[y*cr+n-1] TRUE if digit n has been placed in row y */
320     unsigned char *row;
321     /* col[x*cr+n-1] TRUE if digit n has been placed in row x */
322     unsigned char *col;
323     /* blk[(y*c+x)*cr+n-1] TRUE if digit n has been placed in block (x,y) */
324     unsigned char *blk;
325     /* This lists all the empty spaces remaining in the grid. */
326     struct rsolve_coord *spaces;
327     int nspaces;
328     /* If we need randomisation in the solve, this is our random state. */
329     random_state *rs;
330     /* Number of solutions so far found, and maximum number we care about. */
331     int solns, maxsolns;
332 };
333
334 /*
335  * The real recursive step in the solving function.
336  */
337 static void rsolve_real(struct rsolve_usage *usage, digit *grid)
338 {
339     int c = usage->c, r = usage->r, cr = usage->cr;
340     int i, j, n, sx, sy, bestm, bestr;
341     int *digits;
342
343     /*
344      * Firstly, check for completion! If there are no spaces left
345      * in the grid, we have a solution.
346      */
347     if (usage->nspaces == 0) {
348         if (!usage->solns) {
349             /*
350              * This is our first solution, so fill in the output grid.
351              */
352             memcpy(grid, usage->grid, cr * cr);
353         }
354         usage->solns++;
355         return;
356     }
357
358     /*
359      * Otherwise, there must be at least one space. Find the most
360      * constrained space, using the `r' field as a tie-breaker.
361      */
362     bestm = cr+1;                      /* so that any space will beat it */
363     bestr = 0;
364     i = sx = sy = -1;
365     for (j = 0; j < usage->nspaces; j++) {
366         int x = usage->spaces[j].x, y = usage->spaces[j].y;
367         int m;
368
369         /*
370          * Find the number of digits that could go in this space.
371          */
372         m = 0;
373         for (n = 0; n < cr; n++)
374             if (!usage->row[y*cr+n] && !usage->col[x*cr+n] &&
375                 !usage->blk[((y/c)*c+(x/r))*cr+n])
376                 m++;
377
378         if (m < bestm || (m == bestm && usage->spaces[j].r < bestr)) {
379             bestm = m;
380             bestr = usage->spaces[j].r;
381             sx = x;
382             sy = y;
383             i = j;
384         }
385     }
386
387     /*
388      * Swap that square into the final place in the spaces array,
389      * so that decrementing nspaces will remove it from the list.
390      */
391     if (i != usage->nspaces-1) {
392         struct rsolve_coord t;
393         t = usage->spaces[usage->nspaces-1];
394         usage->spaces[usage->nspaces-1] = usage->spaces[i];
395         usage->spaces[i] = t;
396     }
397
398     /*
399      * Now we've decided which square to start our recursion at,
400      * simply go through all possible values, shuffling them
401      * randomly first if necessary.
402      */
403     digits = snewn(bestm, int);
404     j = 0;
405     for (n = 0; n < cr; n++)
406         if (!usage->row[sy*cr+n] && !usage->col[sx*cr+n] &&
407             !usage->blk[((sy/c)*c+(sx/r))*cr+n]) {
408             digits[j++] = n+1;
409         }
410
411     if (usage->rs) {
412         /* shuffle */
413         for (i = j; i > 1; i--) {
414             int p = random_upto(usage->rs, i);
415             if (p != i-1) {
416                 int t = digits[p];
417                 digits[p] = digits[i-1];
418                 digits[i-1] = t;
419             }
420         }
421     }
422
423     /* And finally, go through the digit list and actually recurse. */
424     for (i = 0; i < j; i++) {
425         n = digits[i];
426
427         /* Update the usage structure to reflect the placing of this digit. */
428         usage->row[sy*cr+n-1] = usage->col[sx*cr+n-1] =
429             usage->blk[((sy/c)*c+(sx/r))*cr+n-1] = TRUE;
430         usage->grid[sy*cr+sx] = n;
431         usage->nspaces--;
432
433         /* Call the solver recursively. */
434         rsolve_real(usage, grid);
435
436         /*
437          * If we have seen as many solutions as we need, terminate
438          * all processing immediately.
439          */
440         if (usage->solns >= usage->maxsolns)
441             break;
442
443         /* Revert the usage structure. */
444         usage->row[sy*cr+n-1] = usage->col[sx*cr+n-1] =
445             usage->blk[((sy/c)*c+(sx/r))*cr+n-1] = FALSE;
446         usage->grid[sy*cr+sx] = 0;
447         usage->nspaces++;
448     }
449
450     sfree(digits);
451 }
452
453 /*
454  * Entry point to solver. You give it dimensions and a starting
455  * grid, which is simply an array of N^4 digits. In that array, 0
456  * means an empty square, and 1..N mean a clue square.
457  *
458  * Return value is the number of solutions found; searching will
459  * stop after the provided `max'. (Thus, you can pass max==1 to
460  * indicate that you only care about finding _one_ solution, or
461  * max==2 to indicate that you want to know the difference between
462  * a unique and non-unique solution.) The input parameter `grid' is
463  * also filled in with the _first_ (or only) solution found by the
464  * solver.
465  */
466 static int rsolve(int c, int r, digit *grid, random_state *rs, int max)
467 {
468     struct rsolve_usage *usage;
469     int x, y, cr = c*r;
470     int ret;
471
472     /*
473      * Create an rsolve_usage structure.
474      */
475     usage = snew(struct rsolve_usage);
476
477     usage->c = c;
478     usage->r = r;
479     usage->cr = cr;
480
481     usage->grid = snewn(cr * cr, digit);
482     memcpy(usage->grid, grid, cr * cr);
483
484     usage->row = snewn(cr * cr, unsigned char);
485     usage->col = snewn(cr * cr, unsigned char);
486     usage->blk = snewn(cr * cr, unsigned char);
487     memset(usage->row, FALSE, cr * cr);
488     memset(usage->col, FALSE, cr * cr);
489     memset(usage->blk, FALSE, cr * cr);
490
491     usage->spaces = snewn(cr * cr, struct rsolve_coord);
492     usage->nspaces = 0;
493
494     usage->solns = 0;
495     usage->maxsolns = max;
496
497     usage->rs = rs;
498
499     /*
500      * Now fill it in with data from the input grid.
501      */
502     for (y = 0; y < cr; y++) {
503         for (x = 0; x < cr; x++) {
504             int v = grid[y*cr+x];
505             if (v == 0) {
506                 usage->spaces[usage->nspaces].x = x;
507                 usage->spaces[usage->nspaces].y = y;
508                 if (rs)
509                     usage->spaces[usage->nspaces].r = random_bits(rs, 31);
510                 else
511                     usage->spaces[usage->nspaces].r = usage->nspaces;
512                 usage->nspaces++;
513             } else {
514                 usage->row[y*cr+v-1] = TRUE;
515                 usage->col[x*cr+v-1] = TRUE;
516                 usage->blk[((y/c)*c+(x/r))*cr+v-1] = TRUE;
517             }
518         }
519     }
520
521     /*
522      * Run the real recursive solving function.
523      */
524     rsolve_real(usage, grid);
525     ret = usage->solns;
526
527     /*
528      * Clean up the usage structure now we have our answer.
529      */
530     sfree(usage->spaces);
531     sfree(usage->blk);
532     sfree(usage->col);
533     sfree(usage->row);
534     sfree(usage->grid);
535     sfree(usage);
536
537     /*
538      * And return.
539      */
540     return ret;
541 }
542
543 /* ----------------------------------------------------------------------
544  * End of recursive solver code.
545  */
546
547 /* ----------------------------------------------------------------------
548  * Less capable non-recursive solver. This one is used to check
549  * solubility of a grid as we gradually remove numbers from it: by
550  * verifying a grid using this solver we can ensure it isn't _too_
551  * hard (e.g. does not actually require guessing and backtracking).
552  *
553  * It supports a variety of specific modes of reasoning. By
554  * enabling or disabling subsets of these modes we can arrange a
555  * range of difficulty levels.
556  */
557
558 /*
559  * Modes of reasoning currently supported:
560  *
561  *  - Positional elimination: a number must go in a particular
562  *    square because all the other empty squares in a given
563  *    row/col/blk are ruled out.
564  *
565  *  - Numeric elimination: a square must have a particular number
566  *    in because all the other numbers that could go in it are
567  *    ruled out.
568  *
569  *  - Intersectional analysis: given two domains which overlap
570  *    (hence one must be a block, and the other can be a row or
571  *    col), if the possible locations for a particular number in
572  *    one of the domains can be narrowed down to the overlap, then
573  *    that number can be ruled out everywhere but the overlap in
574  *    the other domain too.
575  *
576  *  - Set elimination: if there is a subset of the empty squares
577  *    within a domain such that the union of the possible numbers
578  *    in that subset has the same size as the subset itself, then
579  *    those numbers can be ruled out everywhere else in the domain.
580  *    (For example, if there are five empty squares and the
581  *    possible numbers in each are 12, 23, 13, 134 and 1345, then
582  *    the first three empty squares form such a subset: the numbers
583  *    1, 2 and 3 _must_ be in those three squares in some
584  *    permutation, and hence we can deduce none of them can be in
585  *    the fourth or fifth squares.)
586  *     + You can also see this the other way round, concentrating
587  *       on numbers rather than squares: if there is a subset of
588  *       the unplaced numbers within a domain such that the union
589  *       of all their possible positions has the same size as the
590  *       subset itself, then all other numbers can be ruled out for
591  *       those positions. However, it turns out that this is
592  *       exactly equivalent to the first formulation at all times:
593  *       there is a 1-1 correspondence between suitable subsets of
594  *       the unplaced numbers and suitable subsets of the unfilled
595  *       places, found by taking the _complement_ of the union of
596  *       the numbers' possible positions (or the spaces' possible
597  *       contents).
598  */
599
600 /*
601  * Within this solver, I'm going to transform all y-coordinates by
602  * inverting the significance of the block number and the position
603  * within the block. That is, we will start with the top row of
604  * each block in order, then the second row of each block in order,
605  * etc.
606  * 
607  * This transformation has the enormous advantage that it means
608  * every row, column _and_ block is described by an arithmetic
609  * progression of coordinates within the cubic array, so that I can
610  * use the same very simple function to do blockwise, row-wise and
611  * column-wise elimination.
612  */
613 #define YTRANS(y) (((y)%c)*r+(y)/c)
614 #define YUNTRANS(y) (((y)%r)*c+(y)/r)
615
616 struct nsolve_usage {
617     int c, r, cr;
618     /*
619      * We set up a cubic array, indexed by x, y and digit; each
620      * element of this array is TRUE or FALSE according to whether
621      * or not that digit _could_ in principle go in that position.
622      *
623      * The way to index this array is cube[(x*cr+y)*cr+n-1].
624      * y-coordinates in here are transformed.
625      */
626     unsigned char *cube;
627     /*
628      * This is the grid in which we write down our final
629      * deductions. y-coordinates in here are _not_ transformed.
630      */
631     digit *grid;
632     /*
633      * Now we keep track, at a slightly higher level, of what we
634      * have yet to work out, to prevent doing the same deduction
635      * many times.
636      */
637     /* row[y*cr+n-1] TRUE if digit n has been placed in row y */
638     unsigned char *row;
639     /* col[x*cr+n-1] TRUE if digit n has been placed in row x */
640     unsigned char *col;
641     /* blk[(y*c+x)*cr+n-1] TRUE if digit n has been placed in block (x,y) */
642     unsigned char *blk;
643 };
644 #define cubepos(x,y,n) (((x)*usage->cr+(y))*usage->cr+(n)-1)
645 #define cube(x,y,n) (usage->cube[cubepos(x,y,n)])
646
647 /*
648  * Function called when we are certain that a particular square has
649  * a particular number in it. The y-coordinate passed in here is
650  * transformed.
651  */
652 static void nsolve_place(struct nsolve_usage *usage, int x, int y, int n)
653 {
654     int c = usage->c, r = usage->r, cr = usage->cr;
655     int i, j, bx, by;
656
657     assert(cube(x,y,n));
658
659     /*
660      * Rule out all other numbers in this square.
661      */
662     for (i = 1; i <= cr; i++)
663         if (i != n)
664             cube(x,y,i) = FALSE;
665
666     /*
667      * Rule out this number in all other positions in the row.
668      */
669     for (i = 0; i < cr; i++)
670         if (i != y)
671             cube(x,i,n) = FALSE;
672
673     /*
674      * Rule out this number in all other positions in the column.
675      */
676     for (i = 0; i < cr; i++)
677         if (i != x)
678             cube(i,y,n) = FALSE;
679
680     /*
681      * Rule out this number in all other positions in the block.
682      */
683     bx = (x/r)*r;
684     by = y % r;
685     for (i = 0; i < r; i++)
686         for (j = 0; j < c; j++)
687             if (bx+i != x || by+j*r != y)
688                 cube(bx+i,by+j*r,n) = FALSE;
689
690     /*
691      * Enter the number in the result grid.
692      */
693     usage->grid[YUNTRANS(y)*cr+x] = n;
694
695     /*
696      * Cross out this number from the list of numbers left to place
697      * in its row, its column and its block.
698      */
699     usage->row[y*cr+n-1] = usage->col[x*cr+n-1] =
700         usage->blk[((y%r)*c+(x/r))*cr+n-1] = TRUE;
701 }
702
703 static int nsolve_elim(struct nsolve_usage *usage, int start, int step
704 #ifdef STANDALONE_SOLVER
705                        , char *fmt, ...
706 #endif
707                        )
708 {
709     int c = usage->c, r = usage->r, cr = c*r;
710     int fpos, m, i;
711
712     /*
713      * Count the number of set bits within this section of the
714      * cube.
715      */
716     m = 0;
717     fpos = -1;
718     for (i = 0; i < cr; i++)
719         if (usage->cube[start+i*step]) {
720             fpos = start+i*step;
721             m++;
722         }
723
724     if (m == 1) {
725         int x, y, n;
726         assert(fpos >= 0);
727
728         n = 1 + fpos % cr;
729         y = fpos / cr;
730         x = y / cr;
731         y %= cr;
732
733         if (!usage->grid[YUNTRANS(y)*cr+x]) {
734 #ifdef STANDALONE_SOLVER
735             if (solver_show_working) {
736                 va_list ap;
737                 va_start(ap, fmt);
738                 vprintf(fmt, ap);
739                 va_end(ap);
740                 printf(":\n  placing %d at (%d,%d)\n",
741                        n, 1+x, 1+YUNTRANS(y));
742             }
743 #endif
744             nsolve_place(usage, x, y, n);
745             return TRUE;
746         }
747     }
748
749     return FALSE;
750 }
751
752 static int nsolve_intersect(struct nsolve_usage *usage,
753                             int start1, int step1, int start2, int step2
754 #ifdef STANDALONE_SOLVER
755                             , char *fmt, ...
756 #endif
757                             )
758 {
759     int c = usage->c, r = usage->r, cr = c*r;
760     int ret, i;
761
762     /*
763      * Loop over the first domain and see if there's any set bit
764      * not also in the second.
765      */
766     for (i = 0; i < cr; i++) {
767         int p = start1+i*step1;
768         if (usage->cube[p] &&
769             !(p >= start2 && p < start2+cr*step2 &&
770               (p - start2) % step2 == 0))
771             return FALSE;              /* there is, so we can't deduce */
772     }
773
774     /*
775      * We have determined that all set bits in the first domain are
776      * within its overlap with the second. So loop over the second
777      * domain and remove all set bits that aren't also in that
778      * overlap; return TRUE iff we actually _did_ anything.
779      */
780     ret = FALSE;
781     for (i = 0; i < cr; i++) {
782         int p = start2+i*step2;
783         if (usage->cube[p] &&
784             !(p >= start1 && p < start1+cr*step1 && (p - start1) % step1 == 0))
785         {
786 #ifdef STANDALONE_SOLVER
787             if (solver_show_working) {
788                 int px, py, pn;
789
790                 if (!ret) {
791                     va_list ap;
792                     va_start(ap, fmt);
793                     vprintf(fmt, ap);
794                     va_end(ap);
795                     printf(":\n");
796                 }
797
798                 pn = 1 + p % cr;
799                 py = p / cr;
800                 px = py / cr;
801                 py %= cr;
802
803                 printf("  ruling out %d at (%d,%d)\n",
804                        pn, 1+px, 1+YUNTRANS(py));
805             }
806 #endif
807             ret = TRUE;                /* we did something */
808             usage->cube[p] = 0;
809         }
810     }
811
812     return ret;
813 }
814
815 static int nsolve_set(struct nsolve_usage *usage,
816                       int start, int step1, int step2
817 #ifdef STANDALONE_SOLVER
818                       , char *fmt, ...
819 #endif
820                       )
821 {
822     int c = usage->c, r = usage->r, cr = c*r;
823     int i, j, n, count;
824     unsigned char *grid = snewn(cr*cr, unsigned char);
825     unsigned char *rowidx = snewn(cr, unsigned char);
826     unsigned char *colidx = snewn(cr, unsigned char);
827     unsigned char *set = snewn(cr, unsigned char);
828
829     /*
830      * We are passed a cr-by-cr matrix of booleans. Our first job
831      * is to winnow it by finding any definite placements - i.e.
832      * any row with a solitary 1 - and discarding that row and the
833      * column containing the 1.
834      */
835     memset(rowidx, TRUE, cr);
836     memset(colidx, TRUE, cr);
837     for (i = 0; i < cr; i++) {
838         int count = 0, first = -1;
839         for (j = 0; j < cr; j++)
840             if (usage->cube[start+i*step1+j*step2])
841                 first = j, count++;
842         if (count == 0) {
843             /*
844              * This condition actually marks a completely insoluble
845              * (i.e. internally inconsistent) puzzle. We return and
846              * report no progress made.
847              */
848             return FALSE;
849         }
850         if (count == 1)
851             rowidx[i] = colidx[first] = FALSE;
852     }
853
854     /*
855      * Convert each of rowidx/colidx from a list of 0s and 1s to a
856      * list of the indices of the 1s.
857      */
858     for (i = j = 0; i < cr; i++)
859         if (rowidx[i])
860             rowidx[j++] = i;
861     n = j;
862     for (i = j = 0; i < cr; i++)
863         if (colidx[i])
864             colidx[j++] = i;
865     assert(n == j);
866
867     /*
868      * And create the smaller matrix.
869      */
870     for (i = 0; i < n; i++)
871         for (j = 0; j < n; j++)
872             grid[i*cr+j] = usage->cube[start+rowidx[i]*step1+colidx[j]*step2];
873
874     /*
875      * Having done that, we now have a matrix in which every row
876      * has at least two 1s in. Now we search to see if we can find
877      * a rectangle of zeroes (in the set-theoretic sense of
878      * `rectangle', i.e. a subset of rows crossed with a subset of
879      * columns) whose width and height add up to n.
880      */
881
882     memset(set, 0, n);
883     count = 0;
884     while (1) {
885         /*
886          * We have a candidate set. If its size is <=1 or >=n-1
887          * then we move on immediately.
888          */
889         if (count > 1 && count < n-1) {
890             /*
891              * The number of rows we need is n-count. See if we can
892              * find that many rows which each have a zero in all
893              * the positions listed in `set'.
894              */
895             int rows = 0;
896             for (i = 0; i < n; i++) {
897                 int ok = TRUE;
898                 for (j = 0; j < n; j++)
899                     if (set[j] && grid[i*cr+j]) {
900                         ok = FALSE;
901                         break;
902                     }
903                 if (ok)
904                     rows++;
905             }
906
907             /*
908              * We expect never to be able to get _more_ than
909              * n-count suitable rows: this would imply that (for
910              * example) there are four numbers which between them
911              * have at most three possible positions, and hence it
912              * indicates a faulty deduction before this point or
913              * even a bogus clue.
914              */
915             assert(rows <= n - count);
916             if (rows >= n - count) {
917                 int progress = FALSE;
918
919                 /*
920                  * We've got one! Now, for each row which _doesn't_
921                  * satisfy the criterion, eliminate all its set
922                  * bits in the positions _not_ listed in `set'.
923                  * Return TRUE (meaning progress has been made) if
924                  * we successfully eliminated anything at all.
925                  * 
926                  * This involves referring back through
927                  * rowidx/colidx in order to work out which actual
928                  * positions in the cube to meddle with.
929                  */
930                 for (i = 0; i < n; i++) {
931                     int ok = TRUE;
932                     for (j = 0; j < n; j++)
933                         if (set[j] && grid[i*cr+j]) {
934                             ok = FALSE;
935                             break;
936                         }
937                     if (!ok) {
938                         for (j = 0; j < n; j++)
939                             if (!set[j] && grid[i*cr+j]) {
940                                 int fpos = (start+rowidx[i]*step1+
941                                             colidx[j]*step2);
942 #ifdef STANDALONE_SOLVER
943                                 if (solver_show_working) {
944                                     int px, py, pn;
945                                     
946                                     if (!progress) {
947                                         va_list ap;
948                                         va_start(ap, fmt);
949                                         vprintf(fmt, ap);
950                                         va_end(ap);
951                                         printf(":\n");
952                                     }
953
954                                     pn = 1 + fpos % cr;
955                                     py = fpos / cr;
956                                     px = py / cr;
957                                     py %= cr;
958
959                                     printf("  ruling out %d at (%d,%d)\n",
960                                            pn, 1+px, 1+YUNTRANS(py));
961                                 }
962 #endif
963                                 progress = TRUE;
964                                 usage->cube[fpos] = FALSE;
965                             }
966                     }
967                 }
968
969                 if (progress) {
970                     sfree(set);
971                     sfree(colidx);
972                     sfree(rowidx);
973                     sfree(grid);
974                     return TRUE;
975                 }
976             }
977         }
978
979         /*
980          * Binary increment: change the rightmost 0 to a 1, and
981          * change all 1s to the right of it to 0s.
982          */
983         i = n;
984         while (i > 0 && set[i-1])
985             set[--i] = 0, count--;
986         if (i > 0)
987             set[--i] = 1, count++;
988         else
989             break;                     /* done */
990     }
991
992     sfree(set);
993     sfree(colidx);
994     sfree(rowidx);
995     sfree(grid);
996
997     return FALSE;
998 }
999
1000 static int nsolve(int c, int r, digit *grid)
1001 {
1002     struct nsolve_usage *usage;
1003     int cr = c*r;
1004     int x, y, n;
1005     int diff = DIFF_BLOCK;
1006
1007     /*
1008      * Set up a usage structure as a clean slate (everything
1009      * possible).
1010      */
1011     usage = snew(struct nsolve_usage);
1012     usage->c = c;
1013     usage->r = r;
1014     usage->cr = cr;
1015     usage->cube = snewn(cr*cr*cr, unsigned char);
1016     usage->grid = grid;                /* write straight back to the input */
1017     memset(usage->cube, TRUE, cr*cr*cr);
1018
1019     usage->row = snewn(cr * cr, unsigned char);
1020     usage->col = snewn(cr * cr, unsigned char);
1021     usage->blk = snewn(cr * cr, unsigned char);
1022     memset(usage->row, FALSE, cr * cr);
1023     memset(usage->col, FALSE, cr * cr);
1024     memset(usage->blk, FALSE, cr * cr);
1025
1026     /*
1027      * Place all the clue numbers we are given.
1028      */
1029     for (x = 0; x < cr; x++)
1030         for (y = 0; y < cr; y++)
1031             if (grid[y*cr+x])
1032                 nsolve_place(usage, x, YTRANS(y), grid[y*cr+x]);
1033
1034     /*
1035      * Now loop over the grid repeatedly trying all permitted modes
1036      * of reasoning. The loop terminates if we complete an
1037      * iteration without making any progress; we then return
1038      * failure or success depending on whether the grid is full or
1039      * not.
1040      */
1041     while (1) {
1042         /*
1043          * I'd like to write `continue;' inside each of the
1044          * following loops, so that the solver returns here after
1045          * making some progress. However, I can't specify that I
1046          * want to continue an outer loop rather than the innermost
1047          * one, so I'm apologetically resorting to a goto.
1048          */
1049         cont:
1050
1051         /*
1052          * Blockwise positional elimination.
1053          */
1054         for (x = 0; x < cr; x += r)
1055             for (y = 0; y < r; y++)
1056                 for (n = 1; n <= cr; n++)
1057                     if (!usage->blk[(y*c+(x/r))*cr+n-1] &&
1058                         nsolve_elim(usage, cubepos(x,y,n), r*cr
1059 #ifdef STANDALONE_SOLVER
1060                                     , "positional elimination,"
1061                                     " block (%d,%d)", 1+x/r, 1+y
1062 #endif
1063                                     )) {
1064                         diff = max(diff, DIFF_BLOCK);
1065                         goto cont;
1066                     }
1067
1068         /*
1069          * Row-wise positional elimination.
1070          */
1071         for (y = 0; y < cr; y++)
1072             for (n = 1; n <= cr; n++)
1073                 if (!usage->row[y*cr+n-1] &&
1074                     nsolve_elim(usage, cubepos(0,y,n), cr*cr
1075 #ifdef STANDALONE_SOLVER
1076                                 , "positional elimination,"
1077                                 " row %d", 1+YUNTRANS(y)
1078 #endif
1079                                 )) {
1080                     diff = max(diff, DIFF_SIMPLE);
1081                     goto cont;
1082                 }
1083         /*
1084          * Column-wise positional elimination.
1085          */
1086         for (x = 0; x < cr; x++)
1087             for (n = 1; n <= cr; n++)
1088                 if (!usage->col[x*cr+n-1] &&
1089                     nsolve_elim(usage, cubepos(x,0,n), cr
1090 #ifdef STANDALONE_SOLVER
1091                                 , "positional elimination," " column %d", 1+x
1092 #endif
1093                                 )) {
1094                     diff = max(diff, DIFF_SIMPLE);
1095                     goto cont;
1096                 }
1097
1098         /*
1099          * Numeric elimination.
1100          */
1101         for (x = 0; x < cr; x++)
1102             for (y = 0; y < cr; y++)
1103                 if (!usage->grid[YUNTRANS(y)*cr+x] &&
1104                     nsolve_elim(usage, cubepos(x,y,1), 1
1105 #ifdef STANDALONE_SOLVER
1106                                 , "numeric elimination at (%d,%d)", 1+x,
1107                                 1+YUNTRANS(y)
1108 #endif
1109                                 )) {
1110                     diff = max(diff, DIFF_SIMPLE);
1111                     goto cont;
1112                 }
1113
1114         /*
1115          * Intersectional analysis, rows vs blocks.
1116          */
1117         for (y = 0; y < cr; y++)
1118             for (x = 0; x < cr; x += r)
1119                 for (n = 1; n <= cr; n++)
1120                     if (!usage->row[y*cr+n-1] &&
1121                         !usage->blk[((y%r)*c+(x/r))*cr+n-1] &&
1122                         (nsolve_intersect(usage, cubepos(0,y,n), cr*cr,
1123                                           cubepos(x,y%r,n), r*cr
1124 #ifdef STANDALONE_SOLVER
1125                                           , "intersectional analysis,"
1126                                           " row %d vs block (%d,%d)",
1127                                           1+YUNTRANS(y), 1+x, 1+y%r
1128 #endif
1129                                           ) ||
1130                          nsolve_intersect(usage, cubepos(x,y%r,n), r*cr,
1131                                           cubepos(0,y,n), cr*cr
1132 #ifdef STANDALONE_SOLVER
1133                                           , "intersectional analysis,"
1134                                           " block (%d,%d) vs row %d",
1135                                           1+x, 1+y%r, 1+YUNTRANS(y)
1136 #endif
1137                                           ))) {
1138                         diff = max(diff, DIFF_INTERSECT);
1139                         goto cont;
1140                     }
1141
1142         /*
1143          * Intersectional analysis, columns vs blocks.
1144          */
1145         for (x = 0; x < cr; x++)
1146             for (y = 0; y < r; y++)
1147                 for (n = 1; n <= cr; n++)
1148                     if (!usage->col[x*cr+n-1] &&
1149                         !usage->blk[(y*c+(x/r))*cr+n-1] &&
1150                         (nsolve_intersect(usage, cubepos(x,0,n), cr,
1151                                           cubepos((x/r)*r,y,n), r*cr
1152 #ifdef STANDALONE_SOLVER
1153                                           , "intersectional analysis,"
1154                                           " column %d vs block (%d,%d)",
1155                                           1+x, 1+x/r, 1+y
1156 #endif
1157                                           ) ||
1158                          nsolve_intersect(usage, cubepos((x/r)*r,y,n), r*cr,
1159                                           cubepos(x,0,n), cr
1160 #ifdef STANDALONE_SOLVER
1161                                           , "intersectional analysis,"
1162                                           " block (%d,%d) vs column %d",
1163                                           1+x/r, 1+y, 1+x
1164 #endif
1165                                           ))) {
1166                         diff = max(diff, DIFF_INTERSECT);
1167                         goto cont;
1168                     }
1169
1170         /*
1171          * Blockwise set elimination.
1172          */
1173         for (x = 0; x < cr; x += r)
1174             for (y = 0; y < r; y++)
1175                 if (nsolve_set(usage, cubepos(x,y,1), r*cr, 1
1176 #ifdef STANDALONE_SOLVER
1177                                , "set elimination, block (%d,%d)", 1+x/r, 1+y
1178 #endif
1179                                )) {
1180                     diff = max(diff, DIFF_SET);
1181                     goto cont;
1182                 }
1183
1184         /*
1185          * Row-wise set elimination.
1186          */
1187         for (y = 0; y < cr; y++)
1188             if (nsolve_set(usage, cubepos(0,y,1), cr*cr, 1
1189 #ifdef STANDALONE_SOLVER
1190                            , "set elimination, row %d", 1+YUNTRANS(y)
1191 #endif
1192                            )) {
1193                 diff = max(diff, DIFF_SET);
1194                 goto cont;
1195             }
1196
1197         /*
1198          * Column-wise set elimination.
1199          */
1200         for (x = 0; x < cr; x++)
1201             if (nsolve_set(usage, cubepos(x,0,1), cr, 1
1202 #ifdef STANDALONE_SOLVER
1203                            , "set elimination, column %d", 1+x
1204 #endif
1205                            )) {
1206                 diff = max(diff, DIFF_SET);
1207                 goto cont;
1208             }
1209
1210         /*
1211          * If we reach here, we have made no deductions in this
1212          * iteration, so the algorithm terminates.
1213          */
1214         break;
1215     }
1216
1217     sfree(usage->cube);
1218     sfree(usage->row);
1219     sfree(usage->col);
1220     sfree(usage->blk);
1221     sfree(usage);
1222
1223     for (x = 0; x < cr; x++)
1224         for (y = 0; y < cr; y++)
1225             if (!grid[y*cr+x])
1226                 return DIFF_IMPOSSIBLE;
1227     return diff;
1228 }
1229
1230 /* ----------------------------------------------------------------------
1231  * End of non-recursive solver code.
1232  */
1233
1234 /*
1235  * Check whether a grid contains a valid complete puzzle.
1236  */
1237 static int check_valid(int c, int r, digit *grid)
1238 {
1239     int cr = c*r;
1240     unsigned char *used;
1241     int x, y, n;
1242
1243     used = snewn(cr, unsigned char);
1244
1245     /*
1246      * Check that each row contains precisely one of everything.
1247      */
1248     for (y = 0; y < cr; y++) {
1249         memset(used, FALSE, cr);
1250         for (x = 0; x < cr; x++)
1251             if (grid[y*cr+x] > 0 && grid[y*cr+x] <= cr)
1252                 used[grid[y*cr+x]-1] = TRUE;
1253         for (n = 0; n < cr; n++)
1254             if (!used[n]) {
1255                 sfree(used);
1256                 return FALSE;
1257             }
1258     }
1259
1260     /*
1261      * Check that each column contains precisely one of everything.
1262      */
1263     for (x = 0; x < cr; x++) {
1264         memset(used, FALSE, cr);
1265         for (y = 0; y < cr; y++)
1266             if (grid[y*cr+x] > 0 && grid[y*cr+x] <= cr)
1267                 used[grid[y*cr+x]-1] = TRUE;
1268         for (n = 0; n < cr; n++)
1269             if (!used[n]) {
1270                 sfree(used);
1271                 return FALSE;
1272             }
1273     }
1274
1275     /*
1276      * Check that each block contains precisely one of everything.
1277      */
1278     for (x = 0; x < cr; x += r) {
1279         for (y = 0; y < cr; y += c) {
1280             int xx, yy;
1281             memset(used, FALSE, cr);
1282             for (xx = x; xx < x+r; xx++)
1283                 for (yy = 0; yy < y+c; yy++)
1284                     if (grid[yy*cr+xx] > 0 && grid[yy*cr+xx] <= cr)
1285                         used[grid[yy*cr+xx]-1] = TRUE;
1286             for (n = 0; n < cr; n++)
1287                 if (!used[n]) {
1288                     sfree(used);
1289                     return FALSE;
1290                 }
1291         }
1292     }
1293
1294     sfree(used);
1295     return TRUE;
1296 }
1297
1298 static void symmetry_limit(game_params *params, int *xlim, int *ylim, int s)
1299 {
1300     int c = params->c, r = params->r, cr = c*r;
1301
1302     switch (s) {
1303       case SYMM_NONE:
1304         *xlim = *ylim = cr;
1305         break;
1306       case SYMM_ROT2:
1307         *xlim = (cr+1) / 2;
1308         *ylim = cr;
1309         break;
1310       case SYMM_REF4:
1311       case SYMM_ROT4:
1312         *xlim = *ylim = (cr+1) / 2;
1313         break;
1314     }
1315 }
1316
1317 static int symmetries(game_params *params, int x, int y, int *output, int s)
1318 {
1319     int c = params->c, r = params->r, cr = c*r;
1320     int i = 0;
1321
1322     *output++ = x;
1323     *output++ = y;
1324     i++;
1325
1326     switch (s) {
1327       case SYMM_NONE:
1328         break;                         /* just x,y is all we need */
1329       case SYMM_REF4:
1330       case SYMM_ROT4:
1331         switch (s) {
1332           case SYMM_REF4:
1333             *output++ = cr - 1 - x;
1334             *output++ = y;
1335             i++;
1336
1337             *output++ = x;
1338             *output++ = cr - 1 - y;
1339             i++;
1340             break;
1341           case SYMM_ROT4:
1342             *output++ = cr - 1 - y;
1343             *output++ = x;
1344             i++;
1345
1346             *output++ = y;
1347             *output++ = cr - 1 - x;
1348             i++;
1349             break;
1350         }
1351         /* fall through */
1352       case SYMM_ROT2:
1353         *output++ = cr - 1 - x;
1354         *output++ = cr - 1 - y;
1355         i++;
1356         break;
1357     }
1358
1359     return i;
1360 }
1361
1362 static char *new_game_seed(game_params *params, random_state *rs)
1363 {
1364     int c = params->c, r = params->r, cr = c*r;
1365     int area = cr*cr;
1366     digit *grid, *grid2;
1367     struct xy { int x, y; } *locs;
1368     int nlocs;
1369     int ret;
1370     char *seed;
1371     int coords[16], ncoords;
1372     int xlim, ylim;
1373     int maxdiff;
1374
1375     /*
1376      * Adjust the maximum difficulty level to be consistent with
1377      * the puzzle size: all 2x2 puzzles appear to be Trivial
1378      * (DIFF_BLOCK) so we cannot hold out for even a Basic
1379      * (DIFF_SIMPLE) one.
1380      */
1381     maxdiff = params->diff;
1382     if (c == 2 && r == 2)
1383         maxdiff = DIFF_BLOCK;
1384
1385     grid = snewn(area, digit);
1386     locs = snewn(area, struct xy);
1387     grid2 = snewn(area, digit);
1388
1389     /*
1390      * Loop until we get a grid of the required difficulty. This is
1391      * nasty, but it seems to be unpleasantly hard to generate
1392      * difficult grids otherwise.
1393      */
1394     do {
1395         /*
1396          * Start the recursive solver with an empty grid to generate a
1397          * random solved state.
1398          */
1399         memset(grid, 0, area);
1400         ret = rsolve(c, r, grid, rs, 1);
1401         assert(ret == 1);
1402         assert(check_valid(c, r, grid));
1403
1404         /*
1405          * Now we have a solved grid, start removing things from it
1406          * while preserving solubility.
1407          */
1408         symmetry_limit(params, &xlim, &ylim, params->symm);
1409         while (1) {
1410             int x, y, i, j;
1411
1412             /*
1413              * Iterate over the grid and enumerate all the filled
1414              * squares we could empty.
1415              */
1416             nlocs = 0;
1417
1418             for (x = 0; x < xlim; x++)
1419                 for (y = 0; y < ylim; y++)
1420                     if (grid[y*cr+x]) {
1421                         locs[nlocs].x = x;
1422                         locs[nlocs].y = y;
1423                         nlocs++;
1424                     }
1425
1426             /*
1427              * Now shuffle that list.
1428              */
1429             for (i = nlocs; i > 1; i--) {
1430                 int p = random_upto(rs, i);
1431                 if (p != i-1) {
1432                     struct xy t = locs[p];
1433                     locs[p] = locs[i-1];
1434                     locs[i-1] = t;
1435                 }
1436             }
1437
1438             /*
1439              * Now loop over the shuffled list and, for each element,
1440              * see whether removing that element (and its reflections)
1441              * from the grid will still leave the grid soluble by
1442              * nsolve.
1443              */
1444             for (i = 0; i < nlocs; i++) {
1445                 x = locs[i].x;
1446                 y = locs[i].y;
1447
1448                 memcpy(grid2, grid, area);
1449                 ncoords = symmetries(params, x, y, coords, params->symm);
1450                 for (j = 0; j < ncoords; j++)
1451                     grid2[coords[2*j+1]*cr+coords[2*j]] = 0;
1452
1453                 if (nsolve(c, r, grid2) <= maxdiff) {
1454                     for (j = 0; j < ncoords; j++)
1455                         grid[coords[2*j+1]*cr+coords[2*j]] = 0;
1456                     break;
1457                 }
1458             }
1459
1460             if (i == nlocs) {
1461                 /*
1462                  * There was nothing we could remove without destroying
1463                  * solvability.
1464                  */
1465                 break;
1466             }
1467         }
1468
1469         memcpy(grid2, grid, area);
1470     } while (nsolve(c, r, grid2) != maxdiff);
1471
1472     sfree(grid2);
1473     sfree(locs);
1474
1475     /*
1476      * Now we have the grid as it will be presented to the user.
1477      * Encode it in a game seed.
1478      */
1479     {
1480         char *p;
1481         int run, i;
1482
1483         seed = snewn(5 * area, char);
1484         p = seed;
1485         run = 0;
1486         for (i = 0; i <= area; i++) {
1487             int n = (i < area ? grid[i] : -1);
1488
1489             if (!n)
1490                 run++;
1491             else {
1492                 if (run) {
1493                     while (run > 0) {
1494                         int c = 'a' - 1 + run;
1495                         if (run > 26)
1496                             c = 'z';
1497                         *p++ = c;
1498                         run -= c - ('a' - 1);
1499                     }
1500                 } else {
1501                     /*
1502                      * If there's a number in the very top left or
1503                      * bottom right, there's no point putting an
1504                      * unnecessary _ before or after it.
1505                      */
1506                     if (p > seed && n > 0)
1507                         *p++ = '_';
1508                 }
1509                 if (n > 0)
1510                     p += sprintf(p, "%d", n);
1511                 run = 0;
1512             }
1513         }
1514         assert(p - seed < 5 * area);
1515         *p++ = '\0';
1516         seed = sresize(seed, p - seed, char);
1517     }
1518
1519     sfree(grid);
1520
1521     return seed;
1522 }
1523
1524 static char *validate_seed(game_params *params, char *seed)
1525 {
1526     int area = params->r * params->r * params->c * params->c;
1527     int squares = 0;
1528
1529     while (*seed) {
1530         int n = *seed++;
1531         if (n >= 'a' && n <= 'z') {
1532             squares += n - 'a' + 1;
1533         } else if (n == '_') {
1534             /* do nothing */;
1535         } else if (n > '0' && n <= '9') {
1536             squares++;
1537             while (*seed >= '0' && *seed <= '9')
1538                 seed++;
1539         } else
1540             return "Invalid character in game specification";
1541     }
1542
1543     if (squares < area)
1544         return "Not enough data to fill grid";
1545
1546     if (squares > area)
1547         return "Too much data to fit in grid";
1548
1549     return NULL;
1550 }
1551
1552 static game_state *new_game(game_params *params, char *seed)
1553 {
1554     game_state *state = snew(game_state);
1555     int c = params->c, r = params->r, cr = c*r, area = cr * cr;
1556     int i;
1557
1558     state->c = params->c;
1559     state->r = params->r;
1560
1561     state->grid = snewn(area, digit);
1562     state->immutable = snewn(area, unsigned char);
1563     memset(state->immutable, FALSE, area);
1564
1565     state->completed = FALSE;
1566
1567     i = 0;
1568     while (*seed) {
1569         int n = *seed++;
1570         if (n >= 'a' && n <= 'z') {
1571             int run = n - 'a' + 1;
1572             assert(i + run <= area);
1573             while (run-- > 0)
1574                 state->grid[i++] = 0;
1575         } else if (n == '_') {
1576             /* do nothing */;
1577         } else if (n > '0' && n <= '9') {
1578             assert(i < area);
1579             state->immutable[i] = TRUE;
1580             state->grid[i++] = atoi(seed-1);
1581             while (*seed >= '0' && *seed <= '9')
1582                 seed++;
1583         } else {
1584             assert(!"We can't get here");
1585         }
1586     }
1587     assert(i == area);
1588
1589     return state;
1590 }
1591
1592 static game_state *dup_game(game_state *state)
1593 {
1594     game_state *ret = snew(game_state);
1595     int c = state->c, r = state->r, cr = c*r, area = cr * cr;
1596
1597     ret->c = state->c;
1598     ret->r = state->r;
1599
1600     ret->grid = snewn(area, digit);
1601     memcpy(ret->grid, state->grid, area);
1602
1603     ret->immutable = snewn(area, unsigned char);
1604     memcpy(ret->immutable, state->immutable, area);
1605
1606     ret->completed = state->completed;
1607
1608     return ret;
1609 }
1610
1611 static void free_game(game_state *state)
1612 {
1613     sfree(state->immutable);
1614     sfree(state->grid);
1615     sfree(state);
1616 }
1617
1618 struct game_ui {
1619     /*
1620      * These are the coordinates of the currently highlighted
1621      * square on the grid, or -1,-1 if there isn't one. When there
1622      * is, pressing a valid number or letter key or Space will
1623      * enter that number or letter in the grid.
1624      */
1625     int hx, hy;
1626 };
1627
1628 static game_ui *new_ui(game_state *state)
1629 {
1630     game_ui *ui = snew(game_ui);
1631
1632     ui->hx = ui->hy = -1;
1633
1634     return ui;
1635 }
1636
1637 static void free_ui(game_ui *ui)
1638 {
1639     sfree(ui);
1640 }
1641
1642 static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
1643                              int button)
1644 {
1645     int c = from->c, r = from->r, cr = c*r;
1646     int tx, ty;
1647     game_state *ret;
1648
1649     tx = (x + TILE_SIZE - BORDER) / TILE_SIZE - 1;
1650     ty = (y + TILE_SIZE - BORDER) / TILE_SIZE - 1;
1651
1652     if (tx >= 0 && tx < cr && ty >= 0 && ty < cr && button == LEFT_BUTTON) {
1653         if (tx == ui->hx && ty == ui->hy) {
1654             ui->hx = ui->hy = -1;
1655         } else {
1656             ui->hx = tx;
1657             ui->hy = ty;
1658         }
1659         return from;                   /* UI activity occurred */
1660     }
1661
1662     if (ui->hx != -1 && ui->hy != -1 &&
1663         ((button >= '1' && button <= '9' && button - '0' <= cr) ||
1664          (button >= 'a' && button <= 'z' && button - 'a' + 10 <= cr) ||
1665          (button >= 'A' && button <= 'Z' && button - 'A' + 10 <= cr) ||
1666          button == ' ')) {
1667         int n = button - '0';
1668         if (button >= 'A' && button <= 'Z')
1669             n = button - 'A' + 10;
1670         if (button >= 'a' && button <= 'z')
1671             n = button - 'a' + 10;
1672         if (button == ' ')
1673             n = 0;
1674
1675         if (from->immutable[ui->hy*cr+ui->hx])
1676             return NULL;               /* can't overwrite this square */
1677
1678         ret = dup_game(from);
1679         ret->grid[ui->hy*cr+ui->hx] = n;
1680         ui->hx = ui->hy = -1;
1681
1682         /*
1683          * We've made a real change to the grid. Check to see
1684          * if the game has been completed.
1685          */
1686         if (!ret->completed && check_valid(c, r, ret->grid)) {
1687             ret->completed = TRUE;
1688         }
1689
1690         return ret;                    /* made a valid move */
1691     }
1692
1693     return NULL;
1694 }
1695
1696 /* ----------------------------------------------------------------------
1697  * Drawing routines.
1698  */
1699
1700 struct game_drawstate {
1701     int started;
1702     int c, r, cr;
1703     digit *grid;
1704     unsigned char *hl;
1705 };
1706
1707 #define XSIZE(cr) ((cr) * TILE_SIZE + 2*BORDER + 1)
1708 #define YSIZE(cr) ((cr) * TILE_SIZE + 2*BORDER + 1)
1709
1710 static void game_size(game_params *params, int *x, int *y)
1711 {
1712     int c = params->c, r = params->r, cr = c*r;
1713
1714     *x = XSIZE(cr);
1715     *y = YSIZE(cr);
1716 }
1717
1718 static float *game_colours(frontend *fe, game_state *state, int *ncolours)
1719 {
1720     float *ret = snewn(3 * NCOLOURS, float);
1721
1722     frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
1723
1724     ret[COL_GRID * 3 + 0] = 0.0F;
1725     ret[COL_GRID * 3 + 1] = 0.0F;
1726     ret[COL_GRID * 3 + 2] = 0.0F;
1727
1728     ret[COL_CLUE * 3 + 0] = 0.0F;
1729     ret[COL_CLUE * 3 + 1] = 0.0F;
1730     ret[COL_CLUE * 3 + 2] = 0.0F;
1731
1732     ret[COL_USER * 3 + 0] = 0.0F;
1733     ret[COL_USER * 3 + 1] = 0.6F * ret[COL_BACKGROUND * 3 + 1];
1734     ret[COL_USER * 3 + 2] = 0.0F;
1735
1736     ret[COL_HIGHLIGHT * 3 + 0] = 0.85F * ret[COL_BACKGROUND * 3 + 0];
1737     ret[COL_HIGHLIGHT * 3 + 1] = 0.85F * ret[COL_BACKGROUND * 3 + 1];
1738     ret[COL_HIGHLIGHT * 3 + 2] = 0.85F * ret[COL_BACKGROUND * 3 + 2];
1739
1740     *ncolours = NCOLOURS;
1741     return ret;
1742 }
1743
1744 static game_drawstate *game_new_drawstate(game_state *state)
1745 {
1746     struct game_drawstate *ds = snew(struct game_drawstate);
1747     int c = state->c, r = state->r, cr = c*r;
1748
1749     ds->started = FALSE;
1750     ds->c = c;
1751     ds->r = r;
1752     ds->cr = cr;
1753     ds->grid = snewn(cr*cr, digit);
1754     memset(ds->grid, 0, cr*cr);
1755     ds->hl = snewn(cr*cr, unsigned char);
1756     memset(ds->hl, 0, cr*cr);
1757
1758     return ds;
1759 }
1760
1761 static void game_free_drawstate(game_drawstate *ds)
1762 {
1763     sfree(ds->hl);
1764     sfree(ds->grid);
1765     sfree(ds);
1766 }
1767
1768 static void draw_number(frontend *fe, game_drawstate *ds, game_state *state,
1769                         int x, int y, int hl)
1770 {
1771     int c = state->c, r = state->r, cr = c*r;
1772     int tx, ty;
1773     int cx, cy, cw, ch;
1774     char str[2];
1775
1776     if (ds->grid[y*cr+x] == state->grid[y*cr+x] && ds->hl[y*cr+x] == hl)
1777         return;                        /* no change required */
1778
1779     tx = BORDER + x * TILE_SIZE + 2;
1780     ty = BORDER + y * TILE_SIZE + 2;
1781
1782     cx = tx;
1783     cy = ty;
1784     cw = TILE_SIZE-3;
1785     ch = TILE_SIZE-3;
1786
1787     if (x % r)
1788         cx--, cw++;
1789     if ((x+1) % r)
1790         cw++;
1791     if (y % c)
1792         cy--, ch++;
1793     if ((y+1) % c)
1794         ch++;
1795
1796     clip(fe, cx, cy, cw, ch);
1797
1798     /* background needs erasing? */
1799     if (ds->grid[y*cr+x] || ds->hl[y*cr+x] != hl)
1800         draw_rect(fe, cx, cy, cw, ch, hl ? COL_HIGHLIGHT : COL_BACKGROUND);
1801
1802     /* new number needs drawing? */
1803     if (state->grid[y*cr+x]) {
1804         str[1] = '\0';
1805         str[0] = state->grid[y*cr+x] + '0';
1806         if (str[0] > '9')
1807             str[0] += 'a' - ('9'+1);
1808         draw_text(fe, tx + TILE_SIZE/2, ty + TILE_SIZE/2,
1809                   FONT_VARIABLE, TILE_SIZE/2, ALIGN_VCENTRE | ALIGN_HCENTRE,
1810                   state->immutable[y*cr+x] ? COL_CLUE : COL_USER, str);
1811     }
1812
1813     unclip(fe);
1814
1815     draw_update(fe, cx, cy, cw, ch);
1816
1817     ds->grid[y*cr+x] = state->grid[y*cr+x];
1818     ds->hl[y*cr+x] = hl;
1819 }
1820
1821 static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
1822                         game_state *state, int dir, game_ui *ui,
1823                         float animtime, float flashtime)
1824 {
1825     int c = state->c, r = state->r, cr = c*r;
1826     int x, y;
1827
1828     if (!ds->started) {
1829         /*
1830          * The initial contents of the window are not guaranteed
1831          * and can vary with front ends. To be on the safe side,
1832          * all games should start by drawing a big
1833          * background-colour rectangle covering the whole window.
1834          */
1835         draw_rect(fe, 0, 0, XSIZE(cr), YSIZE(cr), COL_BACKGROUND);
1836
1837         /*
1838          * Draw the grid.
1839          */
1840         for (x = 0; x <= cr; x++) {
1841             int thick = (x % r ? 0 : 1);
1842             draw_rect(fe, BORDER + x*TILE_SIZE - thick, BORDER-1,
1843                       1+2*thick, cr*TILE_SIZE+3, COL_GRID);
1844         }
1845         for (y = 0; y <= cr; y++) {
1846             int thick = (y % c ? 0 : 1);
1847             draw_rect(fe, BORDER-1, BORDER + y*TILE_SIZE - thick,
1848                       cr*TILE_SIZE+3, 1+2*thick, COL_GRID);
1849         }
1850     }
1851
1852     /*
1853      * Draw any numbers which need redrawing.
1854      */
1855     for (x = 0; x < cr; x++) {
1856         for (y = 0; y < cr; y++) {
1857             draw_number(fe, ds, state, x, y,
1858                         (x == ui->hx && y == ui->hy) ||
1859                         (flashtime > 0 &&
1860                          (flashtime <= FLASH_TIME/3 ||
1861                           flashtime >= FLASH_TIME*2/3)));
1862         }
1863     }
1864
1865     /*
1866      * Update the _entire_ grid if necessary.
1867      */
1868     if (!ds->started) {
1869         draw_update(fe, 0, 0, XSIZE(cr), YSIZE(cr));
1870         ds->started = TRUE;
1871     }
1872 }
1873
1874 static float game_anim_length(game_state *oldstate, game_state *newstate,
1875                               int dir)
1876 {
1877     return 0.0F;
1878 }
1879
1880 static float game_flash_length(game_state *oldstate, game_state *newstate,
1881                                int dir)
1882 {
1883     if (!oldstate->completed && newstate->completed)
1884         return FLASH_TIME;
1885     return 0.0F;
1886 }
1887
1888 static int game_wants_statusbar(void)
1889 {
1890     return FALSE;
1891 }
1892
1893 #ifdef COMBINED
1894 #define thegame solo
1895 #endif
1896
1897 const struct game thegame = {
1898     "Solo", "games.solo", TRUE,
1899     default_params,
1900     game_fetch_preset,
1901     decode_params,
1902     encode_params,
1903     free_params,
1904     dup_params,
1905     game_configure,
1906     custom_params,
1907     validate_params,
1908     new_game_seed,
1909     validate_seed,
1910     new_game,
1911     dup_game,
1912     free_game,
1913     new_ui,
1914     free_ui,
1915     make_move,
1916     game_size,
1917     game_colours,
1918     game_new_drawstate,
1919     game_free_drawstate,
1920     game_redraw,
1921     game_anim_length,
1922     game_flash_length,
1923     game_wants_statusbar,
1924 };
1925
1926 #ifdef STANDALONE_SOLVER
1927
1928 /*
1929  * gcc -DSTANDALONE_SOLVER -o solosolver solo.c malloc.c
1930  */
1931
1932 void frontend_default_colour(frontend *fe, float *output) {}
1933 void draw_text(frontend *fe, int x, int y, int fonttype, int fontsize,
1934                int align, int colour, char *text) {}
1935 void draw_rect(frontend *fe, int x, int y, int w, int h, int colour) {}
1936 void draw_line(frontend *fe, int x1, int y1, int x2, int y2, int colour) {}
1937 void draw_polygon(frontend *fe, int *coords, int npoints,
1938                   int fill, int colour) {}
1939 void clip(frontend *fe, int x, int y, int w, int h) {}
1940 void unclip(frontend *fe) {}
1941 void start_draw(frontend *fe) {}
1942 void draw_update(frontend *fe, int x, int y, int w, int h) {}
1943 void end_draw(frontend *fe) {}
1944 unsigned long random_bits(random_state *state, int bits)
1945 { assert(!"Shouldn't get randomness"); return 0; }
1946 unsigned long random_upto(random_state *state, unsigned long limit)
1947 { assert(!"Shouldn't get randomness"); return 0; }
1948
1949 void fatal(char *fmt, ...)
1950 {
1951     va_list ap;
1952
1953     fprintf(stderr, "fatal error: ");
1954
1955     va_start(ap, fmt);
1956     vfprintf(stderr, fmt, ap);
1957     va_end(ap);
1958
1959     fprintf(stderr, "\n");
1960     exit(1);
1961 }
1962
1963 int main(int argc, char **argv)
1964 {
1965     game_params *p;
1966     game_state *s;
1967     int recurse = TRUE;
1968     char *id = NULL, *seed, *err;
1969     int y, x;
1970     int grade = FALSE;
1971
1972     while (--argc > 0) {
1973         char *p = *++argv;
1974         if (!strcmp(p, "-r")) {
1975             recurse = TRUE;
1976         } else if (!strcmp(p, "-n")) {
1977             recurse = FALSE;
1978         } else if (!strcmp(p, "-v")) {
1979             solver_show_working = TRUE;
1980             recurse = FALSE;
1981         } else if (!strcmp(p, "-g")) {
1982             grade = TRUE;
1983             recurse = FALSE;
1984         } else if (*p == '-') {
1985             fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0]);
1986             return 1;
1987         } else {
1988             id = p;
1989         }
1990     }
1991
1992     if (!id) {
1993         fprintf(stderr, "usage: %s [-n | -r | -g | -v] <game_id>\n", argv[0]);
1994         return 1;
1995     }
1996
1997     seed = strchr(id, ':');
1998     if (!seed) {
1999         fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
2000         return 1;
2001     }
2002     *seed++ = '\0';
2003
2004     p = decode_params(id);
2005     err = validate_seed(p, seed);
2006     if (err) {
2007         fprintf(stderr, "%s: %s\n", argv[0], err);
2008         return 1;
2009     }
2010     s = new_game(p, seed);
2011
2012     if (recurse) {
2013         int ret = rsolve(p->c, p->r, s->grid, NULL, 2);
2014         if (ret > 1) {
2015             fprintf(stderr, "%s: rsolve: multiple solutions detected\n",
2016                     argv[0]);
2017         }
2018     } else {
2019         int ret = nsolve(p->c, p->r, s->grid);
2020         if (grade) {
2021             if (ret == DIFF_IMPOSSIBLE) {
2022                 /*
2023                  * Now resort to rsolve to determine whether it's
2024                  * really soluble.
2025                  */
2026                 ret = rsolve(p->c, p->r, s->grid, NULL, 2);
2027                 if (ret == 0)
2028                     ret = DIFF_IMPOSSIBLE;
2029                 else if (ret == 1)
2030                     ret = DIFF_RECURSIVE;
2031                 else
2032                     ret = DIFF_AMBIGUOUS;
2033             }
2034             printf("Difficulty rating: %s\n",
2035                    ret==DIFF_BLOCK ? "Trivial (blockwise positional elimination only)":
2036                    ret==DIFF_SIMPLE ? "Basic (row/column/number elimination required)":
2037                    ret==DIFF_INTERSECT ? "Intermediate (intersectional analysis required)":
2038                    ret==DIFF_SET ? "Advanced (set elimination required)":
2039                    ret==DIFF_RECURSIVE ? "Unreasonable (guesswork and backtracking required)":
2040                    ret==DIFF_AMBIGUOUS ? "Ambiguous (multiple solutions exist)":
2041                    ret==DIFF_IMPOSSIBLE ? "Impossible (no solution exists)":
2042                    "INTERNAL ERROR: unrecognised difficulty code");
2043         }
2044     }
2045
2046     for (y = 0; y < p->c * p->r; y++) {
2047         for (x = 0; x < p->c * p->r; x++) {
2048             int c = s->grid[y * p->c * p->r + x];
2049             if (c == 0)
2050                 c = ' ';
2051             else if (c <= 9)
2052                 c = '0' + c;
2053             else
2054                 c = 'a' + c-10;
2055             printf("%c", c);
2056             if (x+1 < p->c * p->r) {
2057                 if ((x+1) % p->r)
2058                     printf(" ");
2059                 else
2060                     printf(" | ");
2061             }
2062         }
2063         printf("\n");
2064         if (y+1 < p->c * p->r && (y+1) % p->c == 0) {
2065             for (x = 0; x < p->c * p->r; x++) {
2066                 printf("-");
2067                 if (x+1 < p->c * p->r) {
2068                     if ((x+1) % p->r)
2069                         printf("-");
2070                     else
2071                         printf("-+-");
2072                 }
2073             }
2074             printf("\n");
2075         }
2076     }
2077     printf("\n");
2078
2079     return 0;
2080 }
2081
2082 #endif