chiark / gitweb /
From James Harvey (via a period of collaborative polishing), a patch
[sgt-puzzles.git] / loopy.c
1 /*
2  * loopy.c:
3  *
4  * An implementation of the Nikoli game 'Loop the loop'.
5  * (c) Mike Pinna, 2005, 2006
6  * Substantially rewritten to allowing for more general types of grid.
7  * (c) Lambros Lambrou 2008
8  *
9  * vim: set shiftwidth=4 :set textwidth=80:
10  */
11
12 /*
13  * Possible future solver enhancements:
14  * 
15  *  - There's an interesting deductive technique which makes use
16  *    of topology rather than just graph theory. Each _face_ in
17  *    the grid is either inside or outside the loop; you can tell
18  *    that two faces are on the same side of the loop if they're
19  *    separated by a LINE_NO (or, more generally, by a path
20  *    crossing no LINE_UNKNOWNs and an even number of LINE_YESes),
21  *    and on the opposite side of the loop if they're separated by
22  *    a LINE_YES (or an odd number of LINE_YESes and no
23  *    LINE_UNKNOWNs). Oh, and any face separated from the outside
24  *    of the grid by a LINE_YES or a LINE_NO is on the inside or
25  *    outside respectively. So if you can track this for all
26  *    faces, you figure out the state of the line between a pair
27  *    once their relative insideness is known.
28  *     + The way I envisage this working is simply to keep an edsf
29  *       of all _faces_, which indicates whether they're on
30  *       opposite sides of the loop from one another. We also
31  *       include a special entry in the edsf for the infinite
32  *       exterior "face".
33  *     + So, the simple way to do this is to just go through the
34  *       edges: every time we see an edge in a state other than
35  *       LINE_UNKNOWN which separates two faces that aren't in the
36  *       same edsf class, we can rectify that by merging the
37  *       classes. Then, conversely, an edge in LINE_UNKNOWN state
38  *       which separates two faces that _are_ in the same edsf
39  *       class can immediately have its state determined.
40  *     + But you can go one better, if you're prepared to loop
41  *       over all _pairs_ of edges. Suppose we have edges A and B,
42  *       which respectively separate faces A1,A2 and B1,B2.
43  *       Suppose that A,B are in the same edge-edsf class and that
44  *       A1,B1 (wlog) are in the same face-edsf class; then we can
45  *       immediately place A2,B2 into the same face-edsf class (as
46  *       each other, not as A1 and A2) one way round or the other.
47  *       And conversely again, if A1,B1 are in the same face-edsf
48  *       class and so are A2,B2, then we can put A,B into the same
49  *       face-edsf class.
50  *        * Of course, this deduction requires a quadratic-time
51  *          loop over all pairs of edges in the grid, so it should
52  *          be reserved until there's nothing easier left to be
53  *          done.
54  * 
55  *  - The generalised grid support has made me (SGT) notice a
56  *    possible extension to the loop-avoidance code. When you have
57  *    a path of connected edges such that no other edges at all
58  *    are incident on any vertex in the middle of the path - or,
59  *    alternatively, such that any such edges are already known to
60  *    be LINE_NO - then you know those edges are either all
61  *    LINE_YES or all LINE_NO. Hence you can mentally merge the
62  *    entire path into a single long curly edge for the purposes
63  *    of loop avoidance, and look directly at whether or not the
64  *    extreme endpoints of the path are connected by some other
65  *    route. I find this coming up fairly often when I play on the
66  *    octagonal grid setting, so it might be worth implementing in
67  *    the solver.
68  *
69  *  - (Just a speed optimisation.)  Consider some todo list queue where every
70  *    time we modify something we mark it for consideration by other bits of
71  *    the solver, to save iteration over things that have already been done.
72  */
73
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <stddef.h>
77 #include <string.h>
78 #include <assert.h>
79 #include <ctype.h>
80 #include <math.h>
81
82 #include "puzzles.h"
83 #include "tree234.h"
84 #include "grid.h"
85
86 /* Debugging options */
87
88 /*
89 #define DEBUG_CACHES
90 #define SHOW_WORKING
91 #define DEBUG_DLINES
92 */
93
94 /* ----------------------------------------------------------------------
95  * Struct, enum and function declarations
96  */
97
98 enum {
99     COL_BACKGROUND,
100     COL_FOREGROUND,
101     COL_LINEUNKNOWN,
102     COL_HIGHLIGHT,
103     COL_MISTAKE,
104     COL_SATISFIED,
105     COL_FAINT,
106     NCOLOURS
107 };
108
109 struct game_state {
110     grid *game_grid; /* ref-counted (internally) */
111
112     /* Put -1 in a face that doesn't get a clue */
113     signed char *clues;
114
115     /* Array of line states, to store whether each line is
116      * YES, NO or UNKNOWN */
117     char *lines;
118
119     unsigned char *line_errors;
120
121     int solved;
122     int cheated;
123
124     /* Used in game_text_format(), so that it knows what type of
125      * grid it's trying to render as ASCII text. */
126     int grid_type;
127 };
128
129 enum solver_status {
130     SOLVER_SOLVED,    /* This is the only solution the solver could find */
131     SOLVER_MISTAKE,   /* This is definitely not a solution */
132     SOLVER_AMBIGUOUS, /* This _might_ be an ambiguous solution */
133     SOLVER_INCOMPLETE /* This may be a partial solution */
134 };
135
136 /* ------ Solver state ------ */
137 typedef struct solver_state {
138     game_state *state;
139     enum solver_status solver_status;
140     /* NB looplen is the number of dots that are joined together at a point, ie a
141      * looplen of 1 means there are no lines to a particular dot */
142     int *looplen;
143
144     /* Difficulty level of solver.  Used by solver functions that want to
145      * vary their behaviour depending on the requested difficulty level. */
146     int diff;
147
148     /* caches */
149     char *dot_yes_count;
150     char *dot_no_count;
151     char *face_yes_count;
152     char *face_no_count;
153     char *dot_solved, *face_solved;
154     int *dotdsf;
155
156     /* Information for Normal level deductions:
157      * For each dline, store a bitmask for whether we know:
158      * (bit 0) at least one is YES
159      * (bit 1) at most one is YES */
160     char *dlines;
161
162     /* Hard level information */
163     int *linedsf;
164 } solver_state;
165
166 /*
167  * Difficulty levels. I do some macro ickery here to ensure that my
168  * enum and the various forms of my name list always match up.
169  */
170
171 #define DIFFLIST(A) \
172     A(EASY,Easy,e) \
173     A(NORMAL,Normal,n) \
174     A(TRICKY,Tricky,t) \
175     A(HARD,Hard,h)
176 #define ENUM(upper,title,lower) DIFF_ ## upper,
177 #define TITLE(upper,title,lower) #title,
178 #define ENCODE(upper,title,lower) #lower
179 #define CONFIG(upper,title,lower) ":" #title
180 enum { DIFFLIST(ENUM) DIFF_MAX };
181 static char const *const diffnames[] = { DIFFLIST(TITLE) };
182 static char const diffchars[] = DIFFLIST(ENCODE);
183 #define DIFFCONFIG DIFFLIST(CONFIG)
184
185 /*
186  * Solver routines, sorted roughly in order of computational cost.
187  * The solver will run the faster deductions first, and slower deductions are
188  * only invoked when the faster deductions are unable to make progress.
189  * Each function is associated with a difficulty level, so that the generated
190  * puzzles are solvable by applying only the functions with the chosen
191  * difficulty level or lower.
192  */
193 #define SOLVERLIST(A) \
194     A(trivial_deductions, DIFF_EASY) \
195     A(dline_deductions, DIFF_NORMAL) \
196     A(linedsf_deductions, DIFF_HARD) \
197     A(loop_deductions, DIFF_EASY)
198 #define SOLVER_FN_DECL(fn,diff) static int fn(solver_state *);
199 #define SOLVER_FN(fn,diff) &fn,
200 #define SOLVER_DIFF(fn,diff) diff,
201 SOLVERLIST(SOLVER_FN_DECL)
202 static int (*(solver_fns[]))(solver_state *) = { SOLVERLIST(SOLVER_FN) };
203 static int const solver_diffs[] = { SOLVERLIST(SOLVER_DIFF) };
204 const int NUM_SOLVERS = sizeof(solver_diffs)/sizeof(*solver_diffs);
205
206 struct game_params {
207     int w, h;
208     int diff;
209     int type;
210 };
211
212 /* line_drawstate is the same as line_state, but with the extra ERROR
213  * possibility.  The drawing code copies line_state to line_drawstate,
214  * except in the case that the line is an error. */
215 enum line_state { LINE_YES, LINE_UNKNOWN, LINE_NO };
216 enum line_drawstate { DS_LINE_YES, DS_LINE_UNKNOWN,
217                       DS_LINE_NO, DS_LINE_ERROR };
218
219 #define OPP(line_state) \
220     (2 - line_state)
221
222
223 struct game_drawstate {
224     int started;
225     int tilesize;
226     int flashing;
227     int *textx, *texty;
228     char *lines;
229     char *clue_error;
230     char *clue_satisfied;
231 };
232
233 static char *validate_desc(game_params *params, char *desc);
234 static int dot_order(const game_state* state, int i, char line_type);
235 static int face_order(const game_state* state, int i, char line_type);
236 static solver_state *solve_game_rec(const solver_state *sstate);
237
238 #ifdef DEBUG_CACHES
239 static void check_caches(const solver_state* sstate);
240 #else
241 #define check_caches(s)
242 #endif
243
244 /* ------- List of grid generators ------- */
245 #define GRIDLIST(A) \
246     A(Squares,GRID_SQUARE,3,3) \
247     A(Triangular,GRID_TRIANGULAR,3,3) \
248     A(Honeycomb,GRID_HONEYCOMB,3,3) \
249     A(Snub-Square,GRID_SNUBSQUARE,3,3) \
250     A(Cairo,GRID_CAIRO,3,4) \
251     A(Great-Hexagonal,GRID_GREATHEXAGONAL,3,3) \
252     A(Octagonal,GRID_OCTAGONAL,3,3) \
253     A(Kites,GRID_KITE,3,3) \
254     A(Floret,GRID_FLORET,1,2) \
255     A(Dodecagonal,GRID_DODECAGONAL,2,2) \
256     A(Great-Dodecagonal,GRID_GREATDODECAGONAL,2,2) \
257     A(Penrose (kite/dart),GRID_PENROSE_P2,3,3) \
258     A(Penrose (rhombs),GRID_PENROSE_P3,3,3)
259
260 #define GRID_NAME(title,type,amin,omin) #title,
261 #define GRID_CONFIG(title,type,amin,omin) ":" #title
262 #define GRID_TYPE(title,type,amin,omin) type,
263 #define GRID_SIZES(title,type,amin,omin) \
264     {amin, omin, \
265      "Width and height for this grid type must both be at least " #amin, \
266      "At least one of width and height for this grid type must be at least " #omin,},
267 static char const *const gridnames[] = { GRIDLIST(GRID_NAME) };
268 #define GRID_CONFIGS GRIDLIST(GRID_CONFIG)
269 static grid_type grid_types[] = { GRIDLIST(GRID_TYPE) };
270 #define NUM_GRID_TYPES (sizeof(grid_types) / sizeof(grid_types[0]))
271 static const struct {
272     int amin, omin;
273     char *aerr, *oerr;
274 } grid_size_limits[] = { GRIDLIST(GRID_SIZES) };
275
276 /* Generates a (dynamically allocated) new grid, according to the
277  * type and size requested in params.  Does nothing if the grid is already
278  * generated. */
279 static grid *loopy_generate_grid(game_params *params, char *grid_desc)
280 {
281     return grid_new(grid_types[params->type], params->w, params->h, grid_desc);
282 }
283
284 /* ----------------------------------------------------------------------
285  * Preprocessor magic
286  */
287
288 /* General constants */
289 #define PREFERRED_TILE_SIZE 32
290 #define BORDER(tilesize) ((tilesize) / 2)
291 #define FLASH_TIME 0.5F
292
293 #define BIT_SET(field, bit) ((field) & (1<<(bit)))
294
295 #define SET_BIT(field, bit)  (BIT_SET(field, bit) ? FALSE : \
296                               ((field) |= (1<<(bit)), TRUE))
297
298 #define CLEAR_BIT(field, bit) (BIT_SET(field, bit) ? \
299                                ((field) &= ~(1<<(bit)), TRUE) : FALSE)
300
301 #define CLUE2CHAR(c) \
302     ((c < 0) ? ' ' : c < 10 ? c + '0' : c - 10 + 'A')
303
304 /* ----------------------------------------------------------------------
305  * General struct manipulation and other straightforward code
306  */
307
308 static game_state *dup_game(game_state *state)
309 {
310     game_state *ret = snew(game_state);
311
312     ret->game_grid = state->game_grid;
313     ret->game_grid->refcount++;
314
315     ret->solved = state->solved;
316     ret->cheated = state->cheated;
317
318     ret->clues = snewn(state->game_grid->num_faces, signed char);
319     memcpy(ret->clues, state->clues, state->game_grid->num_faces);
320
321     ret->lines = snewn(state->game_grid->num_edges, char);
322     memcpy(ret->lines, state->lines, state->game_grid->num_edges);
323
324     ret->line_errors = snewn(state->game_grid->num_edges, unsigned char);
325     memcpy(ret->line_errors, state->line_errors, state->game_grid->num_edges);
326
327     ret->grid_type = state->grid_type;
328     return ret;
329 }
330
331 static void free_game(game_state *state)
332 {
333     if (state) {
334         grid_free(state->game_grid);
335         sfree(state->clues);
336         sfree(state->lines);
337         sfree(state->line_errors);
338         sfree(state);
339     }
340 }
341
342 static solver_state *new_solver_state(game_state *state, int diff) {
343     int i;
344     int num_dots = state->game_grid->num_dots;
345     int num_faces = state->game_grid->num_faces;
346     int num_edges = state->game_grid->num_edges;
347     solver_state *ret = snew(solver_state);
348
349     ret->state = dup_game(state);
350
351     ret->solver_status = SOLVER_INCOMPLETE;
352     ret->diff = diff;
353
354     ret->dotdsf = snew_dsf(num_dots);
355     ret->looplen = snewn(num_dots, int);
356
357     for (i = 0; i < num_dots; i++) {
358         ret->looplen[i] = 1;
359     }
360
361     ret->dot_solved = snewn(num_dots, char);
362     ret->face_solved = snewn(num_faces, char);
363     memset(ret->dot_solved, FALSE, num_dots);
364     memset(ret->face_solved, FALSE, num_faces);
365
366     ret->dot_yes_count = snewn(num_dots, char);
367     memset(ret->dot_yes_count, 0, num_dots);
368     ret->dot_no_count = snewn(num_dots, char);
369     memset(ret->dot_no_count, 0, num_dots);
370     ret->face_yes_count = snewn(num_faces, char);
371     memset(ret->face_yes_count, 0, num_faces);
372     ret->face_no_count = snewn(num_faces, char);
373     memset(ret->face_no_count, 0, num_faces);
374
375     if (diff < DIFF_NORMAL) {
376         ret->dlines = NULL;
377     } else {
378         ret->dlines = snewn(2*num_edges, char);
379         memset(ret->dlines, 0, 2*num_edges);
380     }
381
382     if (diff < DIFF_HARD) {
383         ret->linedsf = NULL;
384     } else {
385         ret->linedsf = snew_dsf(state->game_grid->num_edges);
386     }
387
388     return ret;
389 }
390
391 static void free_solver_state(solver_state *sstate) {
392     if (sstate) {
393         free_game(sstate->state);
394         sfree(sstate->dotdsf);
395         sfree(sstate->looplen);
396         sfree(sstate->dot_solved);
397         sfree(sstate->face_solved);
398         sfree(sstate->dot_yes_count);
399         sfree(sstate->dot_no_count);
400         sfree(sstate->face_yes_count);
401         sfree(sstate->face_no_count);
402
403         /* OK, because sfree(NULL) is a no-op */
404         sfree(sstate->dlines);
405         sfree(sstate->linedsf);
406
407         sfree(sstate);
408     }
409 }
410
411 static solver_state *dup_solver_state(const solver_state *sstate) {
412     game_state *state = sstate->state;
413     int num_dots = state->game_grid->num_dots;
414     int num_faces = state->game_grid->num_faces;
415     int num_edges = state->game_grid->num_edges;
416     solver_state *ret = snew(solver_state);
417
418     ret->state = state = dup_game(sstate->state);
419
420     ret->solver_status = sstate->solver_status;
421     ret->diff = sstate->diff;
422
423     ret->dotdsf = snewn(num_dots, int);
424     ret->looplen = snewn(num_dots, int);
425     memcpy(ret->dotdsf, sstate->dotdsf,
426            num_dots * sizeof(int));
427     memcpy(ret->looplen, sstate->looplen,
428            num_dots * sizeof(int));
429
430     ret->dot_solved = snewn(num_dots, char);
431     ret->face_solved = snewn(num_faces, char);
432     memcpy(ret->dot_solved, sstate->dot_solved, num_dots);
433     memcpy(ret->face_solved, sstate->face_solved, num_faces);
434
435     ret->dot_yes_count = snewn(num_dots, char);
436     memcpy(ret->dot_yes_count, sstate->dot_yes_count, num_dots);
437     ret->dot_no_count = snewn(num_dots, char);
438     memcpy(ret->dot_no_count, sstate->dot_no_count, num_dots);
439
440     ret->face_yes_count = snewn(num_faces, char);
441     memcpy(ret->face_yes_count, sstate->face_yes_count, num_faces);
442     ret->face_no_count = snewn(num_faces, char);
443     memcpy(ret->face_no_count, sstate->face_no_count, num_faces);
444
445     if (sstate->dlines) {
446         ret->dlines = snewn(2*num_edges, char);
447         memcpy(ret->dlines, sstate->dlines,
448                2*num_edges);
449     } else {
450         ret->dlines = NULL;
451     }
452
453     if (sstate->linedsf) {
454         ret->linedsf = snewn(num_edges, int);
455         memcpy(ret->linedsf, sstate->linedsf,
456                num_edges * sizeof(int));
457     } else {
458         ret->linedsf = NULL;
459     }
460
461     return ret;
462 }
463
464 static game_params *default_params(void)
465 {
466     game_params *ret = snew(game_params);
467
468 #ifdef SLOW_SYSTEM
469     ret->h = 7;
470     ret->w = 7;
471 #else
472     ret->h = 10;
473     ret->w = 10;
474 #endif
475     ret->diff = DIFF_EASY;
476     ret->type = 0;
477
478     return ret;
479 }
480
481 static game_params *dup_params(game_params *params)
482 {
483     game_params *ret = snew(game_params);
484
485     *ret = *params;                       /* structure copy */
486     return ret;
487 }
488
489 static const game_params presets[] = {
490 #ifdef SMALL_SCREEN
491     {  7,  7, DIFF_EASY, 0 },
492     {  7,  7, DIFF_NORMAL, 0 },
493     {  7,  7, DIFF_HARD, 0 },
494     {  7,  7, DIFF_HARD, 1 },
495     {  7,  7, DIFF_HARD, 2 },
496     {  5,  5, DIFF_HARD, 3 },
497     {  7,  7, DIFF_HARD, 4 },
498     {  5,  4, DIFF_HARD, 5 },
499     {  5,  5, DIFF_HARD, 6 },
500     {  5,  5, DIFF_HARD, 7 },
501     {  3,  3, DIFF_HARD, 8 },
502     {  3,  3, DIFF_HARD, 9 },
503     {  3,  3, DIFF_HARD, 10 },
504     {  6,  6, DIFF_HARD, 11 },
505     {  6,  6, DIFF_HARD, 12 },
506 #else
507     {  7,  7, DIFF_EASY, 0 },
508     {  10,  10, DIFF_EASY, 0 },
509     {  7,  7, DIFF_NORMAL, 0 },
510     {  10,  10, DIFF_NORMAL, 0 },
511     {  7,  7, DIFF_HARD, 0 },
512     {  10,  10, DIFF_HARD, 0 },
513     {  10,  10, DIFF_HARD, 1 },
514     {  12,  10, DIFF_HARD, 2 },
515     {  7,  7, DIFF_HARD, 3 },
516     {  9,  9, DIFF_HARD, 4 },
517     {  5,  4, DIFF_HARD, 5 },
518     {  7,  7, DIFF_HARD, 6 },
519     {  5,  5, DIFF_HARD, 7 },
520     {  5,  5, DIFF_HARD, 8 },
521     {  5,  4, DIFF_HARD, 9 },
522     {  5,  4, DIFF_HARD, 10 },
523     {  10, 10, DIFF_HARD, 11 },
524     {  10, 10, DIFF_HARD, 12 }
525 #endif
526 };
527
528 static int game_fetch_preset(int i, char **name, game_params **params)
529 {
530     game_params *tmppar;
531     char buf[80];
532
533     if (i < 0 || i >= lenof(presets))
534         return FALSE;
535
536     tmppar = snew(game_params);
537     *tmppar = presets[i];
538     *params = tmppar;
539     sprintf(buf, "%dx%d %s - %s", tmppar->h, tmppar->w,
540             gridnames[tmppar->type], diffnames[tmppar->diff]);
541     *name = dupstr(buf);
542
543     return TRUE;
544 }
545
546 static void free_params(game_params *params)
547 {
548     sfree(params);
549 }
550
551 static void decode_params(game_params *params, char const *string)
552 {
553     params->h = params->w = atoi(string);
554     params->diff = DIFF_EASY;
555     while (*string && isdigit((unsigned char)*string)) string++;
556     if (*string == 'x') {
557         string++;
558         params->h = atoi(string);
559         while (*string && isdigit((unsigned char)*string)) string++;
560     }
561     if (*string == 't') {
562         string++;
563         params->type = atoi(string);
564         while (*string && isdigit((unsigned char)*string)) string++;
565     }
566     if (*string == 'd') {
567         int i;
568         string++;
569         for (i = 0; i < DIFF_MAX; i++)
570             if (*string == diffchars[i])
571                 params->diff = i;
572         if (*string) string++;
573     }
574 }
575
576 static char *encode_params(game_params *params, int full)
577 {
578     char str[80];
579     sprintf(str, "%dx%dt%d", params->w, params->h, params->type);
580     if (full)
581         sprintf(str + strlen(str), "d%c", diffchars[params->diff]);
582     return dupstr(str);
583 }
584
585 static config_item *game_configure(game_params *params)
586 {
587     config_item *ret;
588     char buf[80];
589
590     ret = snewn(5, config_item);
591
592     ret[0].name = "Width";
593     ret[0].type = C_STRING;
594     sprintf(buf, "%d", params->w);
595     ret[0].sval = dupstr(buf);
596     ret[0].ival = 0;
597
598     ret[1].name = "Height";
599     ret[1].type = C_STRING;
600     sprintf(buf, "%d", params->h);
601     ret[1].sval = dupstr(buf);
602     ret[1].ival = 0;
603
604     ret[2].name = "Grid type";
605     ret[2].type = C_CHOICES;
606     ret[2].sval = GRID_CONFIGS;
607     ret[2].ival = params->type;
608
609     ret[3].name = "Difficulty";
610     ret[3].type = C_CHOICES;
611     ret[3].sval = DIFFCONFIG;
612     ret[3].ival = params->diff;
613
614     ret[4].name = NULL;
615     ret[4].type = C_END;
616     ret[4].sval = NULL;
617     ret[4].ival = 0;
618
619     return ret;
620 }
621
622 static game_params *custom_params(config_item *cfg)
623 {
624     game_params *ret = snew(game_params);
625
626     ret->w = atoi(cfg[0].sval);
627     ret->h = atoi(cfg[1].sval);
628     ret->type = cfg[2].ival;
629     ret->diff = cfg[3].ival;
630
631     return ret;
632 }
633
634 static char *validate_params(game_params *params, int full)
635 {
636     if (params->type < 0 || params->type >= NUM_GRID_TYPES)
637         return "Illegal grid type";
638     if (params->w < grid_size_limits[params->type].amin ||
639         params->h < grid_size_limits[params->type].amin)
640         return grid_size_limits[params->type].aerr;
641     if (params->w < grid_size_limits[params->type].omin &&
642         params->h < grid_size_limits[params->type].omin)
643         return grid_size_limits[params->type].oerr;
644
645     /*
646      * This shouldn't be able to happen at all, since decode_params
647      * and custom_params will never generate anything that isn't
648      * within range.
649      */
650     assert(params->diff < DIFF_MAX);
651
652     return NULL;
653 }
654
655 /* Returns a newly allocated string describing the current puzzle */
656 static char *state_to_text(const game_state *state)
657 {
658     grid *g = state->game_grid;
659     char *retval;
660     int num_faces = g->num_faces;
661     char *description = snewn(num_faces + 1, char);
662     char *dp = description;
663     int empty_count = 0;
664     int i;
665
666     for (i = 0; i < num_faces; i++) {
667         if (state->clues[i] < 0) {
668             if (empty_count > 25) {
669                 dp += sprintf(dp, "%c", (int)(empty_count + 'a' - 1));
670                 empty_count = 0;
671             }
672             empty_count++;
673         } else {
674             if (empty_count) {
675                 dp += sprintf(dp, "%c", (int)(empty_count + 'a' - 1));
676                 empty_count = 0;
677             }
678             dp += sprintf(dp, "%c", (int)CLUE2CHAR(state->clues[i]));
679         }
680     }
681
682     if (empty_count)
683         dp += sprintf(dp, "%c", (int)(empty_count + 'a' - 1));
684
685     retval = dupstr(description);
686     sfree(description);
687
688     return retval;
689 }
690
691 #define GRID_DESC_SEP '_'
692
693 /* Splits up a (optional) grid_desc from the game desc. Returns the
694  * grid_desc (which needs freeing) and updates the desc pointer to
695  * start of real desc, or returns NULL if no desc. */
696 static char *extract_grid_desc(char **desc)
697 {
698     char *sep = strchr(*desc, GRID_DESC_SEP), *gd;
699     int gd_len;
700
701     if (!sep) return NULL;
702
703     gd_len = sep - (*desc);
704     gd = snewn(gd_len+1, char);
705     memcpy(gd, *desc, gd_len);
706     gd[gd_len] = '\0';
707
708     *desc = sep+1;
709
710     return gd;
711 }
712
713 /* We require that the params pass the test in validate_params and that the
714  * description fills the entire game area */
715 static char *validate_desc(game_params *params, char *desc)
716 {
717     int count = 0;
718     grid *g;
719     char *grid_desc, *ret;
720
721     /* It's pretty inefficient to do this just for validation. All we need to
722      * know is the precise number of faces. */
723     grid_desc = extract_grid_desc(&desc);
724     ret = grid_validate_desc(grid_types[params->type], params->w, params->h, grid_desc);
725     if (ret) return ret;
726
727     g = loopy_generate_grid(params, grid_desc);
728     if (grid_desc) sfree(grid_desc);
729
730     for (; *desc; ++desc) {
731         if ((*desc >= '0' && *desc <= '9') || (*desc >= 'A' && *desc <= 'Z')) {
732             count++;
733             continue;
734         }
735         if (*desc >= 'a') {
736             count += *desc - 'a' + 1;
737             continue;
738         }
739         return "Unknown character in description";
740     }
741
742     if (count < g->num_faces)
743         return "Description too short for board size";
744     if (count > g->num_faces)
745         return "Description too long for board size";
746
747     grid_free(g);
748
749     return NULL;
750 }
751
752 /* Sums the lengths of the numbers in range [0,n) */
753 /* See equivalent function in solo.c for justification of this. */
754 static int len_0_to_n(int n)
755 {
756     int len = 1; /* Counting 0 as a bit of a special case */
757     int i;
758
759     for (i = 1; i < n; i *= 10) {
760         len += max(n - i, 0);
761     }
762
763     return len;
764 }
765
766 static char *encode_solve_move(const game_state *state)
767 {
768     int len;
769     char *ret, *p;
770     int i;
771     int num_edges = state->game_grid->num_edges;
772
773     /* This is going to return a string representing the moves needed to set
774      * every line in a grid to be the same as the ones in 'state'.  The exact
775      * length of this string is predictable. */
776
777     len = 1;  /* Count the 'S' prefix */
778     /* Numbers in all lines */
779     len += len_0_to_n(num_edges);
780     /* For each line we also have a letter */
781     len += num_edges;
782
783     ret = snewn(len + 1, char);
784     p = ret;
785
786     p += sprintf(p, "S");
787
788     for (i = 0; i < num_edges; i++) {
789         switch (state->lines[i]) {
790           case LINE_YES:
791             p += sprintf(p, "%dy", i);
792             break;
793           case LINE_NO:
794             p += sprintf(p, "%dn", i);
795             break;
796         }
797     }
798
799     /* No point in doing sums like that if they're going to be wrong */
800     assert(strlen(ret) <= (size_t)len);
801     return ret;
802 }
803
804 static game_ui *new_ui(game_state *state)
805 {
806     return NULL;
807 }
808
809 static void free_ui(game_ui *ui)
810 {
811 }
812
813 static char *encode_ui(game_ui *ui)
814 {
815     return NULL;
816 }
817
818 static void decode_ui(game_ui *ui, char *encoding)
819 {
820 }
821
822 static void game_changed_state(game_ui *ui, game_state *oldstate,
823                                game_state *newstate)
824 {
825 }
826
827 static void game_compute_size(game_params *params, int tilesize,
828                               int *x, int *y)
829 {
830     int grid_width, grid_height, rendered_width, rendered_height;
831     int g_tilesize;
832
833     grid_compute_size(grid_types[params->type], params->w, params->h,
834                       &g_tilesize, &grid_width, &grid_height);
835
836     /* multiply first to minimise rounding error on integer division */
837     rendered_width = grid_width * tilesize / g_tilesize;
838     rendered_height = grid_height * tilesize / g_tilesize;
839     *x = rendered_width + 2 * BORDER(tilesize) + 1;
840     *y = rendered_height + 2 * BORDER(tilesize) + 1;
841 }
842
843 static void game_set_size(drawing *dr, game_drawstate *ds,
844                           game_params *params, int tilesize)
845 {
846     ds->tilesize = tilesize;
847 }
848
849 static float *game_colours(frontend *fe, int *ncolours)
850 {
851     float *ret = snewn(4 * NCOLOURS, float);
852
853     frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
854
855     ret[COL_FOREGROUND * 3 + 0] = 0.0F;
856     ret[COL_FOREGROUND * 3 + 1] = 0.0F;
857     ret[COL_FOREGROUND * 3 + 2] = 0.0F;
858
859     /*
860      * We want COL_LINEUNKNOWN to be a yellow which is a bit darker
861      * than the background. (I previously set it to 0.8,0.8,0, but
862      * found that this went badly with the 0.8,0.8,0.8 favoured as a
863      * background by the Java frontend.)
864      */
865     ret[COL_LINEUNKNOWN * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
866     ret[COL_LINEUNKNOWN * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 0.9F;
867     ret[COL_LINEUNKNOWN * 3 + 2] = 0.0F;
868
869     ret[COL_HIGHLIGHT * 3 + 0] = 1.0F;
870     ret[COL_HIGHLIGHT * 3 + 1] = 1.0F;
871     ret[COL_HIGHLIGHT * 3 + 2] = 1.0F;
872
873     ret[COL_MISTAKE * 3 + 0] = 1.0F;
874     ret[COL_MISTAKE * 3 + 1] = 0.0F;
875     ret[COL_MISTAKE * 3 + 2] = 0.0F;
876
877     ret[COL_SATISFIED * 3 + 0] = 0.0F;
878     ret[COL_SATISFIED * 3 + 1] = 0.0F;
879     ret[COL_SATISFIED * 3 + 2] = 0.0F;
880
881     /* We want the faint lines to be a bit darker than the background.
882      * Except if the background is pretty dark already; then it ought to be a
883      * bit lighter.  Oy vey.
884      */
885     ret[COL_FAINT * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
886     ret[COL_FAINT * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 0.9F;
887     ret[COL_FAINT * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 0.9F;
888
889     *ncolours = NCOLOURS;
890     return ret;
891 }
892
893 static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
894 {
895     struct game_drawstate *ds = snew(struct game_drawstate);
896     int num_faces = state->game_grid->num_faces;
897     int num_edges = state->game_grid->num_edges;
898     int i;
899
900     ds->tilesize = 0;
901     ds->started = 0;
902     ds->lines = snewn(num_edges, char);
903     ds->clue_error = snewn(num_faces, char);
904     ds->clue_satisfied = snewn(num_faces, char);
905     ds->textx = snewn(num_faces, int);
906     ds->texty = snewn(num_faces, int);
907     ds->flashing = 0;
908
909     memset(ds->lines, LINE_UNKNOWN, num_edges);
910     memset(ds->clue_error, 0, num_faces);
911     memset(ds->clue_satisfied, 0, num_faces);
912     for (i = 0; i < num_faces; i++)
913         ds->textx[i] = ds->texty[i] = -1;
914
915     return ds;
916 }
917
918 static void game_free_drawstate(drawing *dr, game_drawstate *ds)
919 {
920     sfree(ds->clue_error);
921     sfree(ds->clue_satisfied);
922     sfree(ds->lines);
923     sfree(ds);
924 }
925
926 static int game_timing_state(game_state *state, game_ui *ui)
927 {
928     return TRUE;
929 }
930
931 static float game_anim_length(game_state *oldstate, game_state *newstate,
932                               int dir, game_ui *ui)
933 {
934     return 0.0F;
935 }
936
937 static int game_can_format_as_text_now(game_params *params)
938 {
939     if (params->type != 0)
940         return FALSE;
941     return TRUE;
942 }
943
944 static char *game_text_format(game_state *state)
945 {
946     int w, h, W, H;
947     int x, y, i;
948     int cell_size;
949     char *ret;
950     grid *g = state->game_grid;
951     grid_face *f;
952
953     assert(state->grid_type == 0);
954
955     /* Work out the basic size unit */
956     f = g->faces; /* first face */
957     assert(f->order == 4);
958     /* The dots are ordered clockwise, so the two opposite
959      * corners are guaranteed to span the square */
960     cell_size = abs(f->dots[0]->x - f->dots[2]->x);
961
962     w = (g->highest_x - g->lowest_x) / cell_size;
963     h = (g->highest_y - g->lowest_y) / cell_size;
964
965     /* Create a blank "canvas" to "draw" on */
966     W = 2 * w + 2;
967     H = 2 * h + 1;
968     ret = snewn(W * H + 1, char);
969     for (y = 0; y < H; y++) {
970         for (x = 0; x < W-1; x++) {
971             ret[y*W + x] = ' ';
972         }
973         ret[y*W + W-1] = '\n';
974     }
975     ret[H*W] = '\0';
976
977     /* Fill in edge info */
978     for (i = 0; i < g->num_edges; i++) {
979         grid_edge *e = g->edges + i;
980         /* Cell coordinates, from (0,0) to (w-1,h-1) */
981         int x1 = (e->dot1->x - g->lowest_x) / cell_size;
982         int x2 = (e->dot2->x - g->lowest_x) / cell_size;
983         int y1 = (e->dot1->y - g->lowest_y) / cell_size;
984         int y2 = (e->dot2->y - g->lowest_y) / cell_size;
985         /* Midpoint, in canvas coordinates (canvas coordinates are just twice
986          * cell coordinates) */
987         x = x1 + x2;
988         y = y1 + y2;
989         switch (state->lines[i]) {
990           case LINE_YES:
991             ret[y*W + x] = (y1 == y2) ? '-' : '|';
992             break;
993           case LINE_NO:
994             ret[y*W + x] = 'x';
995             break;
996           case LINE_UNKNOWN:
997             break; /* already a space */
998           default:
999             assert(!"Illegal line state");
1000         }
1001     }
1002
1003     /* Fill in clues */
1004     for (i = 0; i < g->num_faces; i++) {
1005         int x1, x2, y1, y2;
1006
1007         f = g->faces + i;
1008         assert(f->order == 4);
1009         /* Cell coordinates, from (0,0) to (w-1,h-1) */
1010         x1 = (f->dots[0]->x - g->lowest_x) / cell_size;
1011         x2 = (f->dots[2]->x - g->lowest_x) / cell_size;
1012         y1 = (f->dots[0]->y - g->lowest_y) / cell_size;
1013         y2 = (f->dots[2]->y - g->lowest_y) / cell_size;
1014         /* Midpoint, in canvas coordinates */
1015         x = x1 + x2;
1016         y = y1 + y2;
1017         ret[y*W + x] = CLUE2CHAR(state->clues[i]);
1018     }
1019     return ret;
1020 }
1021
1022 /* ----------------------------------------------------------------------
1023  * Debug code
1024  */
1025
1026 #ifdef DEBUG_CACHES
1027 static void check_caches(const solver_state* sstate)
1028 {
1029     int i;
1030     const game_state *state = sstate->state;
1031     const grid *g = state->game_grid;
1032
1033     for (i = 0; i < g->num_dots; i++) {
1034         assert(dot_order(state, i, LINE_YES) == sstate->dot_yes_count[i]);
1035         assert(dot_order(state, i, LINE_NO) == sstate->dot_no_count[i]);
1036     }
1037
1038     for (i = 0; i < g->num_faces; i++) {
1039         assert(face_order(state, i, LINE_YES) == sstate->face_yes_count[i]);
1040         assert(face_order(state, i, LINE_NO) == sstate->face_no_count[i]);
1041     }
1042 }
1043
1044 #if 0
1045 #define check_caches(s) \
1046     do { \
1047         fprintf(stderr, "check_caches at line %d\n", __LINE__); \
1048         check_caches(s); \
1049     } while (0)
1050 #endif
1051 #endif /* DEBUG_CACHES */
1052
1053 /* ----------------------------------------------------------------------
1054  * Solver utility functions
1055  */
1056
1057 /* Sets the line (with index i) to the new state 'line_new', and updates
1058  * the cached counts of any affected faces and dots.
1059  * Returns TRUE if this actually changed the line's state. */
1060 static int solver_set_line(solver_state *sstate, int i,
1061                            enum line_state line_new
1062 #ifdef SHOW_WORKING
1063                            , const char *reason
1064 #endif
1065                            )
1066 {
1067     game_state *state = sstate->state;
1068     grid *g;
1069     grid_edge *e;
1070
1071     assert(line_new != LINE_UNKNOWN);
1072
1073     check_caches(sstate);
1074
1075     if (state->lines[i] == line_new) {
1076         return FALSE; /* nothing changed */
1077     }
1078     state->lines[i] = line_new;
1079
1080 #ifdef SHOW_WORKING
1081     fprintf(stderr, "solver: set line [%d] to %s (%s)\n",
1082             i, line_new == LINE_YES ? "YES" : "NO",
1083             reason);
1084 #endif
1085
1086     g = state->game_grid;
1087     e = g->edges + i;
1088
1089     /* Update the cache for both dots and both faces affected by this. */
1090     if (line_new == LINE_YES) {
1091         sstate->dot_yes_count[e->dot1 - g->dots]++;
1092         sstate->dot_yes_count[e->dot2 - g->dots]++;
1093         if (e->face1) {
1094             sstate->face_yes_count[e->face1 - g->faces]++;
1095         }
1096         if (e->face2) {
1097             sstate->face_yes_count[e->face2 - g->faces]++;
1098         }
1099     } else {
1100         sstate->dot_no_count[e->dot1 - g->dots]++;
1101         sstate->dot_no_count[e->dot2 - g->dots]++;
1102         if (e->face1) {
1103             sstate->face_no_count[e->face1 - g->faces]++;
1104         }
1105         if (e->face2) {
1106             sstate->face_no_count[e->face2 - g->faces]++;
1107         }
1108     }
1109
1110     check_caches(sstate);
1111     return TRUE;
1112 }
1113
1114 #ifdef SHOW_WORKING
1115 #define solver_set_line(a, b, c) \
1116     solver_set_line(a, b, c, __FUNCTION__)
1117 #endif
1118
1119 /*
1120  * Merge two dots due to the existence of an edge between them.
1121  * Updates the dsf tracking equivalence classes, and keeps track of
1122  * the length of path each dot is currently a part of.
1123  * Returns TRUE if the dots were already linked, ie if they are part of a
1124  * closed loop, and false otherwise.
1125  */
1126 static int merge_dots(solver_state *sstate, int edge_index)
1127 {
1128     int i, j, len;
1129     grid *g = sstate->state->game_grid;
1130     grid_edge *e = g->edges + edge_index;
1131
1132     i = e->dot1 - g->dots;
1133     j = e->dot2 - g->dots;
1134
1135     i = dsf_canonify(sstate->dotdsf, i);
1136     j = dsf_canonify(sstate->dotdsf, j);
1137
1138     if (i == j) {
1139         return TRUE;
1140     } else {
1141         len = sstate->looplen[i] + sstate->looplen[j];
1142         dsf_merge(sstate->dotdsf, i, j);
1143         i = dsf_canonify(sstate->dotdsf, i);
1144         sstate->looplen[i] = len;
1145         return FALSE;
1146     }
1147 }
1148
1149 /* Merge two lines because the solver has deduced that they must be either
1150  * identical or opposite.   Returns TRUE if this is new information, otherwise
1151  * FALSE. */
1152 static int merge_lines(solver_state *sstate, int i, int j, int inverse
1153 #ifdef SHOW_WORKING
1154                        , const char *reason
1155 #endif
1156                        )
1157 {
1158     int inv_tmp;
1159
1160     assert(i < sstate->state->game_grid->num_edges);
1161     assert(j < sstate->state->game_grid->num_edges);
1162
1163     i = edsf_canonify(sstate->linedsf, i, &inv_tmp);
1164     inverse ^= inv_tmp;
1165     j = edsf_canonify(sstate->linedsf, j, &inv_tmp);
1166     inverse ^= inv_tmp;
1167
1168     edsf_merge(sstate->linedsf, i, j, inverse);
1169
1170 #ifdef SHOW_WORKING
1171     if (i != j) {
1172         fprintf(stderr, "%s [%d] [%d] %s(%s)\n",
1173                 __FUNCTION__, i, j,
1174                 inverse ? "inverse " : "", reason);
1175     }
1176 #endif
1177     return (i != j);
1178 }
1179
1180 #ifdef SHOW_WORKING
1181 #define merge_lines(a, b, c, d) \
1182     merge_lines(a, b, c, d, __FUNCTION__)
1183 #endif
1184
1185 /* Count the number of lines of a particular type currently going into the
1186  * given dot. */
1187 static int dot_order(const game_state* state, int dot, char line_type)
1188 {
1189     int n = 0;
1190     grid *g = state->game_grid;
1191     grid_dot *d = g->dots + dot;
1192     int i;
1193
1194     for (i = 0; i < d->order; i++) {
1195         grid_edge *e = d->edges[i];
1196         if (state->lines[e - g->edges] == line_type)
1197             ++n;
1198     }
1199     return n;
1200 }
1201
1202 /* Count the number of lines of a particular type currently surrounding the
1203  * given face */
1204 static int face_order(const game_state* state, int face, char line_type)
1205 {
1206     int n = 0;
1207     grid *g = state->game_grid;
1208     grid_face *f = g->faces + face;
1209     int i;
1210
1211     for (i = 0; i < f->order; i++) {
1212         grid_edge *e = f->edges[i];
1213         if (state->lines[e - g->edges] == line_type)
1214             ++n;
1215     }
1216     return n;
1217 }
1218
1219 /* Set all lines bordering a dot of type old_type to type new_type
1220  * Return value tells caller whether this function actually did anything */
1221 static int dot_setall(solver_state *sstate, int dot,
1222                       char old_type, char new_type)
1223 {
1224     int retval = FALSE, r;
1225     game_state *state = sstate->state;
1226     grid *g;
1227     grid_dot *d;
1228     int i;
1229
1230     if (old_type == new_type)
1231         return FALSE;
1232
1233     g = state->game_grid;
1234     d = g->dots + dot;
1235
1236     for (i = 0; i < d->order; i++) {
1237         int line_index = d->edges[i] - g->edges;
1238         if (state->lines[line_index] == old_type) {
1239             r = solver_set_line(sstate, line_index, new_type);
1240             assert(r == TRUE);
1241             retval = TRUE;
1242         }
1243     }
1244     return retval;
1245 }
1246
1247 /* Set all lines bordering a face of type old_type to type new_type */
1248 static int face_setall(solver_state *sstate, int face,
1249                        char old_type, char new_type)
1250 {
1251     int retval = FALSE, r;
1252     game_state *state = sstate->state;
1253     grid *g;
1254     grid_face *f;
1255     int i;
1256
1257     if (old_type == new_type)
1258         return FALSE;
1259
1260     g = state->game_grid;
1261     f = g->faces + face;
1262
1263     for (i = 0; i < f->order; i++) {
1264         int line_index = f->edges[i] - g->edges;
1265         if (state->lines[line_index] == old_type) {
1266             r = solver_set_line(sstate, line_index, new_type);
1267             assert(r == TRUE);
1268             retval = TRUE;
1269         }
1270     }
1271     return retval;
1272 }
1273
1274 /* ----------------------------------------------------------------------
1275  * Loop generation and clue removal
1276  */
1277
1278 /* We're going to store lists of current candidate faces for colouring black
1279  * or white.
1280  * Each face gets a 'score', which tells us how adding that face right
1281  * now would affect the curliness of the solution loop.  We're trying to
1282  * maximise that quantity so will bias our random selection of faces to
1283  * colour those with high scores */
1284 struct face_score {
1285     int white_score;
1286     int black_score;
1287     unsigned long random;
1288     /* No need to store a grid_face* here.  The 'face_scores' array will
1289      * be a list of 'face_score' objects, one for each face of the grid, so
1290      * the position (index) within the 'face_scores' array will determine
1291      * which face corresponds to a particular face_score.
1292      * Having a single 'face_scores' array for all faces simplifies memory
1293      * management, and probably improves performance, because we don't have to 
1294      * malloc/free each individual face_score, and we don't have to maintain
1295      * a mapping from grid_face* pointers to face_score* pointers.
1296      */
1297 };
1298
1299 static int generic_sort_cmpfn(void *v1, void *v2, size_t offset)
1300 {
1301     struct face_score *f1 = v1;
1302     struct face_score *f2 = v2;
1303     int r;
1304
1305     r = *(int *)((char *)f2 + offset) - *(int *)((char *)f1 + offset);
1306     if (r) {
1307         return r;
1308     }
1309
1310     if (f1->random < f2->random)
1311         return -1;
1312     else if (f1->random > f2->random)
1313         return 1;
1314
1315     /*
1316      * It's _just_ possible that two faces might have been given
1317      * the same random value. In that situation, fall back to
1318      * comparing based on the positions within the face_scores list.
1319      * This introduces a tiny directional bias, but not a significant one.
1320      */
1321     return f1 - f2;
1322 }
1323
1324 static int white_sort_cmpfn(void *v1, void *v2)
1325 {
1326     return generic_sort_cmpfn(v1, v2, offsetof(struct face_score,white_score));
1327 }
1328
1329 static int black_sort_cmpfn(void *v1, void *v2)
1330 {
1331     return generic_sort_cmpfn(v1, v2, offsetof(struct face_score,black_score));
1332 }
1333
1334 enum face_colour { FACE_WHITE, FACE_GREY, FACE_BLACK };
1335
1336 /* face should be of type grid_face* here. */
1337 #define FACE_COLOUR(face) \
1338     ( (face) == NULL ? FACE_BLACK : \
1339           board[(face) - g->faces] )
1340
1341 /* 'board' is an array of these enums, indicating which faces are
1342  * currently black/white/grey.  'colour' is FACE_WHITE or FACE_BLACK.
1343  * Returns whether it's legal to colour the given face with this colour. */
1344 static int can_colour_face(grid *g, char* board, int face_index,
1345                            enum face_colour colour)
1346 {
1347     int i, j;
1348     grid_face *test_face = g->faces + face_index;
1349     grid_face *starting_face, *current_face;
1350     grid_dot *starting_dot;
1351     int transitions;
1352     int current_state, s; /* booleans: equal or not-equal to 'colour' */
1353     int found_same_coloured_neighbour = FALSE;
1354     assert(board[face_index] != colour);
1355
1356     /* Can only consider a face for colouring if it's adjacent to a face
1357      * with the same colour. */
1358     for (i = 0; i < test_face->order; i++) {
1359         grid_edge *e = test_face->edges[i];
1360         grid_face *f = (e->face1 == test_face) ? e->face2 : e->face1;
1361         if (FACE_COLOUR(f) == colour) {
1362             found_same_coloured_neighbour = TRUE;
1363             break;
1364         }
1365     }
1366     if (!found_same_coloured_neighbour)
1367         return FALSE;
1368
1369     /* Need to avoid creating a loop of faces of this colour around some
1370      * differently-coloured faces.
1371      * Also need to avoid meeting a same-coloured face at a corner, with
1372      * other-coloured faces in between.  Here's a simple test that (I believe)
1373      * takes care of both these conditions:
1374      *
1375      * Take the circular path formed by this face's edges, and inflate it
1376      * slightly outwards.  Imagine walking around this path and consider
1377      * the faces that you visit in sequence.  This will include all faces
1378      * touching the given face, either along an edge or just at a corner.
1379      * Count the number of 'colour'/not-'colour' transitions you encounter, as
1380      * you walk along the complete loop.  This will obviously turn out to be
1381      * an even number.
1382      * If 0, we're either in the middle of an "island" of this colour (should
1383      * be impossible as we're not supposed to create black or white loops),
1384      * or we're about to start a new island - also not allowed.
1385      * If 4 or greater, there are too many separate coloured regions touching
1386      * this face, and colouring it would create a loop or a corner-violation.
1387      * The only allowed case is when the count is exactly 2. */
1388
1389     /* i points to a dot around the test face.
1390      * j points to a face around the i^th dot.
1391      * The current face will always be:
1392      *     test_face->dots[i]->faces[j]
1393      * We assume dots go clockwise around the test face,
1394      * and faces go clockwise around dots. */
1395
1396     /*
1397      * The end condition is slightly fiddly. In sufficiently strange
1398      * degenerate grids, our test face may be adjacent to the same
1399      * other face multiple times (typically if it's the exterior
1400      * face). Consider this, in particular:
1401      * 
1402      *   +--+
1403      *   |  |
1404      *   +--+--+
1405      *   |  |  |
1406      *   +--+--+
1407      * 
1408      * The bottom left face there is adjacent to the exterior face
1409      * twice, so we can't just terminate our iteration when we reach
1410      * the same _face_ we started at. Furthermore, we can't
1411      * condition on having the same (i,j) pair either, because
1412      * several (i,j) pairs identify the bottom left contiguity with
1413      * the exterior face! We canonicalise the (i,j) pair by taking
1414      * one step around before we set the termination tracking.
1415      */
1416
1417     i = j = 0;
1418     current_face = test_face->dots[0]->faces[0];
1419     if (current_face == test_face) {
1420         j = 1;
1421         current_face = test_face->dots[0]->faces[1];
1422     }
1423     transitions = 0;
1424     current_state = (FACE_COLOUR(current_face) == colour);
1425     starting_dot = NULL;
1426     starting_face = NULL;
1427     while (TRUE) {
1428         /* Advance to next face.
1429          * Need to loop here because it might take several goes to
1430          * find it. */
1431         while (TRUE) {
1432             j++;
1433             if (j == test_face->dots[i]->order)
1434                 j = 0;
1435
1436             if (test_face->dots[i]->faces[j] == test_face) {
1437                 /* Advance to next dot round test_face, then
1438                  * find current_face around new dot
1439                  * and advance to the next face clockwise */
1440                 i++;
1441                 if (i == test_face->order)
1442                     i = 0;
1443                 for (j = 0; j < test_face->dots[i]->order; j++) {
1444                     if (test_face->dots[i]->faces[j] == current_face)
1445                         break;
1446                 }
1447                 /* Must actually find current_face around new dot,
1448                  * or else something's wrong with the grid. */
1449                 assert(j != test_face->dots[i]->order);
1450                 /* Found, so advance to next face and try again */
1451             } else {
1452                 break;
1453             }
1454         }
1455         /* (i,j) are now advanced to next face */
1456         current_face = test_face->dots[i]->faces[j];
1457         s = (FACE_COLOUR(current_face) == colour);
1458         if (!starting_dot) {
1459             starting_dot = test_face->dots[i];
1460             starting_face = current_face;
1461             current_state = s;
1462         } else {
1463             if (s != current_state) {
1464                 ++transitions;
1465                 current_state = s;
1466                 if (transitions > 2)
1467                     break;
1468             }
1469             if (test_face->dots[i] == starting_dot &&
1470                 current_face == starting_face)
1471                 break;
1472         }
1473     }
1474
1475     return (transitions == 2) ? TRUE : FALSE;
1476 }
1477
1478 /* Count the number of neighbours of 'face', having colour 'colour' */
1479 static int face_num_neighbours(grid *g, char *board, grid_face *face,
1480                                enum face_colour colour)
1481 {
1482     int colour_count = 0;
1483     int i;
1484     grid_face *f;
1485     grid_edge *e;
1486     for (i = 0; i < face->order; i++) {
1487         e = face->edges[i];
1488         f = (e->face1 == face) ? e->face2 : e->face1;
1489         if (FACE_COLOUR(f) == colour)
1490             ++colour_count;
1491     }
1492     return colour_count;
1493 }
1494
1495 /* The 'score' of a face reflects its current desirability for selection
1496  * as the next face to colour white or black.  We want to encourage moving
1497  * into grey areas and increasing loopiness, so we give scores according to
1498  * how many of the face's neighbours are currently coloured the same as the
1499  * proposed colour. */
1500 static int face_score(grid *g, char *board, grid_face *face,
1501                       enum face_colour colour)
1502 {
1503     /* Simple formula: score = 0 - num. same-coloured neighbours,
1504      * so a higher score means fewer same-coloured neighbours. */
1505     return -face_num_neighbours(g, board, face, colour);
1506 }
1507
1508 /* Generate a new complete set of clues for the given game_state.
1509  * The method is to generate a WHITE/BLACK colouring of all the faces,
1510  * such that the WHITE faces will define the inside of the path, and the
1511  * BLACK faces define the outside.
1512  * To do this, we initially colour all faces GREY.  The infinite space outside
1513  * the grid is coloured BLACK, and we choose a random face to colour WHITE.
1514  * Then we gradually grow the BLACK and the WHITE regions, eliminating GREY
1515  * faces, until the grid is filled with BLACK/WHITE.  As we grow the regions,
1516  * we avoid creating loops of a single colour, to preserve the topological
1517  * shape of the WHITE and BLACK regions.
1518  * We also try to make the boundary as loopy and twisty as possible, to avoid
1519  * generating paths that are uninteresting.
1520  * The algorithm works by choosing a BLACK/WHITE colour, then choosing a GREY
1521  * face that can be coloured with that colour (without violating the
1522  * topological shape of that region).  It's not obvious, but I think this
1523  * algorithm is guaranteed to terminate without leaving any GREY faces behind.
1524  * Indeed, if there are any GREY faces at all, both the WHITE and BLACK
1525  * regions can be grown.
1526  * This is checked using assert()ions, and I haven't seen any failures yet.
1527  *
1528  * Hand-wavy proof: imagine what can go wrong...
1529  *
1530  * Could the white faces get completely cut off by the black faces, and still
1531  * leave some grey faces remaining?
1532  * No, because then the black faces would form a loop around both the white
1533  * faces and the grey faces, which is disallowed because we continually
1534  * maintain the correct topological shape of the black region.
1535  * Similarly, the black faces can never get cut off by the white faces.  That
1536  * means both the WHITE and BLACK regions always have some room to grow into
1537  * the GREY regions.
1538  * Could it be that we can't colour some GREY face, because there are too many
1539  * WHITE/BLACK transitions as we walk round the face? (see the
1540  * can_colour_face() function for details)
1541  * No.  Imagine otherwise, and we see WHITE/BLACK/WHITE/BLACK as we walk
1542  * around the face.  The two WHITE faces would be connected by a WHITE path,
1543  * and the BLACK faces would be connected by a BLACK path.  These paths would
1544  * have to cross, which is impossible.
1545  * Another thing that could go wrong: perhaps we can't find any GREY face to
1546  * colour WHITE, because it would create a loop-violation or a corner-violation
1547  * with the other WHITE faces?
1548  * This is a little bit tricky to prove impossible.  Imagine you have such a
1549  * GREY face (that is, if you coloured it WHITE, you would create a WHITE loop
1550  * or corner violation).
1551  * That would cut all the non-white area into two blobs.  One of those blobs
1552  * must be free of BLACK faces (because the BLACK stuff is a connected blob).
1553  * So we have a connected GREY area, completely surrounded by WHITE
1554  * (including the GREY face we've tentatively coloured WHITE).
1555  * A well-known result in graph theory says that you can always find a GREY
1556  * face whose removal leaves the remaining GREY area connected.  And it says
1557  * there are at least two such faces, so we can always choose the one that
1558  * isn't the "tentative" GREY face.  Colouring that face WHITE leaves
1559  * everything nice and connected, including that "tentative" GREY face which
1560  * acts as a gateway to the rest of the non-WHITE grid.
1561  */
1562 static void add_full_clues(game_state *state, random_state *rs)
1563 {
1564     signed char *clues = state->clues;
1565     char *board;
1566     grid *g = state->game_grid;
1567     int i, j;
1568     int num_faces = g->num_faces;
1569     struct face_score *face_scores; /* Array of face_score objects */
1570     struct face_score *fs; /* Points somewhere in the above list */
1571     struct grid_face *cur_face;
1572     tree234 *lightable_faces_sorted;
1573     tree234 *darkable_faces_sorted;
1574     int *face_list;
1575     int do_random_pass;
1576
1577     board = snewn(num_faces, char);
1578
1579     /* Make a board */
1580     memset(board, FACE_GREY, num_faces);
1581     
1582     /* Create and initialise the list of face_scores */
1583     face_scores = snewn(num_faces, struct face_score);
1584     for (i = 0; i < num_faces; i++) {
1585         face_scores[i].random = random_bits(rs, 31);
1586         face_scores[i].black_score = face_scores[i].white_score = 0;
1587     }
1588     
1589     /* Colour a random, finite face white.  The infinite face is implicitly
1590      * coloured black.  Together, they will seed the random growth process
1591      * for the black and white areas. */
1592     i = random_upto(rs, num_faces);
1593     board[i] = FACE_WHITE;
1594
1595     /* We need a way of favouring faces that will increase our loopiness.
1596      * We do this by maintaining a list of all candidate faces sorted by
1597      * their score and choose randomly from that with appropriate skew.
1598      * In order to avoid consistently biasing towards particular faces, we
1599      * need the sort order _within_ each group of scores to be completely
1600      * random.  But it would be abusing the hospitality of the tree234 data
1601      * structure if our comparison function were nondeterministic :-).  So with
1602      * each face we associate a random number that does not change during a
1603      * particular run of the generator, and use that as a secondary sort key.
1604      * Yes, this means we will be biased towards particular random faces in
1605      * any one run but that doesn't actually matter. */
1606
1607     lightable_faces_sorted = newtree234(white_sort_cmpfn);
1608     darkable_faces_sorted = newtree234(black_sort_cmpfn);
1609
1610     /* Initialise the lists of lightable and darkable faces.  This is
1611      * slightly different from the code inside the while-loop, because we need
1612      * to check every face of the board (the grid structure does not keep a
1613      * list of the infinite face's neighbours). */
1614     for (i = 0; i < num_faces; i++) {
1615         grid_face *f = g->faces + i;
1616         struct face_score *fs = face_scores + i;
1617         if (board[i] != FACE_GREY) continue;
1618         /* We need the full colourability check here, it's not enough simply
1619          * to check neighbourhood.  On some grids, a neighbour of the infinite
1620          * face is not necessarily darkable. */
1621         if (can_colour_face(g, board, i, FACE_BLACK)) {
1622             fs->black_score = face_score(g, board, f, FACE_BLACK);
1623             add234(darkable_faces_sorted, fs);
1624         }
1625         if (can_colour_face(g, board, i, FACE_WHITE)) {
1626             fs->white_score = face_score(g, board, f, FACE_WHITE);
1627             add234(lightable_faces_sorted, fs);
1628         }
1629     }
1630
1631     /* Colour faces one at a time until no more faces are colourable. */
1632     while (TRUE)
1633     {
1634         enum face_colour colour;
1635         struct face_score *fs_white, *fs_black;
1636         int c_lightable = count234(lightable_faces_sorted);
1637         int c_darkable = count234(darkable_faces_sorted);
1638         if (c_lightable == 0 && c_darkable == 0) {
1639             /* No more faces we can use at all. */
1640             break;
1641         }
1642         assert(c_lightable != 0 && c_darkable != 0);
1643
1644         fs_white = (struct face_score *)index234(lightable_faces_sorted, 0);
1645         fs_black = (struct face_score *)index234(darkable_faces_sorted, 0);
1646
1647         /* Choose a colour, and colour the best available face
1648          * with that colour. */
1649         colour = random_upto(rs, 2) ? FACE_WHITE : FACE_BLACK;
1650
1651         if (colour == FACE_WHITE)
1652             fs = fs_white;
1653         else
1654             fs = fs_black;
1655         assert(fs);
1656         i = fs - face_scores;
1657         assert(board[i] == FACE_GREY);
1658         board[i] = colour;
1659
1660         /* Remove this newly-coloured face from the lists.  These lists should
1661          * only contain grey faces. */
1662         del234(lightable_faces_sorted, fs);
1663         del234(darkable_faces_sorted, fs);
1664
1665         /* Remember which face we've just coloured */
1666         cur_face = g->faces + i;
1667
1668         /* The face we've just coloured potentially affects the colourability
1669          * and the scores of any neighbouring faces (touching at a corner or
1670          * edge).  So the search needs to be conducted around all faces
1671          * touching the one we've just lit.  Iterate over its corners, then
1672          * over each corner's faces.  For each such face, we remove it from
1673          * the lists, recalculate any scores, then add it back to the lists
1674          * (depending on whether it is lightable, darkable or both). */
1675         for (i = 0; i < cur_face->order; i++) {
1676             grid_dot *d = cur_face->dots[i];
1677             for (j = 0; j < d->order; j++) {
1678                 grid_face *f = d->faces[j];
1679                 int fi; /* face index of f */
1680
1681                 if (f == NULL)
1682                     continue;
1683                 if (f == cur_face)
1684                     continue;
1685                 
1686                 /* If the face is already coloured, it won't be on our
1687                  * lightable/darkable lists anyway, so we can skip it without 
1688                  * bothering with the removal step. */
1689                 if (FACE_COLOUR(f) != FACE_GREY) continue; 
1690
1691                 /* Find the face index and face_score* corresponding to f */
1692                 fi = f - g->faces;                
1693                 fs = face_scores + fi;
1694
1695                 /* Remove from lightable list if it's in there.  We do this,
1696                  * even if it is still lightable, because the score might
1697                  * be different, and we need to remove-then-add to maintain
1698                  * correct sort order. */
1699                 del234(lightable_faces_sorted, fs);
1700                 if (can_colour_face(g, board, fi, FACE_WHITE)) {
1701                     fs->white_score = face_score(g, board, f, FACE_WHITE);
1702                     add234(lightable_faces_sorted, fs);
1703                 }
1704                 /* Do the same for darkable list. */
1705                 del234(darkable_faces_sorted, fs);
1706                 if (can_colour_face(g, board, fi, FACE_BLACK)) {
1707                     fs->black_score = face_score(g, board, f, FACE_BLACK);
1708                     add234(darkable_faces_sorted, fs);
1709                 }
1710             }
1711         }
1712     }
1713
1714     /* Clean up */
1715     freetree234(lightable_faces_sorted);
1716     freetree234(darkable_faces_sorted);
1717     sfree(face_scores);
1718
1719     /* The next step requires a shuffled list of all faces */
1720     face_list = snewn(num_faces, int);
1721     for (i = 0; i < num_faces; ++i) {
1722         face_list[i] = i;
1723     }
1724     shuffle(face_list, num_faces, sizeof(int), rs);
1725
1726     /* The above loop-generation algorithm can often leave large clumps
1727      * of faces of one colour.  In extreme cases, the resulting path can be 
1728      * degenerate and not very satisfying to solve.
1729      * This next step alleviates this problem:
1730      * Go through the shuffled list, and flip the colour of any face we can
1731      * legally flip, and which is adjacent to only one face of the opposite
1732      * colour - this tends to grow 'tendrils' into any clumps.
1733      * Repeat until we can find no more faces to flip.  This will
1734      * eventually terminate, because each flip increases the loop's
1735      * perimeter, which cannot increase for ever.
1736      * The resulting path will have maximal loopiness (in the sense that it
1737      * cannot be improved "locally".  Unfortunately, this allows a player to
1738      * make some illicit deductions.  To combat this (and make the path more
1739      * interesting), we do one final pass making random flips. */
1740
1741     /* Set to TRUE for final pass */
1742     do_random_pass = FALSE;
1743
1744     while (TRUE) {
1745         /* Remember whether a flip occurred during this pass */
1746         int flipped = FALSE;
1747
1748         for (i = 0; i < num_faces; ++i) {
1749             int j = face_list[i];
1750             enum face_colour opp =
1751                 (board[j] == FACE_WHITE) ? FACE_BLACK : FACE_WHITE;
1752             if (can_colour_face(g, board, j, opp)) {
1753                 grid_face *face = g->faces +j;
1754                 if (do_random_pass) {
1755                     /* final random pass */
1756                     if (!random_upto(rs, 10))
1757                         board[j] = opp;
1758                 } else {
1759                     /* normal pass - flip when neighbour count is 1 */
1760                     if (face_num_neighbours(g, board, face, opp) == 1) {
1761                         board[j] = opp;
1762                         flipped = TRUE;
1763                     }
1764                 }
1765             }
1766         }
1767
1768         if (do_random_pass) break;
1769         if (!flipped) do_random_pass = TRUE;
1770      }
1771
1772     sfree(face_list);
1773
1774     /* Fill out all the clues by initialising to 0, then iterating over
1775      * all edges and incrementing each clue as we find edges that border
1776      * between BLACK/WHITE faces.  While we're at it, we verify that the
1777      * algorithm does work, and there aren't any GREY faces still there. */
1778     memset(clues, 0, num_faces);
1779     for (i = 0; i < g->num_edges; i++) {
1780         grid_edge *e = g->edges + i;
1781         grid_face *f1 = e->face1;
1782         grid_face *f2 = e->face2;
1783         enum face_colour c1 = FACE_COLOUR(f1);
1784         enum face_colour c2 = FACE_COLOUR(f2);
1785         assert(c1 != FACE_GREY);
1786         assert(c2 != FACE_GREY);
1787         if (c1 != c2) {
1788             if (f1) clues[f1 - g->faces]++;
1789             if (f2) clues[f2 - g->faces]++;
1790         }
1791     }
1792
1793     sfree(board);
1794 }
1795
1796
1797 static int game_has_unique_soln(const game_state *state, int diff)
1798 {
1799     int ret;
1800     solver_state *sstate_new;
1801     solver_state *sstate = new_solver_state((game_state *)state, diff);
1802
1803     sstate_new = solve_game_rec(sstate);
1804
1805     assert(sstate_new->solver_status != SOLVER_MISTAKE);
1806     ret = (sstate_new->solver_status == SOLVER_SOLVED);
1807
1808     free_solver_state(sstate_new);
1809     free_solver_state(sstate);
1810
1811     return ret;
1812 }
1813
1814
1815 /* Remove clues one at a time at random. */
1816 static game_state *remove_clues(game_state *state, random_state *rs,
1817                                 int diff)
1818 {
1819     int *face_list;
1820     int num_faces = state->game_grid->num_faces;
1821     game_state *ret = dup_game(state), *saved_ret;
1822     int n;
1823
1824     /* We need to remove some clues.  We'll do this by forming a list of all
1825      * available clues, shuffling it, then going along one at a
1826      * time clearing each clue in turn for which doing so doesn't render the
1827      * board unsolvable. */
1828     face_list = snewn(num_faces, int);
1829     for (n = 0; n < num_faces; ++n) {
1830         face_list[n] = n;
1831     }
1832
1833     shuffle(face_list, num_faces, sizeof(int), rs);
1834
1835     for (n = 0; n < num_faces; ++n) {
1836         saved_ret = dup_game(ret);
1837         ret->clues[face_list[n]] = -1;
1838
1839         if (game_has_unique_soln(ret, diff)) {
1840             free_game(saved_ret);
1841         } else {
1842             free_game(ret);
1843             ret = saved_ret;
1844         }
1845     }
1846     sfree(face_list);
1847
1848     return ret;
1849 }
1850
1851
1852 static char *new_game_desc(game_params *params, random_state *rs,
1853                            char **aux, int interactive)
1854 {
1855     /* solution and description both use run-length encoding in obvious ways */
1856     char *retval, *game_desc, *grid_desc;
1857     grid *g;
1858     game_state *state = snew(game_state);
1859     game_state *state_new;
1860
1861     grid_desc = grid_new_desc(grid_types[params->type], params->w, params->h, rs);
1862     state->game_grid = g = loopy_generate_grid(params, grid_desc);
1863
1864     state->clues = snewn(g->num_faces, signed char);
1865     state->lines = snewn(g->num_edges, char);
1866     state->line_errors = snewn(g->num_edges, unsigned char);
1867
1868     state->grid_type = params->type;
1869
1870     newboard_please:
1871
1872     memset(state->lines, LINE_UNKNOWN, g->num_edges);
1873     memset(state->line_errors, 0, g->num_edges);
1874
1875     state->solved = state->cheated = FALSE;
1876
1877     /* Get a new random solvable board with all its clues filled in.  Yes, this
1878      * can loop for ever if the params are suitably unfavourable, but
1879      * preventing games smaller than 4x4 seems to stop this happening */
1880     do {
1881         add_full_clues(state, rs);
1882     } while (!game_has_unique_soln(state, params->diff));
1883
1884     state_new = remove_clues(state, rs, params->diff);
1885     free_game(state);
1886     state = state_new;
1887
1888
1889     if (params->diff > 0 && game_has_unique_soln(state, params->diff-1)) {
1890 #ifdef SHOW_WORKING
1891         fprintf(stderr, "Rejecting board, it is too easy\n");
1892 #endif
1893         goto newboard_please;
1894     }
1895
1896     game_desc = state_to_text(state);
1897
1898     free_game(state);
1899
1900     if (grid_desc) {
1901         retval = snewn(strlen(grid_desc) + 1 + strlen(game_desc) + 1, char);
1902         sprintf(retval, "%s%c%s", grid_desc, GRID_DESC_SEP, game_desc);
1903         sfree(grid_desc);
1904         sfree(game_desc);
1905     } else {
1906         retval = game_desc;
1907     }
1908
1909     assert(!validate_desc(params, retval));
1910
1911     return retval;
1912 }
1913
1914 static game_state *new_game(midend *me, game_params *params, char *desc)
1915 {
1916     int i;
1917     game_state *state = snew(game_state);
1918     int empties_to_make = 0;
1919     int n,n2;
1920     const char *dp;
1921     char *grid_desc;
1922     grid *g;
1923     int num_faces, num_edges;
1924
1925     grid_desc = extract_grid_desc(&desc);
1926     state->game_grid = g = loopy_generate_grid(params, grid_desc);
1927     if (grid_desc) sfree(grid_desc);
1928
1929     dp = desc;
1930
1931     num_faces = g->num_faces;
1932     num_edges = g->num_edges;
1933
1934     state->clues = snewn(num_faces, signed char);
1935     state->lines = snewn(num_edges, char);
1936     state->line_errors = snewn(num_edges, unsigned char);
1937
1938     state->solved = state->cheated = FALSE;
1939
1940     state->grid_type = params->type;
1941
1942     for (i = 0; i < num_faces; i++) {
1943         if (empties_to_make) {
1944             empties_to_make--;
1945             state->clues[i] = -1;
1946             continue;
1947         }
1948
1949         assert(*dp);
1950         n = *dp - '0';
1951         n2 = *dp - 'A' + 10;
1952         if (n >= 0 && n < 10) {
1953             state->clues[i] = n;
1954         } else if (n2 >= 10 && n2 < 36) {
1955             state->clues[i] = n2;
1956         } else {
1957             n = *dp - 'a' + 1;
1958             assert(n > 0);
1959             state->clues[i] = -1;
1960             empties_to_make = n - 1;
1961         }
1962         ++dp;
1963     }
1964
1965     memset(state->lines, LINE_UNKNOWN, num_edges);
1966     memset(state->line_errors, 0, num_edges);
1967     return state;
1968 }
1969
1970 /* Calculates the line_errors data, and checks if the current state is a
1971  * solution */
1972 static int check_completion(game_state *state)
1973 {
1974     grid *g = state->game_grid;
1975     int *dsf;
1976     int num_faces = g->num_faces;
1977     int i;
1978     int infinite_area, finite_area;
1979     int loops_found = 0;
1980     int found_edge_not_in_loop = FALSE;
1981
1982     memset(state->line_errors, 0, g->num_edges);
1983
1984     /* LL implementation of SGT's idea:
1985      * A loop will partition the grid into an inside and an outside.
1986      * If there is more than one loop, the grid will be partitioned into
1987      * even more distinct regions.  We can therefore track equivalence of
1988      * faces, by saying that two faces are equivalent when there is a non-YES
1989      * edge between them.
1990      * We could keep track of the number of connected components, by counting
1991      * the number of dsf-merges that aren't no-ops.
1992      * But we're only interested in 3 separate cases:
1993      * no loops, one loop, more than one loop.
1994      *
1995      * No loops: all faces are equivalent to the infinite face.
1996      * One loop: only two equivalence classes - finite and infinite.
1997      * >= 2 loops: there are 2 distinct finite regions.
1998      *
1999      * So we simply make two passes through all the edges.
2000      * In the first pass, we dsf-merge the two faces bordering each non-YES
2001      * edge.
2002      * In the second pass, we look for YES-edges bordering:
2003      * a) two non-equivalent faces.
2004      * b) two non-equivalent faces, and one of them is part of a different
2005      *    finite area from the first finite area we've seen.
2006      *
2007      * An occurrence of a) means there is at least one loop.
2008      * An occurrence of b) means there is more than one loop.
2009      * Edges satisfying a) are marked as errors.
2010      *
2011      * While we're at it, we set a flag if we find a YES edge that is not
2012      * part of a loop.
2013      * This information will help decide, if there's a single loop, whether it
2014      * is a candidate for being a solution (that is, all YES edges are part of
2015      * this loop).
2016      *
2017      * If there is a candidate loop, we then go through all clues and check
2018      * they are all satisfied.  If so, we have found a solution and we can
2019      * unmark all line_errors.
2020      */
2021     
2022     /* Infinite face is at the end - its index is num_faces.
2023      * This macro is just to make this obvious! */
2024     #define INF_FACE num_faces
2025     dsf = snewn(num_faces + 1, int);
2026     dsf_init(dsf, num_faces + 1);
2027     
2028     /* First pass */
2029     for (i = 0; i < g->num_edges; i++) {
2030         grid_edge *e = g->edges + i;
2031         int f1 = e->face1 ? e->face1 - g->faces : INF_FACE;
2032         int f2 = e->face2 ? e->face2 - g->faces : INF_FACE;
2033         if (state->lines[i] != LINE_YES)
2034             dsf_merge(dsf, f1, f2);
2035     }
2036     
2037     /* Second pass */
2038     infinite_area = dsf_canonify(dsf, INF_FACE);
2039     finite_area = -1;
2040     for (i = 0; i < g->num_edges; i++) {
2041         grid_edge *e = g->edges + i;
2042         int f1 = e->face1 ? e->face1 - g->faces : INF_FACE;
2043         int can1 = dsf_canonify(dsf, f1);
2044         int f2 = e->face2 ? e->face2 - g->faces : INF_FACE;
2045         int can2 = dsf_canonify(dsf, f2);
2046         if (state->lines[i] != LINE_YES) continue;
2047
2048         if (can1 == can2) {
2049             /* Faces are equivalent, so this edge not part of a loop */
2050             found_edge_not_in_loop = TRUE;
2051             continue;
2052         }
2053         state->line_errors[i] = TRUE;
2054         if (loops_found == 0) loops_found = 1;
2055
2056         /* Don't bother with further checks if we've already found 2 loops */
2057         if (loops_found == 2) continue;
2058
2059         if (finite_area == -1) {
2060             /* Found our first finite area */
2061             if (can1 != infinite_area)
2062                 finite_area = can1;
2063             else
2064                 finite_area = can2;
2065         }
2066
2067         /* Have we found a second area? */
2068         if (finite_area != -1) {
2069             if (can1 != infinite_area && can1 != finite_area) {
2070                 loops_found = 2;
2071                 continue;
2072             }
2073             if (can2 != infinite_area && can2 != finite_area) {
2074                 loops_found = 2;
2075             }
2076         }
2077     }
2078
2079 /*
2080     printf("loops_found = %d\n", loops_found);
2081     printf("found_edge_not_in_loop = %s\n",
2082         found_edge_not_in_loop ? "TRUE" : "FALSE");
2083 */
2084
2085     sfree(dsf); /* No longer need the dsf */
2086     
2087     /* Have we found a candidate loop? */
2088     if (loops_found == 1 && !found_edge_not_in_loop) {
2089         /* Yes, so check all clues are satisfied */
2090         int found_clue_violation = FALSE;
2091         for (i = 0; i < num_faces; i++) {
2092             int c = state->clues[i];
2093             if (c >= 0) {
2094                 if (face_order(state, i, LINE_YES) != c) {
2095                     found_clue_violation = TRUE;
2096                     break;
2097                 }
2098             }
2099         }
2100         
2101         if (!found_clue_violation) {
2102             /* The loop is good */
2103             memset(state->line_errors, 0, g->num_edges);
2104             return TRUE; /* No need to bother checking for dot violations */
2105         }
2106     }
2107
2108     /* Check for dot violations */
2109     for (i = 0; i < g->num_dots; i++) {
2110         int yes = dot_order(state, i, LINE_YES);
2111         int unknown = dot_order(state, i, LINE_UNKNOWN);
2112         if ((yes == 1 && unknown == 0) || (yes >= 3)) {
2113             /* violation, so mark all YES edges as errors */
2114             grid_dot *d = g->dots + i;
2115             int j;
2116             for (j = 0; j < d->order; j++) {
2117                 int e = d->edges[j] - g->edges;
2118                 if (state->lines[e] == LINE_YES)
2119                     state->line_errors[e] = TRUE;
2120             }
2121         }
2122     }
2123     return FALSE;
2124 }
2125
2126 /* ----------------------------------------------------------------------
2127  * Solver logic
2128  *
2129  * Our solver modes operate as follows.  Each mode also uses the modes above it.
2130  *
2131  *   Easy Mode
2132  *   Just implement the rules of the game.
2133  *
2134  *   Normal and Tricky Modes
2135  *   For each (adjacent) pair of lines through each dot we store a bit for
2136  *   whether at least one of them is on and whether at most one is on.  (If we
2137  *   know both or neither is on that's already stored more directly.)
2138  *
2139  *   Advanced Mode
2140  *   Use edsf data structure to make equivalence classes of lines that are
2141  *   known identical to or opposite to one another.
2142  */
2143
2144
2145 /* DLines:
2146  * For general grids, we consider "dlines" to be pairs of lines joined
2147  * at a dot.  The lines must be adjacent around the dot, so we can think of
2148  * a dline as being a dot+face combination.  Or, a dot+edge combination where
2149  * the second edge is taken to be the next clockwise edge from the dot.
2150  * Original loopy code didn't have this extra restriction of the lines being
2151  * adjacent.  From my tests with square grids, this extra restriction seems to
2152  * take little, if anything, away from the quality of the puzzles.
2153  * A dline can be uniquely identified by an edge/dot combination, given that
2154  * a dline-pair always goes clockwise around its common dot.  The edge/dot
2155  * combination can be represented by an edge/bool combination - if bool is
2156  * TRUE, use edge->dot1 else use edge->dot2.  So the total number of dlines is
2157  * exactly twice the number of edges in the grid - although the dlines
2158  * spanning the infinite face are not all that useful to the solver.
2159  * Note that, by convention, a dline goes clockwise around its common dot,
2160  * which means the dline goes anti-clockwise around its common face.
2161  */
2162
2163 /* Helper functions for obtaining an index into an array of dlines, given
2164  * various information.  We assume the grid layout conventions about how
2165  * the various lists are interleaved - see grid_make_consistent() for
2166  * details. */
2167
2168 /* i points to the first edge of the dline pair, reading clockwise around
2169  * the dot. */
2170 static int dline_index_from_dot(grid *g, grid_dot *d, int i)
2171 {
2172     grid_edge *e = d->edges[i];
2173     int ret;
2174 #ifdef DEBUG_DLINES
2175     grid_edge *e2;
2176     int i2 = i+1;
2177     if (i2 == d->order) i2 = 0;
2178     e2 = d->edges[i2];
2179 #endif
2180     ret = 2 * (e - g->edges) + ((e->dot1 == d) ? 1 : 0);
2181 #ifdef DEBUG_DLINES
2182     printf("dline_index_from_dot: d=%d,i=%d, edges [%d,%d] - %d\n",
2183            (int)(d - g->dots), i, (int)(e - g->edges),
2184            (int)(e2 - g->edges), ret);
2185 #endif
2186     return ret;
2187 }
2188 /* i points to the second edge of the dline pair, reading clockwise around
2189  * the face.  That is, the edges of the dline, starting at edge{i}, read
2190  * anti-clockwise around the face.  By layout conventions, the common dot
2191  * of the dline will be f->dots[i] */
2192 static int dline_index_from_face(grid *g, grid_face *f, int i)
2193 {
2194     grid_edge *e = f->edges[i];
2195     grid_dot *d = f->dots[i];
2196     int ret;
2197 #ifdef DEBUG_DLINES
2198     grid_edge *e2;
2199     int i2 = i - 1;
2200     if (i2 < 0) i2 += f->order;
2201     e2 = f->edges[i2];
2202 #endif
2203     ret = 2 * (e - g->edges) + ((e->dot1 == d) ? 1 : 0);
2204 #ifdef DEBUG_DLINES
2205     printf("dline_index_from_face: f=%d,i=%d, edges [%d,%d] - %d\n",
2206            (int)(f - g->faces), i, (int)(e - g->edges),
2207            (int)(e2 - g->edges), ret);
2208 #endif
2209     return ret;
2210 }
2211 static int is_atleastone(const char *dline_array, int index)
2212 {
2213     return BIT_SET(dline_array[index], 0);
2214 }
2215 static int set_atleastone(char *dline_array, int index)
2216 {
2217     return SET_BIT(dline_array[index], 0);
2218 }
2219 static int is_atmostone(const char *dline_array, int index)
2220 {
2221     return BIT_SET(dline_array[index], 1);
2222 }
2223 static int set_atmostone(char *dline_array, int index)
2224 {
2225     return SET_BIT(dline_array[index], 1);
2226 }
2227
2228 static void array_setall(char *array, char from, char to, int len)
2229 {
2230     char *p = array, *p_old = p;
2231     int len_remaining = len;
2232
2233     while ((p = memchr(p, from, len_remaining))) {
2234         *p = to;
2235         len_remaining -= p - p_old;
2236         p_old = p;
2237     }
2238 }
2239
2240 /* Helper, called when doing dline dot deductions, in the case where we
2241  * have 4 UNKNOWNs, and two of them (adjacent) have *exactly* one YES between
2242  * them (because of dline atmostone/atleastone).
2243  * On entry, edge points to the first of these two UNKNOWNs.  This function
2244  * will find the opposite UNKNOWNS (if they are adjacent to one another)
2245  * and set their corresponding dline to atleastone.  (Setting atmostone
2246  * already happens in earlier dline deductions) */
2247 static int dline_set_opp_atleastone(solver_state *sstate,
2248                                     grid_dot *d, int edge)
2249 {
2250     game_state *state = sstate->state;
2251     grid *g = state->game_grid;
2252     int N = d->order;
2253     int opp, opp2;
2254     for (opp = 0; opp < N; opp++) {
2255         int opp_dline_index;
2256         if (opp == edge || opp == edge+1 || opp == edge-1)
2257             continue;
2258         if (opp == 0 && edge == N-1)
2259             continue;
2260         if (opp == N-1 && edge == 0)
2261             continue;
2262         opp2 = opp + 1;
2263         if (opp2 == N) opp2 = 0;
2264         /* Check if opp, opp2 point to LINE_UNKNOWNs */
2265         if (state->lines[d->edges[opp] - g->edges] != LINE_UNKNOWN)
2266             continue;
2267         if (state->lines[d->edges[opp2] - g->edges] != LINE_UNKNOWN)
2268             continue;
2269         /* Found opposite UNKNOWNS and they're next to each other */
2270         opp_dline_index = dline_index_from_dot(g, d, opp);
2271         return set_atleastone(sstate->dlines, opp_dline_index);
2272     }
2273     return FALSE;
2274 }
2275
2276
2277 /* Set pairs of lines around this face which are known to be identical, to
2278  * the given line_state */
2279 static int face_setall_identical(solver_state *sstate, int face_index,
2280                                  enum line_state line_new)
2281 {
2282     /* can[dir] contains the canonical line associated with the line in
2283      * direction dir from the square in question.  Similarly inv[dir] is
2284      * whether or not the line in question is inverse to its canonical
2285      * element. */
2286     int retval = FALSE;
2287     game_state *state = sstate->state;
2288     grid *g = state->game_grid;
2289     grid_face *f = g->faces + face_index;
2290     int N = f->order;
2291     int i, j;
2292     int can1, can2, inv1, inv2;
2293
2294     for (i = 0; i < N; i++) {
2295         int line1_index = f->edges[i] - g->edges;
2296         if (state->lines[line1_index] != LINE_UNKNOWN)
2297             continue;
2298         for (j = i + 1; j < N; j++) {
2299             int line2_index = f->edges[j] - g->edges;
2300             if (state->lines[line2_index] != LINE_UNKNOWN)
2301                 continue;
2302
2303             /* Found two UNKNOWNS */
2304             can1 = edsf_canonify(sstate->linedsf, line1_index, &inv1);
2305             can2 = edsf_canonify(sstate->linedsf, line2_index, &inv2);
2306             if (can1 == can2 && inv1 == inv2) {
2307                 solver_set_line(sstate, line1_index, line_new);
2308                 solver_set_line(sstate, line2_index, line_new);
2309             }
2310         }
2311     }
2312     return retval;
2313 }
2314
2315 /* Given a dot or face, and a count of LINE_UNKNOWNs, find them and
2316  * return the edge indices into e. */
2317 static void find_unknowns(game_state *state,
2318     grid_edge **edge_list, /* Edge list to search (from a face or a dot) */
2319     int expected_count, /* Number of UNKNOWNs (comes from solver's cache) */
2320     int *e /* Returned edge indices */)
2321 {
2322     int c = 0;
2323     grid *g = state->game_grid;
2324     while (c < expected_count) {
2325         int line_index = *edge_list - g->edges;
2326         if (state->lines[line_index] == LINE_UNKNOWN) {
2327             e[c] = line_index;
2328             c++;
2329         }
2330         ++edge_list;
2331     }
2332 }
2333
2334 /* If we have a list of edges, and we know whether the number of YESs should
2335  * be odd or even, and there are only a few UNKNOWNs, we can do some simple
2336  * linedsf deductions.  This can be used for both face and dot deductions.
2337  * Returns the difficulty level of the next solver that should be used,
2338  * or DIFF_MAX if no progress was made. */
2339 static int parity_deductions(solver_state *sstate,
2340     grid_edge **edge_list, /* Edge list (from a face or a dot) */
2341     int total_parity, /* Expected number of YESs modulo 2 (either 0 or 1) */
2342     int unknown_count)
2343 {
2344     game_state *state = sstate->state;
2345     int diff = DIFF_MAX;
2346     int *linedsf = sstate->linedsf;
2347
2348     if (unknown_count == 2) {
2349         /* Lines are known alike/opposite, depending on inv. */
2350         int e[2];
2351         find_unknowns(state, edge_list, 2, e);
2352         if (merge_lines(sstate, e[0], e[1], total_parity))
2353             diff = min(diff, DIFF_HARD);
2354     } else if (unknown_count == 3) {
2355         int e[3];
2356         int can[3]; /* canonical edges */
2357         int inv[3]; /* whether can[x] is inverse to e[x] */
2358         find_unknowns(state, edge_list, 3, e);
2359         can[0] = edsf_canonify(linedsf, e[0], inv);
2360         can[1] = edsf_canonify(linedsf, e[1], inv+1);
2361         can[2] = edsf_canonify(linedsf, e[2], inv+2);
2362         if (can[0] == can[1]) {
2363             if (solver_set_line(sstate, e[2], (total_parity^inv[0]^inv[1]) ?
2364                                 LINE_YES : LINE_NO))
2365                 diff = min(diff, DIFF_EASY);
2366         }
2367         if (can[0] == can[2]) {
2368             if (solver_set_line(sstate, e[1], (total_parity^inv[0]^inv[2]) ?
2369                                 LINE_YES : LINE_NO))
2370                 diff = min(diff, DIFF_EASY);
2371         }
2372         if (can[1] == can[2]) {
2373             if (solver_set_line(sstate, e[0], (total_parity^inv[1]^inv[2]) ?
2374                                 LINE_YES : LINE_NO))
2375                 diff = min(diff, DIFF_EASY);
2376         }
2377     } else if (unknown_count == 4) {
2378         int e[4];
2379         int can[4]; /* canonical edges */
2380         int inv[4]; /* whether can[x] is inverse to e[x] */
2381         find_unknowns(state, edge_list, 4, e);
2382         can[0] = edsf_canonify(linedsf, e[0], inv);
2383         can[1] = edsf_canonify(linedsf, e[1], inv+1);
2384         can[2] = edsf_canonify(linedsf, e[2], inv+2);
2385         can[3] = edsf_canonify(linedsf, e[3], inv+3);
2386         if (can[0] == can[1]) {
2387             if (merge_lines(sstate, e[2], e[3], total_parity^inv[0]^inv[1]))
2388                 diff = min(diff, DIFF_HARD);
2389         } else if (can[0] == can[2]) {
2390             if (merge_lines(sstate, e[1], e[3], total_parity^inv[0]^inv[2]))
2391                 diff = min(diff, DIFF_HARD);
2392         } else if (can[0] == can[3]) {
2393             if (merge_lines(sstate, e[1], e[2], total_parity^inv[0]^inv[3]))
2394                 diff = min(diff, DIFF_HARD);
2395         } else if (can[1] == can[2]) {
2396             if (merge_lines(sstate, e[0], e[3], total_parity^inv[1]^inv[2]))
2397                 diff = min(diff, DIFF_HARD);
2398         } else if (can[1] == can[3]) {
2399             if (merge_lines(sstate, e[0], e[2], total_parity^inv[1]^inv[3]))
2400                 diff = min(diff, DIFF_HARD);
2401         } else if (can[2] == can[3]) {
2402             if (merge_lines(sstate, e[0], e[1], total_parity^inv[2]^inv[3]))
2403                 diff = min(diff, DIFF_HARD);
2404         }
2405     }
2406     return diff;
2407 }
2408
2409
2410 /*
2411  * These are the main solver functions.
2412  *
2413  * Their return values are diff values corresponding to the lowest mode solver
2414  * that would notice the work that they have done.  For example if the normal
2415  * mode solver adds actual lines or crosses, it will return DIFF_EASY as the
2416  * easy mode solver might be able to make progress using that.  It doesn't make
2417  * sense for one of them to return a diff value higher than that of the
2418  * function itself.
2419  *
2420  * Each function returns the lowest value it can, as early as possible, in
2421  * order to try and pass as much work as possible back to the lower level
2422  * solvers which progress more quickly.
2423  */
2424
2425 /* PROPOSED NEW DESIGN:
2426  * We have a work queue consisting of 'events' notifying us that something has
2427  * happened that a particular solver mode might be interested in.  For example
2428  * the hard mode solver might do something that helps the normal mode solver at
2429  * dot [x,y] in which case it will enqueue an event recording this fact.  Then
2430  * we pull events off the work queue, and hand each in turn to the solver that
2431  * is interested in them.  If a solver reports that it failed we pass the same
2432  * event on to progressively more advanced solvers and the loop detector.  Once
2433  * we've exhausted an event, or it has helped us progress, we drop it and
2434  * continue to the next one.  The events are sorted first in order of solver
2435  * complexity (easy first) then order of insertion (oldest first).
2436  * Once we run out of events we loop over each permitted solver in turn
2437  * (easiest first) until either a deduction is made (and an event therefore
2438  * emerges) or no further deductions can be made (in which case we've failed).
2439  *
2440  * QUESTIONS:
2441  *    * How do we 'loop over' a solver when both dots and squares are concerned.
2442  *      Answer: first all squares then all dots.
2443  */
2444
2445 static int trivial_deductions(solver_state *sstate)
2446 {
2447     int i, current_yes, current_no;
2448     game_state *state = sstate->state;
2449     grid *g = state->game_grid;
2450     int diff = DIFF_MAX;
2451
2452     /* Per-face deductions */
2453     for (i = 0; i < g->num_faces; i++) {
2454         grid_face *f = g->faces + i;
2455
2456         if (sstate->face_solved[i])
2457             continue;
2458
2459         current_yes = sstate->face_yes_count[i];
2460         current_no  = sstate->face_no_count[i];
2461
2462         if (current_yes + current_no == f->order)  {
2463             sstate->face_solved[i] = TRUE;
2464             continue;
2465         }
2466
2467         if (state->clues[i] < 0)
2468             continue;
2469
2470         /*
2471          * This code checks whether the numeric clue on a face is so
2472          * large as to permit all its remaining LINE_UNKNOWNs to be
2473          * filled in as LINE_YES, or alternatively so small as to
2474          * permit them all to be filled in as LINE_NO.
2475          */
2476
2477         if (state->clues[i] < current_yes) {
2478             sstate->solver_status = SOLVER_MISTAKE;
2479             return DIFF_EASY;
2480         }
2481         if (state->clues[i] == current_yes) {
2482             if (face_setall(sstate, i, LINE_UNKNOWN, LINE_NO))
2483                 diff = min(diff, DIFF_EASY);
2484             sstate->face_solved[i] = TRUE;
2485             continue;
2486         }
2487
2488         if (f->order - state->clues[i] < current_no) {
2489             sstate->solver_status = SOLVER_MISTAKE;
2490             return DIFF_EASY;
2491         }
2492         if (f->order - state->clues[i] == current_no) {
2493             if (face_setall(sstate, i, LINE_UNKNOWN, LINE_YES))
2494                 diff = min(diff, DIFF_EASY);
2495             sstate->face_solved[i] = TRUE;
2496             continue;
2497         }
2498
2499         if (f->order - state->clues[i] == current_no + 1 &&
2500             f->order - current_yes - current_no > 2) {
2501             /*
2502              * One small refinement to the above: we also look for any
2503              * adjacent pair of LINE_UNKNOWNs around the face with
2504              * some LINE_YES incident on it from elsewhere. If we find
2505              * one, then we know that pair of LINE_UNKNOWNs can't
2506              * _both_ be LINE_YES, and hence that pushes us one line
2507              * closer to being able to determine all the rest.
2508              */
2509             int j, k, e1, e2, e, d;
2510
2511             for (j = 0; j < f->order; j++) {
2512                 e1 = f->edges[j] - g->edges;
2513                 e2 = f->edges[j+1 < f->order ? j+1 : 0] - g->edges;
2514
2515                 if (g->edges[e1].dot1 == g->edges[e2].dot1 ||
2516                     g->edges[e1].dot1 == g->edges[e2].dot2) {
2517                     d = g->edges[e1].dot1 - g->dots;
2518                 } else {
2519                     assert(g->edges[e1].dot2 == g->edges[e2].dot1 ||
2520                            g->edges[e1].dot2 == g->edges[e2].dot2);
2521                     d = g->edges[e1].dot2 - g->dots;
2522                 }
2523
2524                 if (state->lines[e1] == LINE_UNKNOWN &&
2525                     state->lines[e2] == LINE_UNKNOWN) {
2526                     for (k = 0; k < g->dots[d].order; k++) {
2527                         int e = g->dots[d].edges[k] - g->edges;
2528                         if (state->lines[e] == LINE_YES)
2529                             goto found;    /* multi-level break */
2530                     }
2531                 }
2532             }
2533             continue;
2534
2535           found:
2536             /*
2537              * If we get here, we've found such a pair of edges, and
2538              * they're e1 and e2.
2539              */
2540             for (j = 0; j < f->order; j++) {
2541                 e = f->edges[j] - g->edges;
2542                 if (state->lines[e] == LINE_UNKNOWN && e != e1 && e != e2) {
2543                     int r = solver_set_line(sstate, e, LINE_YES);
2544                     assert(r);
2545                     diff = min(diff, DIFF_EASY);
2546                 }
2547             }
2548         }
2549     }
2550
2551     check_caches(sstate);
2552
2553     /* Per-dot deductions */
2554     for (i = 0; i < g->num_dots; i++) {
2555         grid_dot *d = g->dots + i;
2556         int yes, no, unknown;
2557
2558         if (sstate->dot_solved[i])
2559             continue;
2560
2561         yes = sstate->dot_yes_count[i];
2562         no = sstate->dot_no_count[i];
2563         unknown = d->order - yes - no;
2564
2565         if (yes == 0) {
2566             if (unknown == 0) {
2567                 sstate->dot_solved[i] = TRUE;
2568             } else if (unknown == 1) {
2569                 dot_setall(sstate, i, LINE_UNKNOWN, LINE_NO);
2570                 diff = min(diff, DIFF_EASY);
2571                 sstate->dot_solved[i] = TRUE;
2572             }
2573         } else if (yes == 1) {
2574             if (unknown == 0) {
2575                 sstate->solver_status = SOLVER_MISTAKE;
2576                 return DIFF_EASY;
2577             } else if (unknown == 1) {
2578                 dot_setall(sstate, i, LINE_UNKNOWN, LINE_YES);
2579                 diff = min(diff, DIFF_EASY);
2580             }
2581         } else if (yes == 2) {
2582             if (unknown > 0) {
2583                 dot_setall(sstate, i, LINE_UNKNOWN, LINE_NO);
2584                 diff = min(diff, DIFF_EASY);
2585             }
2586             sstate->dot_solved[i] = TRUE;
2587         } else {
2588             sstate->solver_status = SOLVER_MISTAKE;
2589             return DIFF_EASY;
2590         }
2591     }
2592
2593     check_caches(sstate);
2594
2595     return diff;
2596 }
2597
2598 static int dline_deductions(solver_state *sstate)
2599 {
2600     game_state *state = sstate->state;
2601     grid *g = state->game_grid;
2602     char *dlines = sstate->dlines;
2603     int i;
2604     int diff = DIFF_MAX;
2605
2606     /* ------ Face deductions ------ */
2607
2608     /* Given a set of dline atmostone/atleastone constraints, need to figure
2609      * out if we can deduce any further info.  For more general faces than
2610      * squares, this turns out to be a tricky problem.
2611      * The approach taken here is to define (per face) NxN matrices:
2612      * "maxs" and "mins".
2613      * The entries maxs(j,k) and mins(j,k) define the upper and lower limits
2614      * for the possible number of edges that are YES between positions j and k
2615      * going clockwise around the face.  Can think of j and k as marking dots
2616      * around the face (recall the labelling scheme: edge0 joins dot0 to dot1,
2617      * edge1 joins dot1 to dot2 etc).
2618      * Trivially, mins(j,j) = maxs(j,j) = 0, and we don't even bother storing
2619      * these.  mins(j,j+1) and maxs(j,j+1) are determined by whether edge{j}
2620      * is YES, NO or UNKNOWN.  mins(j,j+2) and maxs(j,j+2) are related to
2621      * the dline atmostone/atleastone status for edges j and j+1.
2622      *
2623      * Then we calculate the remaining entries recursively.  We definitely
2624      * know that
2625      * mins(j,k) >= { mins(j,u) + mins(u,k) } for any u between j and k.
2626      * This is because any valid placement of YESs between j and k must give
2627      * a valid placement between j and u, and also between u and k.
2628      * I believe it's sufficient to use just the two values of u:
2629      * j+1 and j+2.  Seems to work well in practice - the bounds we compute
2630      * are rigorous, even if they might not be best-possible.
2631      *
2632      * Once we have maxs and mins calculated, we can make inferences about
2633      * each dline{j,j+1} by looking at the possible complementary edge-counts
2634      * mins(j+2,j) and maxs(j+2,j) and comparing these with the face clue.
2635      * As well as dlines, we can make similar inferences about single edges.
2636      * For example, consider a pentagon with clue 3, and we know at most one
2637      * of (edge0, edge1) is YES, and at most one of (edge2, edge3) is YES.
2638      * We could then deduce edge4 is YES, because maxs(0,4) would be 2, so
2639      * that final edge would have to be YES to make the count up to 3.
2640      */
2641
2642     /* Much quicker to allocate arrays on the stack than the heap, so
2643      * define the largest possible face size, and base our array allocations
2644      * on that.  We check this with an assertion, in case someone decides to
2645      * make a grid which has larger faces than this.  Note, this algorithm
2646      * could get quite expensive if there are many large faces. */
2647 #define MAX_FACE_SIZE 12
2648
2649     for (i = 0; i < g->num_faces; i++) {
2650         int maxs[MAX_FACE_SIZE][MAX_FACE_SIZE];
2651         int mins[MAX_FACE_SIZE][MAX_FACE_SIZE];
2652         grid_face *f = g->faces + i;
2653         int N = f->order;
2654         int j,m;
2655         int clue = state->clues[i];
2656         assert(N <= MAX_FACE_SIZE);
2657         if (sstate->face_solved[i])
2658             continue;
2659         if (clue < 0) continue;
2660
2661         /* Calculate the (j,j+1) entries */
2662         for (j = 0; j < N; j++) {
2663             int edge_index = f->edges[j] - g->edges;
2664             int dline_index;
2665             enum line_state line1 = state->lines[edge_index];
2666             enum line_state line2;
2667             int tmp;
2668             int k = j + 1;
2669             if (k >= N) k = 0;
2670             maxs[j][k] = (line1 == LINE_NO) ? 0 : 1;
2671             mins[j][k] = (line1 == LINE_YES) ? 1 : 0;
2672             /* Calculate the (j,j+2) entries */
2673             dline_index = dline_index_from_face(g, f, k);
2674             edge_index = f->edges[k] - g->edges;
2675             line2 = state->lines[edge_index];
2676             k++;
2677             if (k >= N) k = 0;
2678
2679             /* max */
2680             tmp = 2;
2681             if (line1 == LINE_NO) tmp--;
2682             if (line2 == LINE_NO) tmp--;
2683             if (tmp == 2 && is_atmostone(dlines, dline_index))
2684                 tmp = 1;
2685             maxs[j][k] = tmp;
2686
2687             /* min */
2688             tmp = 0;
2689             if (line1 == LINE_YES) tmp++;
2690             if (line2 == LINE_YES) tmp++;
2691             if (tmp == 0 && is_atleastone(dlines, dline_index))
2692                 tmp = 1;
2693             mins[j][k] = tmp;
2694         }
2695
2696         /* Calculate the (j,j+m) entries for m between 3 and N-1 */
2697         for (m = 3; m < N; m++) {
2698             for (j = 0; j < N; j++) {
2699                 int k = j + m;
2700                 int u = j + 1;
2701                 int v = j + 2;
2702                 int tmp;
2703                 if (k >= N) k -= N;
2704                 if (u >= N) u -= N;
2705                 if (v >= N) v -= N;
2706                 maxs[j][k] = maxs[j][u] + maxs[u][k];
2707                 mins[j][k] = mins[j][u] + mins[u][k];
2708                 tmp = maxs[j][v] + maxs[v][k];
2709                 maxs[j][k] = min(maxs[j][k], tmp);
2710                 tmp = mins[j][v] + mins[v][k];
2711                 mins[j][k] = max(mins[j][k], tmp);
2712             }
2713         }
2714
2715         /* See if we can make any deductions */
2716         for (j = 0; j < N; j++) {
2717             int k;
2718             grid_edge *e = f->edges[j];
2719             int line_index = e - g->edges;
2720             int dline_index;
2721
2722             if (state->lines[line_index] != LINE_UNKNOWN)
2723                 continue;
2724             k = j + 1;
2725             if (k >= N) k = 0;
2726
2727             /* minimum YESs in the complement of this edge */
2728             if (mins[k][j] > clue) {
2729                 sstate->solver_status = SOLVER_MISTAKE;
2730                 return DIFF_EASY;
2731             }
2732             if (mins[k][j] == clue) {
2733                 /* setting this edge to YES would make at least
2734                  * (clue+1) edges - contradiction */
2735                 solver_set_line(sstate, line_index, LINE_NO);
2736                 diff = min(diff, DIFF_EASY);
2737             }
2738             if (maxs[k][j] < clue - 1) {
2739                 sstate->solver_status = SOLVER_MISTAKE;
2740                 return DIFF_EASY;
2741             }
2742             if (maxs[k][j] == clue - 1) {
2743                 /* Only way to satisfy the clue is to set edge{j} as YES */
2744                 solver_set_line(sstate, line_index, LINE_YES);
2745                 diff = min(diff, DIFF_EASY);
2746             }
2747
2748             /* More advanced deduction that allows propagation along diagonal
2749              * chains of faces connected by dots, for example, 3-2-...-2-3
2750              * in square grids. */
2751             if (sstate->diff >= DIFF_TRICKY) {
2752                 /* Now see if we can make dline deduction for edges{j,j+1} */
2753                 e = f->edges[k];
2754                 if (state->lines[e - g->edges] != LINE_UNKNOWN)
2755                     /* Only worth doing this for an UNKNOWN,UNKNOWN pair.
2756                      * Dlines where one of the edges is known, are handled in the
2757                      * dot-deductions */
2758                     continue;
2759     
2760                 dline_index = dline_index_from_face(g, f, k);
2761                 k++;
2762                 if (k >= N) k = 0;
2763     
2764                 /* minimum YESs in the complement of this dline */
2765                 if (mins[k][j] > clue - 2) {
2766                     /* Adding 2 YESs would break the clue */
2767                     if (set_atmostone(dlines, dline_index))
2768                         diff = min(diff, DIFF_NORMAL);
2769                 }
2770                 /* maximum YESs in the complement of this dline */
2771                 if (maxs[k][j] < clue) {
2772                     /* Adding 2 NOs would mean not enough YESs */
2773                     if (set_atleastone(dlines, dline_index))
2774                         diff = min(diff, DIFF_NORMAL);
2775                 }
2776             }
2777         }
2778     }
2779
2780     if (diff < DIFF_NORMAL)
2781         return diff;
2782
2783     /* ------ Dot deductions ------ */
2784
2785     for (i = 0; i < g->num_dots; i++) {
2786         grid_dot *d = g->dots + i;
2787         int N = d->order;
2788         int yes, no, unknown;
2789         int j;
2790         if (sstate->dot_solved[i])
2791             continue;
2792         yes = sstate->dot_yes_count[i];
2793         no = sstate->dot_no_count[i];
2794         unknown = N - yes - no;
2795
2796         for (j = 0; j < N; j++) {
2797             int k;
2798             int dline_index;
2799             int line1_index, line2_index;
2800             enum line_state line1, line2;
2801             k = j + 1;
2802             if (k >= N) k = 0;
2803             dline_index = dline_index_from_dot(g, d, j);
2804             line1_index = d->edges[j] - g->edges;
2805             line2_index = d->edges[k] - g->edges;
2806             line1 = state->lines[line1_index];
2807             line2 = state->lines[line2_index];
2808
2809             /* Infer dline state from line state */
2810             if (line1 == LINE_NO || line2 == LINE_NO) {
2811                 if (set_atmostone(dlines, dline_index))
2812                     diff = min(diff, DIFF_NORMAL);
2813             }
2814             if (line1 == LINE_YES || line2 == LINE_YES) {
2815                 if (set_atleastone(dlines, dline_index))
2816                     diff = min(diff, DIFF_NORMAL);
2817             }
2818             /* Infer line state from dline state */
2819             if (is_atmostone(dlines, dline_index)) {
2820                 if (line1 == LINE_YES && line2 == LINE_UNKNOWN) {
2821                     solver_set_line(sstate, line2_index, LINE_NO);
2822                     diff = min(diff, DIFF_EASY);
2823                 }
2824                 if (line2 == LINE_YES && line1 == LINE_UNKNOWN) {
2825                     solver_set_line(sstate, line1_index, LINE_NO);
2826                     diff = min(diff, DIFF_EASY);
2827                 }
2828             }
2829             if (is_atleastone(dlines, dline_index)) {
2830                 if (line1 == LINE_NO && line2 == LINE_UNKNOWN) {
2831                     solver_set_line(sstate, line2_index, LINE_YES);
2832                     diff = min(diff, DIFF_EASY);
2833                 }
2834                 if (line2 == LINE_NO && line1 == LINE_UNKNOWN) {
2835                     solver_set_line(sstate, line1_index, LINE_YES);
2836                     diff = min(diff, DIFF_EASY);
2837                 }
2838             }
2839             /* Deductions that depend on the numbers of lines.
2840              * Only bother if both lines are UNKNOWN, otherwise the
2841              * easy-mode solver (or deductions above) would have taken
2842              * care of it. */
2843             if (line1 != LINE_UNKNOWN || line2 != LINE_UNKNOWN)
2844                 continue;
2845
2846             if (yes == 0 && unknown == 2) {
2847                 /* Both these unknowns must be identical.  If we know
2848                  * atmostone or atleastone, we can make progress. */
2849                 if (is_atmostone(dlines, dline_index)) {
2850                     solver_set_line(sstate, line1_index, LINE_NO);
2851                     solver_set_line(sstate, line2_index, LINE_NO);
2852                     diff = min(diff, DIFF_EASY);
2853                 }
2854                 if (is_atleastone(dlines, dline_index)) {
2855                     solver_set_line(sstate, line1_index, LINE_YES);
2856                     solver_set_line(sstate, line2_index, LINE_YES);
2857                     diff = min(diff, DIFF_EASY);
2858                 }
2859             }
2860             if (yes == 1) {
2861                 if (set_atmostone(dlines, dline_index))
2862                     diff = min(diff, DIFF_NORMAL);
2863                 if (unknown == 2) {
2864                     if (set_atleastone(dlines, dline_index))
2865                         diff = min(diff, DIFF_NORMAL);
2866                 }
2867             }
2868
2869             /* More advanced deduction that allows propagation along diagonal
2870              * chains of faces connected by dots, for example: 3-2-...-2-3
2871              * in square grids. */
2872             if (sstate->diff >= DIFF_TRICKY) {
2873                 /* If we have atleastone set for this dline, infer
2874                  * atmostone for each "opposite" dline (that is, each
2875                  * dline without edges in common with this one).
2876                  * Again, this test is only worth doing if both these
2877                  * lines are UNKNOWN.  For if one of these lines were YES,
2878                  * the (yes == 1) test above would kick in instead. */
2879                 if (is_atleastone(dlines, dline_index)) {
2880                     int opp;
2881                     for (opp = 0; opp < N; opp++) {
2882                         int opp_dline_index;
2883                         if (opp == j || opp == j+1 || opp == j-1)
2884                             continue;
2885                         if (j == 0 && opp == N-1)
2886                             continue;
2887                         if (j == N-1 && opp == 0)
2888                             continue;
2889                         opp_dline_index = dline_index_from_dot(g, d, opp);
2890                         if (set_atmostone(dlines, opp_dline_index))
2891                             diff = min(diff, DIFF_NORMAL);
2892                     }
2893                     if (yes == 0 && is_atmostone(dlines, dline_index)) {
2894                         /* This dline has *exactly* one YES and there are no
2895                          * other YESs.  This allows more deductions. */
2896                         if (unknown == 3) {
2897                             /* Third unknown must be YES */
2898                             for (opp = 0; opp < N; opp++) {
2899                                 int opp_index;
2900                                 if (opp == j || opp == k)
2901                                     continue;
2902                                 opp_index = d->edges[opp] - g->edges;
2903                                 if (state->lines[opp_index] == LINE_UNKNOWN) {
2904                                     solver_set_line(sstate, opp_index,
2905                                                     LINE_YES);
2906                                     diff = min(diff, DIFF_EASY);
2907                                 }
2908                             }
2909                         } else if (unknown == 4) {
2910                             /* Exactly one of opposite UNKNOWNS is YES.  We've
2911                              * already set atmostone, so set atleastone as
2912                              * well.
2913                              */
2914                             if (dline_set_opp_atleastone(sstate, d, j))
2915                                 diff = min(diff, DIFF_NORMAL);
2916                         }
2917                     }
2918                 }
2919             }
2920         }
2921     }
2922     return diff;
2923 }
2924
2925 static int linedsf_deductions(solver_state *sstate)
2926 {
2927     game_state *state = sstate->state;
2928     grid *g = state->game_grid;
2929     char *dlines = sstate->dlines;
2930     int i;
2931     int diff = DIFF_MAX;
2932     int diff_tmp;
2933
2934     /* ------ Face deductions ------ */
2935
2936     /* A fully-general linedsf deduction seems overly complicated
2937      * (I suspect the problem is NP-complete, though in practice it might just
2938      * be doable because faces are limited in size).
2939      * For simplicity, we only consider *pairs* of LINE_UNKNOWNS that are
2940      * known to be identical.  If setting them both to YES (or NO) would break
2941      * the clue, set them to NO (or YES). */
2942
2943     for (i = 0; i < g->num_faces; i++) {
2944         int N, yes, no, unknown;
2945         int clue;
2946
2947         if (sstate->face_solved[i])
2948             continue;
2949         clue = state->clues[i];
2950         if (clue < 0)
2951             continue;
2952
2953         N = g->faces[i].order;
2954         yes = sstate->face_yes_count[i];
2955         if (yes + 1 == clue) {
2956             if (face_setall_identical(sstate, i, LINE_NO))
2957                 diff = min(diff, DIFF_EASY);
2958         }
2959         no = sstate->face_no_count[i];
2960         if (no + 1 == N - clue) {
2961             if (face_setall_identical(sstate, i, LINE_YES))
2962                 diff = min(diff, DIFF_EASY);
2963         }
2964
2965         /* Reload YES count, it might have changed */
2966         yes = sstate->face_yes_count[i];
2967         unknown = N - no - yes;
2968
2969         /* Deductions with small number of LINE_UNKNOWNs, based on overall
2970          * parity of lines. */
2971         diff_tmp = parity_deductions(sstate, g->faces[i].edges,
2972                                      (clue - yes) % 2, unknown);
2973         diff = min(diff, diff_tmp);
2974     }
2975
2976     /* ------ Dot deductions ------ */
2977     for (i = 0; i < g->num_dots; i++) {
2978         grid_dot *d = g->dots + i;
2979         int N = d->order;
2980         int j;
2981         int yes, no, unknown;
2982         /* Go through dlines, and do any dline<->linedsf deductions wherever
2983          * we find two UNKNOWNS. */
2984         for (j = 0; j < N; j++) {
2985             int dline_index = dline_index_from_dot(g, d, j);
2986             int line1_index;
2987             int line2_index;
2988             int can1, can2, inv1, inv2;
2989             int j2;
2990             line1_index = d->edges[j] - g->edges;
2991             if (state->lines[line1_index] != LINE_UNKNOWN)
2992                 continue;
2993             j2 = j + 1;
2994             if (j2 == N) j2 = 0;
2995             line2_index = d->edges[j2] - g->edges;
2996             if (state->lines[line2_index] != LINE_UNKNOWN)
2997                 continue;
2998             /* Infer dline flags from linedsf */
2999             can1 = edsf_canonify(sstate->linedsf, line1_index, &inv1);
3000             can2 = edsf_canonify(sstate->linedsf, line2_index, &inv2);
3001             if (can1 == can2 && inv1 != inv2) {
3002                 /* These are opposites, so set dline atmostone/atleastone */
3003                 if (set_atmostone(dlines, dline_index))
3004                     diff = min(diff, DIFF_NORMAL);
3005                 if (set_atleastone(dlines, dline_index))
3006                     diff = min(diff, DIFF_NORMAL);
3007                 continue;
3008             }
3009             /* Infer linedsf from dline flags */
3010             if (is_atmostone(dlines, dline_index)
3011                 && is_atleastone(dlines, dline_index)) {
3012                 if (merge_lines(sstate, line1_index, line2_index, 1))
3013                     diff = min(diff, DIFF_HARD);
3014             }
3015         }
3016
3017         /* Deductions with small number of LINE_UNKNOWNs, based on overall
3018          * parity of lines. */
3019         yes = sstate->dot_yes_count[i];
3020         no = sstate->dot_no_count[i];
3021         unknown = N - yes - no;
3022         diff_tmp = parity_deductions(sstate, d->edges,
3023                                      yes % 2, unknown);
3024         diff = min(diff, diff_tmp);
3025     }
3026
3027     /* ------ Edge dsf deductions ------ */
3028
3029     /* If the state of a line is known, deduce the state of its canonical line
3030      * too, and vice versa. */
3031     for (i = 0; i < g->num_edges; i++) {
3032         int can, inv;
3033         enum line_state s;
3034         can = edsf_canonify(sstate->linedsf, i, &inv);
3035         if (can == i)
3036             continue;
3037         s = sstate->state->lines[can];
3038         if (s != LINE_UNKNOWN) {
3039             if (solver_set_line(sstate, i, inv ? OPP(s) : s))
3040                 diff = min(diff, DIFF_EASY);
3041         } else {
3042             s = sstate->state->lines[i];
3043             if (s != LINE_UNKNOWN) {
3044                 if (solver_set_line(sstate, can, inv ? OPP(s) : s))
3045                     diff = min(diff, DIFF_EASY);
3046             }
3047         }
3048     }
3049
3050     return diff;
3051 }
3052
3053 static int loop_deductions(solver_state *sstate)
3054 {
3055     int edgecount = 0, clues = 0, satclues = 0, sm1clues = 0;
3056     game_state *state = sstate->state;
3057     grid *g = state->game_grid;
3058     int shortest_chainlen = g->num_dots;
3059     int loop_found = FALSE;
3060     int dots_connected;
3061     int progress = FALSE;
3062     int i;
3063
3064     /*
3065      * Go through the grid and update for all the new edges.
3066      * Since merge_dots() is idempotent, the simplest way to
3067      * do this is just to update for _all_ the edges.
3068      * Also, while we're here, we count the edges.
3069      */
3070     for (i = 0; i < g->num_edges; i++) {
3071         if (state->lines[i] == LINE_YES) {
3072             loop_found |= merge_dots(sstate, i);
3073             edgecount++;
3074         }
3075     }
3076
3077     /*
3078      * Count the clues, count the satisfied clues, and count the
3079      * satisfied-minus-one clues.
3080      */
3081     for (i = 0; i < g->num_faces; i++) {
3082         int c = state->clues[i];
3083         if (c >= 0) {
3084             int o = sstate->face_yes_count[i];
3085             if (o == c)
3086                 satclues++;
3087             else if (o == c-1)
3088                 sm1clues++;
3089             clues++;
3090         }
3091     }
3092
3093     for (i = 0; i < g->num_dots; ++i) {
3094         dots_connected =
3095             sstate->looplen[dsf_canonify(sstate->dotdsf, i)];
3096         if (dots_connected > 1)
3097             shortest_chainlen = min(shortest_chainlen, dots_connected);
3098     }
3099
3100     assert(sstate->solver_status == SOLVER_INCOMPLETE);
3101
3102     if (satclues == clues && shortest_chainlen == edgecount) {
3103         sstate->solver_status = SOLVER_SOLVED;
3104         /* This discovery clearly counts as progress, even if we haven't
3105          * just added any lines or anything */
3106         progress = TRUE;
3107         goto finished_loop_deductionsing;
3108     }
3109
3110     /*
3111      * Now go through looking for LINE_UNKNOWN edges which
3112      * connect two dots that are already in the same
3113      * equivalence class. If we find one, test to see if the
3114      * loop it would create is a solution.
3115      */
3116     for (i = 0; i < g->num_edges; i++) {
3117         grid_edge *e = g->edges + i;
3118         int d1 = e->dot1 - g->dots;
3119         int d2 = e->dot2 - g->dots;
3120         int eqclass, val;
3121         if (state->lines[i] != LINE_UNKNOWN)
3122             continue;
3123
3124         eqclass = dsf_canonify(sstate->dotdsf, d1);
3125         if (eqclass != dsf_canonify(sstate->dotdsf, d2))
3126             continue;
3127
3128         val = LINE_NO;  /* loop is bad until proven otherwise */
3129
3130         /*
3131          * This edge would form a loop. Next
3132          * question: how long would the loop be?
3133          * Would it equal the total number of edges
3134          * (plus the one we'd be adding if we added
3135          * it)?
3136          */
3137         if (sstate->looplen[eqclass] == edgecount + 1) {
3138             int sm1_nearby;
3139
3140             /*
3141              * This edge would form a loop which
3142              * took in all the edges in the entire
3143              * grid. So now we need to work out
3144              * whether it would be a valid solution
3145              * to the puzzle, which means we have to
3146              * check if it satisfies all the clues.
3147              * This means that every clue must be
3148              * either satisfied or satisfied-minus-
3149              * 1, and also that the number of
3150              * satisfied-minus-1 clues must be at
3151              * most two and they must lie on either
3152              * side of this edge.
3153              */
3154             sm1_nearby = 0;
3155             if (e->face1) {
3156                 int f = e->face1 - g->faces;
3157                 int c = state->clues[f];
3158                 if (c >= 0 && sstate->face_yes_count[f] == c - 1)
3159                     sm1_nearby++;
3160             }
3161             if (e->face2) {
3162                 int f = e->face2 - g->faces;
3163                 int c = state->clues[f];
3164                 if (c >= 0 && sstate->face_yes_count[f] == c - 1)
3165                     sm1_nearby++;
3166             }
3167             if (sm1clues == sm1_nearby &&
3168                 sm1clues + satclues == clues) {
3169                 val = LINE_YES;  /* loop is good! */
3170             }
3171         }
3172
3173         /*
3174          * Right. Now we know that adding this edge
3175          * would form a loop, and we know whether
3176          * that loop would be a viable solution or
3177          * not.
3178          *
3179          * If adding this edge produces a solution,
3180          * then we know we've found _a_ solution but
3181          * we don't know that it's _the_ solution -
3182          * if it were provably the solution then
3183          * we'd have deduced this edge some time ago
3184          * without the need to do loop detection. So
3185          * in this state we return SOLVER_AMBIGUOUS,
3186          * which has the effect that hitting Solve
3187          * on a user-provided puzzle will fill in a
3188          * solution but using the solver to
3189          * construct new puzzles won't consider this
3190          * a reasonable deduction for the user to
3191          * make.
3192          */
3193         progress = solver_set_line(sstate, i, val);
3194         assert(progress == TRUE);
3195         if (val == LINE_YES) {
3196             sstate->solver_status = SOLVER_AMBIGUOUS;
3197             goto finished_loop_deductionsing;
3198         }
3199     }
3200
3201     finished_loop_deductionsing:
3202     return progress ? DIFF_EASY : DIFF_MAX;
3203 }
3204
3205 /* This will return a dynamically allocated solver_state containing the (more)
3206  * solved grid */
3207 static solver_state *solve_game_rec(const solver_state *sstate_start)
3208 {
3209     solver_state *sstate;
3210
3211     /* Index of the solver we should call next. */
3212     int i = 0;
3213     
3214     /* As a speed-optimisation, we avoid re-running solvers that we know
3215      * won't make any progress.  This happens when a high-difficulty
3216      * solver makes a deduction that can only help other high-difficulty
3217      * solvers.
3218      * For example: if a new 'dline' flag is set by dline_deductions, the
3219      * trivial_deductions solver cannot do anything with this information.
3220      * If we've already run the trivial_deductions solver (because it's
3221      * earlier in the list), there's no point running it again.
3222      *
3223      * Therefore: if a solver is earlier in the list than "threshold_index",
3224      * we don't bother running it if it's difficulty level is less than
3225      * "threshold_diff".
3226      */
3227     int threshold_diff = 0;
3228     int threshold_index = 0;
3229     
3230     sstate = dup_solver_state(sstate_start);
3231
3232     check_caches(sstate);
3233
3234     while (i < NUM_SOLVERS) {
3235         if (sstate->solver_status == SOLVER_MISTAKE)
3236             return sstate;
3237         if (sstate->solver_status == SOLVER_SOLVED ||
3238             sstate->solver_status == SOLVER_AMBIGUOUS) {
3239             /* solver finished */
3240             break;
3241         }
3242
3243         if ((solver_diffs[i] >= threshold_diff || i >= threshold_index)
3244             && solver_diffs[i] <= sstate->diff) {
3245             /* current_solver is eligible, so use it */
3246             int next_diff = solver_fns[i](sstate);
3247             if (next_diff != DIFF_MAX) {
3248                 /* solver made progress, so use new thresholds and
3249                 * start again at top of list. */
3250                 threshold_diff = next_diff;
3251                 threshold_index = i;
3252                 i = 0;
3253                 continue;
3254             }
3255         }
3256         /* current_solver is ineligible, or failed to make progress, so
3257          * go to the next solver in the list */
3258         i++;
3259     }
3260
3261     if (sstate->solver_status == SOLVER_SOLVED ||
3262         sstate->solver_status == SOLVER_AMBIGUOUS) {
3263         /* s/LINE_UNKNOWN/LINE_NO/g */
3264         array_setall(sstate->state->lines, LINE_UNKNOWN, LINE_NO,
3265                      sstate->state->game_grid->num_edges);
3266         return sstate;
3267     }
3268
3269     return sstate;
3270 }
3271
3272 static char *solve_game(game_state *state, game_state *currstate,
3273                         char *aux, char **error)
3274 {
3275     char *soln = NULL;
3276     solver_state *sstate, *new_sstate;
3277
3278     sstate = new_solver_state(state, DIFF_MAX);
3279     new_sstate = solve_game_rec(sstate);
3280
3281     if (new_sstate->solver_status == SOLVER_SOLVED) {
3282         soln = encode_solve_move(new_sstate->state);
3283     } else if (new_sstate->solver_status == SOLVER_AMBIGUOUS) {
3284         soln = encode_solve_move(new_sstate->state);
3285         /**error = "Solver found ambiguous solutions"; */
3286     } else {
3287         soln = encode_solve_move(new_sstate->state);
3288         /**error = "Solver failed"; */
3289     }
3290
3291     free_solver_state(new_sstate);
3292     free_solver_state(sstate);
3293
3294     return soln;
3295 }
3296
3297 /* ----------------------------------------------------------------------
3298  * Drawing and mouse-handling
3299  */
3300
3301 static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
3302                             int x, int y, int button)
3303 {
3304     grid *g = state->game_grid;
3305     grid_edge *e;
3306     int i;
3307     char *ret, buf[80];
3308     char button_char = ' ';
3309     enum line_state old_state;
3310
3311     button &= ~MOD_MASK;
3312
3313     /* Convert mouse-click (x,y) to grid coordinates */
3314     x -= BORDER(ds->tilesize);
3315     y -= BORDER(ds->tilesize);
3316     x = x * g->tilesize / ds->tilesize;
3317     y = y * g->tilesize / ds->tilesize;
3318     x += g->lowest_x;
3319     y += g->lowest_y;
3320
3321     e = grid_nearest_edge(g, x, y);
3322     if (e == NULL)
3323         return NULL;
3324
3325     i = e - g->edges;
3326
3327     /* I think it's only possible to play this game with mouse clicks, sorry */
3328     /* Maybe will add mouse drag support some time */
3329     old_state = state->lines[i];
3330
3331     switch (button) {
3332       case LEFT_BUTTON:
3333         switch (old_state) {
3334           case LINE_UNKNOWN:
3335             button_char = 'y';
3336             break;
3337           case LINE_YES:
3338 #ifdef STYLUS_BASED
3339             button_char = 'n';
3340             break;
3341 #endif
3342           case LINE_NO:
3343             button_char = 'u';
3344             break;
3345         }
3346         break;
3347       case MIDDLE_BUTTON:
3348         button_char = 'u';
3349         break;
3350       case RIGHT_BUTTON:
3351         switch (old_state) {
3352           case LINE_UNKNOWN:
3353             button_char = 'n';
3354             break;
3355           case LINE_NO:
3356 #ifdef STYLUS_BASED
3357             button_char = 'y';
3358             break;
3359 #endif
3360           case LINE_YES:
3361             button_char = 'u';
3362             break;
3363         }
3364         break;
3365       default:
3366         return NULL;
3367     }
3368
3369
3370     sprintf(buf, "%d%c", i, (int)button_char);
3371     ret = dupstr(buf);
3372
3373     return ret;
3374 }
3375
3376 static game_state *execute_move(game_state *state, char *move)
3377 {
3378     int i;
3379     game_state *newstate = dup_game(state);
3380
3381     if (move[0] == 'S') {
3382         move++;
3383         newstate->cheated = TRUE;
3384     }
3385
3386     while (*move) {
3387         i = atoi(move);
3388         if (i < 0 || i >= newstate->game_grid->num_edges)
3389             goto fail;
3390         move += strspn(move, "1234567890");
3391         switch (*(move++)) {
3392           case 'y':
3393             newstate->lines[i] = LINE_YES;
3394             break;
3395           case 'n':
3396             newstate->lines[i] = LINE_NO;
3397             break;
3398           case 'u':
3399             newstate->lines[i] = LINE_UNKNOWN;
3400             break;
3401           default:
3402             goto fail;
3403         }
3404     }
3405
3406     /*
3407      * Check for completion.
3408      */
3409     if (check_completion(newstate))
3410         newstate->solved = TRUE;
3411
3412     return newstate;
3413
3414     fail:
3415     free_game(newstate);
3416     return NULL;
3417 }
3418
3419 /* ----------------------------------------------------------------------
3420  * Drawing routines.
3421  */
3422
3423 /* Convert from grid coordinates to screen coordinates */
3424 static void grid_to_screen(const game_drawstate *ds, const grid *g,
3425                            int grid_x, int grid_y, int *x, int *y)
3426 {
3427     *x = grid_x - g->lowest_x;
3428     *y = grid_y - g->lowest_y;
3429     *x = *x * ds->tilesize / g->tilesize;
3430     *y = *y * ds->tilesize / g->tilesize;
3431     *x += BORDER(ds->tilesize);
3432     *y += BORDER(ds->tilesize);
3433 }
3434
3435 /* Returns (into x,y) position of centre of face for rendering the text clue.
3436  */
3437 static void face_text_pos(const game_drawstate *ds, const grid *g,
3438                           grid_face *f, int *xret, int *yret)
3439 {
3440     int faceindex = f - g->faces;
3441
3442     /*
3443      * Return the cached position for this face, if we've already
3444      * worked it out.
3445      */
3446     if (ds->textx[faceindex] >= 0) {
3447         *xret = ds->textx[faceindex];
3448         *yret = ds->texty[faceindex];
3449         return;
3450     }
3451
3452     /*
3453      * Otherwise, use the incentre computed by grid.c and convert it
3454      * to screen coordinates.
3455      */
3456     grid_find_incentre(f);
3457     grid_to_screen(ds, g, f->ix, f->iy,
3458                    &ds->textx[faceindex], &ds->texty[faceindex]);
3459
3460     *xret = ds->textx[faceindex];
3461     *yret = ds->texty[faceindex];
3462 }
3463
3464 static void face_text_bbox(game_drawstate *ds, grid *g, grid_face *f,
3465                            int *x, int *y, int *w, int *h)
3466 {
3467     int xx, yy;
3468     face_text_pos(ds, g, f, &xx, &yy);
3469
3470     /* There seems to be a certain amount of trial-and-error involved
3471      * in working out the correct bounding-box for the text. */
3472
3473     *x = xx - ds->tilesize/4 - 1;
3474     *y = yy - ds->tilesize/4 - 3;
3475     *w = ds->tilesize/2 + 2;
3476     *h = ds->tilesize/2 + 5;
3477 }
3478
3479 static void game_redraw_clue(drawing *dr, game_drawstate *ds,
3480                              game_state *state, int i)
3481 {
3482     grid *g = state->game_grid;
3483     grid_face *f = g->faces + i;
3484     int x, y;
3485     char c[3];
3486
3487     if (state->clues[i] < 10) {
3488         c[0] = CLUE2CHAR(state->clues[i]);
3489         c[1] = '\0';
3490     } else {
3491         sprintf(c, "%d", state->clues[i]);
3492     }
3493
3494     face_text_pos(ds, g, f, &x, &y);
3495     draw_text(dr, x, y,
3496               FONT_VARIABLE, ds->tilesize/2,
3497               ALIGN_VCENTRE | ALIGN_HCENTRE,
3498               ds->clue_error[i] ? COL_MISTAKE :
3499               ds->clue_satisfied[i] ? COL_SATISFIED : COL_FOREGROUND, c);
3500 }
3501
3502 static void edge_bbox(game_drawstate *ds, grid *g, grid_edge *e,
3503                       int *x, int *y, int *w, int *h)
3504 {
3505     int x1 = e->dot1->x;
3506     int y1 = e->dot1->y;
3507     int x2 = e->dot2->x;
3508     int y2 = e->dot2->y;
3509     int xmin, xmax, ymin, ymax;
3510
3511     grid_to_screen(ds, g, x1, y1, &x1, &y1);
3512     grid_to_screen(ds, g, x2, y2, &x2, &y2);
3513     /* Allow extra margin for dots, and thickness of lines */
3514     xmin = min(x1, x2) - 2;
3515     xmax = max(x1, x2) + 2;
3516     ymin = min(y1, y2) - 2;
3517     ymax = max(y1, y2) + 2;
3518
3519     *x = xmin;
3520     *y = ymin;
3521     *w = xmax - xmin + 1;
3522     *h = ymax - ymin + 1;
3523 }
3524
3525 static void dot_bbox(game_drawstate *ds, grid *g, grid_dot *d,
3526                      int *x, int *y, int *w, int *h)
3527 {
3528     int x1, y1;
3529
3530     grid_to_screen(ds, g, d->x, d->y, &x1, &y1);
3531
3532     *x = x1 - 2;
3533     *y = y1 - 2;
3534     *w = 5;
3535     *h = 5;
3536 }
3537
3538 static const int loopy_line_redraw_phases[] = {
3539     COL_FAINT, COL_LINEUNKNOWN, COL_FOREGROUND, COL_HIGHLIGHT, COL_MISTAKE
3540 };
3541 #define NPHASES lenof(loopy_line_redraw_phases)
3542
3543 static void game_redraw_line(drawing *dr, game_drawstate *ds,
3544                              game_state *state, int i, int phase)
3545 {
3546     grid *g = state->game_grid;
3547     grid_edge *e = g->edges + i;
3548     int x1, x2, y1, y2;
3549     int xmin, ymin, xmax, ymax;
3550     int line_colour;
3551
3552     if (state->line_errors[i])
3553         line_colour = COL_MISTAKE;
3554     else if (state->lines[i] == LINE_UNKNOWN)
3555         line_colour = COL_LINEUNKNOWN;
3556     else if (state->lines[i] == LINE_NO)
3557         line_colour = COL_FAINT;
3558     else if (ds->flashing)
3559         line_colour = COL_HIGHLIGHT;
3560     else
3561         line_colour = COL_FOREGROUND;
3562     if (line_colour != loopy_line_redraw_phases[phase])
3563         return;
3564
3565     /* Convert from grid to screen coordinates */
3566     grid_to_screen(ds, g, e->dot1->x, e->dot1->y, &x1, &y1);
3567     grid_to_screen(ds, g, e->dot2->x, e->dot2->y, &x2, &y2);
3568
3569     xmin = min(x1, x2);
3570     xmax = max(x1, x2);
3571     ymin = min(y1, y2);
3572     ymax = max(y1, y2);
3573
3574     if (line_colour == COL_FAINT) {
3575         static int draw_faint_lines = -1;
3576         if (draw_faint_lines < 0) {
3577             char *env = getenv("LOOPY_FAINT_LINES");
3578             draw_faint_lines = (!env || (env[0] == 'y' ||
3579                                          env[0] == 'Y'));
3580         }
3581         if (draw_faint_lines)
3582             draw_line(dr, x1, y1, x2, y2, line_colour);
3583     } else {
3584         draw_thick_line(dr, 3.0,
3585                         x1 + 0.5, y1 + 0.5,
3586                         x2 + 0.5, y2 + 0.5,
3587                         line_colour);
3588     }
3589 }
3590
3591 static void game_redraw_dot(drawing *dr, game_drawstate *ds,
3592                             game_state *state, int i)
3593 {
3594     grid *g = state->game_grid;
3595     grid_dot *d = g->dots + i;
3596     int x, y;
3597
3598     grid_to_screen(ds, g, d->x, d->y, &x, &y);
3599     draw_circle(dr, x, y, 2, COL_FOREGROUND, COL_FOREGROUND);
3600 }
3601
3602 static int boxes_intersect(int x0, int y0, int w0, int h0,
3603                            int x1, int y1, int w1, int h1)
3604 {
3605     /*
3606      * Two intervals intersect iff neither is wholly on one side of
3607      * the other. Two boxes intersect iff their horizontal and
3608      * vertical intervals both intersect.
3609      */
3610     return (x0 < x1+w1 && x1 < x0+w0 && y0 < y1+h1 && y1 < y0+h0);
3611 }
3612
3613 static void game_redraw_in_rect(drawing *dr, game_drawstate *ds,
3614                                 game_state *state, int x, int y, int w, int h)
3615 {
3616     grid *g = state->game_grid;
3617     int i, phase;
3618     int bx, by, bw, bh;
3619
3620     clip(dr, x, y, w, h);
3621     draw_rect(dr, x, y, w, h, COL_BACKGROUND);
3622
3623     for (i = 0; i < g->num_faces; i++) {
3624         if (state->clues[i] >= 0) {
3625             face_text_bbox(ds, g, &g->faces[i], &bx, &by, &bw, &bh);
3626             if (boxes_intersect(x, y, w, h, bx, by, bw, bh))
3627                 game_redraw_clue(dr, ds, state, i);
3628         }
3629     }
3630     for (phase = 0; phase < NPHASES; phase++) {
3631         for (i = 0; i < g->num_edges; i++) {
3632             edge_bbox(ds, g, &g->edges[i], &bx, &by, &bw, &bh);
3633             if (boxes_intersect(x, y, w, h, bx, by, bw, bh))
3634                 game_redraw_line(dr, ds, state, i, phase);
3635         }
3636     }
3637     for (i = 0; i < g->num_dots; i++) {
3638         dot_bbox(ds, g, &g->dots[i], &bx, &by, &bw, &bh);
3639         if (boxes_intersect(x, y, w, h, bx, by, bw, bh))
3640             game_redraw_dot(dr, ds, state, i);
3641     }
3642
3643     unclip(dr);
3644     draw_update(dr, x, y, w, h);
3645 }
3646
3647 static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
3648                         game_state *state, int dir, game_ui *ui,
3649                         float animtime, float flashtime)
3650 {
3651 #define REDRAW_OBJECTS_LIMIT 16         /* Somewhat arbitrary tradeoff */
3652
3653     grid *g = state->game_grid;
3654     int border = BORDER(ds->tilesize);
3655     int i;
3656     int flash_changed;
3657     int redraw_everything = FALSE;
3658
3659     int edges[REDRAW_OBJECTS_LIMIT], nedges = 0;
3660     int faces[REDRAW_OBJECTS_LIMIT], nfaces = 0;
3661
3662     /* Redrawing is somewhat involved.
3663      *
3664      * An update can theoretically affect an arbitrary number of edges
3665      * (consider, for example, completing or breaking a cycle which doesn't
3666      * satisfy all the clues -- we'll switch many edges between error and
3667      * normal states).  On the other hand, redrawing the whole grid takes a
3668      * while, making the game feel sluggish, and many updates are actually
3669      * quite well localized.
3670      *
3671      * This redraw algorithm attempts to cope with both situations gracefully
3672      * and correctly.  For localized changes, we set a clip rectangle, fill
3673      * it with background, and then redraw (a plausible but conservative
3674      * guess at) the objects which intersect the rectangle; if several
3675      * objects need redrawing, we'll do them individually.  However, if lots
3676      * of objects are affected, we'll just redraw everything.
3677      *
3678      * The reason for all of this is that it's just not safe to do the redraw
3679      * piecemeal.  If you try to draw an antialiased diagonal line over
3680      * itself, you get a slightly thicker antialiased diagonal line, which
3681      * looks rather ugly after a while.
3682      *
3683      * So, we take two passes over the grid.  The first attempts to work out
3684      * what needs doing, and the second actually does it.
3685      */
3686
3687     if (!ds->started)
3688         redraw_everything = TRUE;
3689     else {
3690
3691         /* First, trundle through the faces. */
3692         for (i = 0; i < g->num_faces; i++) {
3693             grid_face *f = g->faces + i;
3694             int sides = f->order;
3695             int clue_mistake;
3696             int clue_satisfied;
3697             int n = state->clues[i];
3698             if (n < 0)
3699                 continue;
3700
3701             clue_mistake = (face_order(state, i, LINE_YES) > n ||
3702                             face_order(state, i, LINE_NO ) > (sides-n));
3703             clue_satisfied = (face_order(state, i, LINE_YES) == n &&
3704                               face_order(state, i, LINE_NO ) == (sides-n));
3705
3706             if (clue_mistake != ds->clue_error[i] ||
3707                 clue_satisfied != ds->clue_satisfied[i]) {
3708                 ds->clue_error[i] = clue_mistake;
3709                 ds->clue_satisfied[i] = clue_satisfied;
3710                 if (nfaces == REDRAW_OBJECTS_LIMIT)
3711                     redraw_everything = TRUE;
3712                 else
3713                     faces[nfaces++] = i;
3714             }
3715         }
3716
3717         /* Work out what the flash state needs to be. */
3718         if (flashtime > 0 &&
3719             (flashtime <= FLASH_TIME/3 ||
3720              flashtime >= FLASH_TIME*2/3)) {
3721             flash_changed = !ds->flashing;
3722             ds->flashing = TRUE;
3723         } else {
3724             flash_changed = ds->flashing;
3725             ds->flashing = FALSE;
3726         }
3727
3728         /* Now, trundle through the edges. */
3729         for (i = 0; i < g->num_edges; i++) {
3730             char new_ds =
3731                 state->line_errors[i] ? DS_LINE_ERROR : state->lines[i];
3732             if (new_ds != ds->lines[i] ||
3733                 (flash_changed && state->lines[i] == LINE_YES)) {
3734                 ds->lines[i] = new_ds;
3735                 if (nedges == REDRAW_OBJECTS_LIMIT)
3736                     redraw_everything = TRUE;
3737                 else
3738                     edges[nedges++] = i;
3739             }
3740         }
3741     }
3742
3743     /* Pass one is now done.  Now we do the actual drawing. */
3744     if (redraw_everything) {
3745         int grid_width = g->highest_x - g->lowest_x;
3746         int grid_height = g->highest_y - g->lowest_y;
3747         int w = grid_width * ds->tilesize / g->tilesize;
3748         int h = grid_height * ds->tilesize / g->tilesize;
3749
3750         game_redraw_in_rect(dr, ds, state,
3751                             0, 0, w + 2*border + 1, h + 2*border + 1);
3752     } else {
3753
3754         /* Right.  Now we roll up our sleeves. */
3755
3756         for (i = 0; i < nfaces; i++) {
3757             grid_face *f = g->faces + faces[i];
3758             int x, y, w, h;
3759
3760             face_text_bbox(ds, g, f, &x, &y, &w, &h);
3761             game_redraw_in_rect(dr, ds, state, x, y, w, h);
3762         }
3763
3764         for (i = 0; i < nedges; i++) {
3765             grid_edge *e = g->edges + edges[i];
3766             int x, y, w, h;
3767
3768             edge_bbox(ds, g, e, &x, &y, &w, &h);
3769             game_redraw_in_rect(dr, ds, state, x, y, w, h);
3770         }
3771     }
3772
3773     ds->started = TRUE;
3774 }
3775
3776 static float game_flash_length(game_state *oldstate, game_state *newstate,
3777                                int dir, game_ui *ui)
3778 {
3779     if (!oldstate->solved  &&  newstate->solved &&
3780         !oldstate->cheated && !newstate->cheated) {
3781         return FLASH_TIME;
3782     }
3783
3784     return 0.0F;
3785 }
3786
3787 static int game_is_solved(game_state *state)
3788 {
3789     return state->solved;
3790 }
3791
3792 static void game_print_size(game_params *params, float *x, float *y)
3793 {
3794     int pw, ph;
3795
3796     /*
3797      * I'll use 7mm "squares" by default.
3798      */
3799     game_compute_size(params, 700, &pw, &ph);
3800     *x = pw / 100.0F;
3801     *y = ph / 100.0F;
3802 }
3803
3804 static void game_print(drawing *dr, game_state *state, int tilesize)
3805 {
3806     int ink = print_mono_colour(dr, 0);
3807     int i;
3808     game_drawstate ads, *ds = &ads;
3809     grid *g = state->game_grid;
3810
3811     ds->tilesize = tilesize;
3812
3813     for (i = 0; i < g->num_dots; i++) {
3814         int x, y;
3815         grid_to_screen(ds, g, g->dots[i].x, g->dots[i].y, &x, &y);
3816         draw_circle(dr, x, y, ds->tilesize / 15, ink, ink);
3817     }
3818
3819     /*
3820      * Clues.
3821      */
3822     for (i = 0; i < g->num_faces; i++) {
3823         grid_face *f = g->faces + i;
3824         int clue = state->clues[i];
3825         if (clue >= 0) {
3826             char c[2];
3827             int x, y;
3828             c[0] = CLUE2CHAR(clue);
3829             c[1] = '\0';
3830             face_text_pos(ds, g, f, &x, &y);
3831             draw_text(dr, x, y,
3832                       FONT_VARIABLE, ds->tilesize / 2,
3833                       ALIGN_VCENTRE | ALIGN_HCENTRE, ink, c);
3834         }
3835     }
3836
3837     /*
3838      * Lines.
3839      */
3840     for (i = 0; i < g->num_edges; i++) {
3841         int thickness = (state->lines[i] == LINE_YES) ? 30 : 150;
3842         grid_edge *e = g->edges + i;
3843         int x1, y1, x2, y2;
3844         grid_to_screen(ds, g, e->dot1->x, e->dot1->y, &x1, &y1);
3845         grid_to_screen(ds, g, e->dot2->x, e->dot2->y, &x2, &y2);
3846         if (state->lines[i] == LINE_YES)
3847         {
3848             /* (dx, dy) points from (x1, y1) to (x2, y2).
3849              * The line is then "fattened" in a perpendicular
3850              * direction to create a thin rectangle. */
3851             double d = sqrt(SQ((double)x1 - x2) + SQ((double)y1 - y2));
3852             double dx = (x2 - x1) / d;
3853             double dy = (y2 - y1) / d;
3854             int points[8];
3855
3856             dx = (dx * ds->tilesize) / thickness;
3857             dy = (dy * ds->tilesize) / thickness;
3858             points[0] = x1 + (int)dy;
3859             points[1] = y1 - (int)dx;
3860             points[2] = x1 - (int)dy;
3861             points[3] = y1 + (int)dx;
3862             points[4] = x2 - (int)dy;
3863             points[5] = y2 + (int)dx;
3864             points[6] = x2 + (int)dy;
3865             points[7] = y2 - (int)dx;
3866             draw_polygon(dr, points, 4, ink, ink);
3867         }
3868         else
3869         {
3870             /* Draw a dotted line */
3871             int divisions = 6;
3872             int j;
3873             for (j = 1; j < divisions; j++) {
3874                 /* Weighted average */
3875                 int x = (x1 * (divisions -j) + x2 * j) / divisions;
3876                 int y = (y1 * (divisions -j) + y2 * j) / divisions;
3877                 draw_circle(dr, x, y, ds->tilesize / thickness, ink, ink);
3878             }
3879         }
3880     }
3881 }
3882
3883 #ifdef COMBINED
3884 #define thegame loopy
3885 #endif
3886
3887 const struct game thegame = {
3888     "Loopy", "games.loopy", "loopy",
3889     default_params,
3890     game_fetch_preset,
3891     decode_params,
3892     encode_params,
3893     free_params,
3894     dup_params,
3895     TRUE, game_configure, custom_params,
3896     validate_params,
3897     new_game_desc,
3898     validate_desc,
3899     new_game,
3900     dup_game,
3901     free_game,
3902     1, solve_game,
3903     TRUE, game_can_format_as_text_now, game_text_format,
3904     new_ui,
3905     free_ui,
3906     encode_ui,
3907     decode_ui,
3908     game_changed_state,
3909     interpret_move,
3910     execute_move,
3911     PREFERRED_TILE_SIZE, game_compute_size, game_set_size,
3912     game_colours,
3913     game_new_drawstate,
3914     game_free_drawstate,
3915     game_redraw,
3916     game_anim_length,
3917     game_flash_length,
3918     game_is_solved,
3919     TRUE, FALSE, game_print_size, game_print,
3920     FALSE /* wants_statusbar */,
3921     FALSE, game_timing_state,
3922     0,                                       /* mouse_priorities */
3923 };
3924
3925 #ifdef STANDALONE_SOLVER
3926
3927 /*
3928  * Half-hearted standalone solver. It can't output the solution to
3929  * anything but a square puzzle, and it can't log the deductions
3930  * it makes either. But it can solve square puzzles, and more
3931  * importantly it can use its solver to grade the difficulty of
3932  * any puzzle you give it.
3933  */
3934
3935 #include <stdarg.h>
3936
3937 int main(int argc, char **argv)
3938 {
3939     game_params *p;
3940     game_state *s;
3941     char *id = NULL, *desc, *err;
3942     int grade = FALSE;
3943     int ret, diff;
3944 #if 0 /* verbose solver not supported here (yet) */
3945     int really_verbose = FALSE;
3946 #endif
3947
3948     while (--argc > 0) {
3949         char *p = *++argv;
3950 #if 0 /* verbose solver not supported here (yet) */
3951         if (!strcmp(p, "-v")) {
3952             really_verbose = TRUE;
3953         } else
3954 #endif
3955         if (!strcmp(p, "-g")) {
3956             grade = TRUE;
3957         } else if (*p == '-') {
3958             fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
3959             return 1;
3960         } else {
3961             id = p;
3962         }
3963     }
3964
3965     if (!id) {
3966         fprintf(stderr, "usage: %s [-g | -v] <game_id>\n", argv[0]);
3967         return 1;
3968     }
3969
3970     desc = strchr(id, ':');
3971     if (!desc) {
3972         fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
3973         return 1;
3974     }
3975     *desc++ = '\0';
3976
3977     p = default_params();
3978     decode_params(p, id);
3979     err = validate_desc(p, desc);
3980     if (err) {
3981         fprintf(stderr, "%s: %s\n", argv[0], err);
3982         return 1;
3983     }
3984     s = new_game(NULL, p, desc);
3985
3986     /*
3987      * When solving an Easy puzzle, we don't want to bother the
3988      * user with Hard-level deductions. For this reason, we grade
3989      * the puzzle internally before doing anything else.
3990      */
3991     ret = -1;                          /* placate optimiser */
3992     for (diff = 0; diff < DIFF_MAX; diff++) {
3993         solver_state *sstate_new;
3994         solver_state *sstate = new_solver_state((game_state *)s, diff);
3995
3996         sstate_new = solve_game_rec(sstate);
3997
3998         if (sstate_new->solver_status == SOLVER_MISTAKE)
3999             ret = 0;
4000         else if (sstate_new->solver_status == SOLVER_SOLVED)
4001             ret = 1;
4002         else
4003             ret = 2;
4004
4005         free_solver_state(sstate_new);
4006         free_solver_state(sstate);
4007
4008         if (ret < 2)
4009             break;
4010     }
4011
4012     if (diff == DIFF_MAX) {
4013         if (grade)
4014             printf("Difficulty rating: harder than Hard, or ambiguous\n");
4015         else
4016             printf("Unable to find a unique solution\n");
4017     } else {
4018         if (grade) {
4019             if (ret == 0)
4020                 printf("Difficulty rating: impossible (no solution exists)\n");
4021             else if (ret == 1)
4022                 printf("Difficulty rating: %s\n", diffnames[diff]);
4023         } else {
4024             solver_state *sstate_new;
4025             solver_state *sstate = new_solver_state((game_state *)s, diff);
4026
4027             /* If we supported a verbose solver, we'd set verbosity here */
4028
4029             sstate_new = solve_game_rec(sstate);
4030
4031             if (sstate_new->solver_status == SOLVER_MISTAKE)
4032                 printf("Puzzle is inconsistent\n");
4033             else {
4034                 assert(sstate_new->solver_status == SOLVER_SOLVED);
4035                 if (s->grid_type == 0) {
4036                     fputs(game_text_format(sstate_new->state), stdout);
4037                 } else {
4038                     printf("Unable to output non-square grids\n");
4039                 }
4040             }
4041
4042             free_solver_state(sstate_new);
4043             free_solver_state(sstate);
4044         }
4045     }
4046
4047     return 0;
4048 }
4049
4050 #endif
4051
4052 /* vim: set shiftwidth=4 tabstop=8: */