Command-line solver was dividing up non-square puzzles the wrong way
[sgt/puzzles] / 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