chiark / gitweb /
Since the lack of this has caused portability issues in the past:
[sgt-puzzles.git] / tents.c
1 /*
2  * tents.c: Puzzle involving placing tents next to trees subject to
3  * some confusing conditions.
4  * 
5  * TODO:
6  * 
7  *  - error highlighting?
8  *     * highlighting adjacent tents is easy
9  *     * highlighting violated numeric clues is almost as easy
10  *       (might want to pay attention to NONTENTs here)
11  *     * but how in hell do we highlight a failure of maxflow
12  *       during completion checking?
13  *        + well, the _obvious_ approach is to use maxflow's own
14  *          error report: it will provide, via the `cut' parameter,
15  *          a set of trees which have too few tents between them.
16  *          It's unclear that this will be particularly obvious to
17  *          a user, however. Is there any other way?
18  * 
19  *  - it might be nice to make setter-provided tent/nontent clues
20  *    inviolable?
21  *     * on the other hand, this would introduce considerable extra
22  *       complexity and size into the game state; also inviolable
23  *       clues would have to be marked as such somehow, in an
24  *       intrusive and annoying manner. Since they're never
25  *       generated by _my_ generator, I'm currently more inclined
26  *       not to bother.
27  * 
28  *  - more difficult levels at the top end?
29  *     * for example, sometimes we can deduce that two BLANKs in
30  *       the same row are each adjacent to the same unattached tree
31  *       and to nothing else, implying that they can't both be
32  *       tents; this enables us to rule out some extra combinations
33  *       in the row-based deduction loop, and hence deduce more
34  *       from the number in that row than we could otherwise do.
35  *     * that by itself doesn't seem worth implementing a new
36  *       difficulty level for, but if I can find a few more things
37  *       like that then it might become worthwhile.
38  *     * I wonder if there's a sensible heuristic for where to
39  *       guess which would make a recursive solver viable?
40  */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <assert.h>
46 #include <ctype.h>
47 #include <math.h>
48
49 #include "puzzles.h"
50 #include "maxflow.h"
51
52 /*
53  * Design discussion
54  * -----------------
55  * 
56  * The rules of this puzzle as available on the WWW are poorly
57  * specified. The bits about tents having to be orthogonally
58  * adjacent to trees, tents not being even diagonally adjacent to
59  * one another, and the number of tents in each row and column
60  * being given are simple enough; the difficult bit is the
61  * tent-to-tree matching.
62  * 
63  * Some sources use simplistic wordings such as `each tree is
64  * exactly connected to only one tent', which is extremely unclear:
65  * it's easy to read erroneously as `each tree is _orthogonally
66  * adjacent_ to exactly one tent', which is definitely incorrect.
67  * Even the most coherent sources I've found don't do a much better
68  * job of stating the rule.
69  * 
70  * A more precise statement of the rule is that it must be possible
71  * to find a bijection f between tents and trees such that each
72  * tree T is orthogonally adjacent to the tent f(T), but that a
73  * tent is permitted to be adjacent to other trees in addition to
74  * its own. This slightly non-obvious criterion is what gives this
75  * puzzle most of its subtlety.
76  * 
77  * However, there's a particularly subtle ambiguity left over. Is
78  * the bijection between tents and trees required to be _unique_?
79  * In other words, is that bijection conceptually something the
80  * player should be able to exhibit as part of the solution (even
81  * if they aren't actually required to do so)? Or is it sufficient
82  * to have a unique _placement_ of the tents which gives rise to at
83  * least one suitable bijection?
84  * 
85  * The puzzle shown to the right of this       .T. 2      *T* 2
86  * paragraph illustrates the problem. There    T.T 0  ->  T-T 0
87  * are two distinct bijections available.      .T. 2      *T* 2
88  * The answer to the above question will
89  * determine whether it's a valid puzzle.      202        202
90  * 
91  * This is an important question, because it affects both the
92  * player and the generator. Eventually I found all the instances
93  * of this puzzle I could Google up, solved them all by hand, and
94  * verified that in all cases the tree/tent matching was uniquely
95  * determined given the tree and tent positions. Therefore, the
96  * puzzle as implemented in this source file takes the following
97  * policy:
98  * 
99  *  - When checking a user-supplied solution for correctness, only
100  *    verify that there exists _at least_ one matching.
101  *  - When generating a puzzle, enforce that there must be
102  *    _exactly_ one.
103  * 
104  * Algorithmic implications
105  * ------------------------
106  * 
107  * Another way of phrasing the tree/tent matching criterion is to
108  * say that the bipartite adjacency graph between trees and tents
109  * has a perfect matching. That is, if you construct a graph which
110  * has a vertex per tree and a vertex per tent, and an edge between
111  * any tree and tent which are orthogonally adjacent, it is
112  * possible to find a set of N edges of that graph (where N is the
113  * number of trees and also the number of tents) which between them
114  * connect every tree to every tent.
115  * 
116  * The most efficient known algorithms for finding such a matching
117  * given a graph, as far as I'm aware, are the Munkres assignment
118  * algorithm (also known as the Hungarian algorithm) and the
119  * Ford-Fulkerson algorithm (for finding optimal flows in
120  * networks). Each of these takes O(N^3) running time; so we're
121  * talking O(N^3) time to verify any candidate solution to this
122  * puzzle. That's just about OK if you're doing it once per mouse
123  * click (and in fact not even that, since the sensible thing to do
124  * is check all the _other_ puzzle criteria and only wade into this
125  * quagmire if none are violated); but if the solver had to keep
126  * doing N^3 work internally, then it would probably end up with
127  * more like N^5 or N^6 running time, and grid generation would
128  * become very clunky.
129  * 
130  * Fortunately, I've been able to prove a very useful property of
131  * _unique_ perfect matchings, by adapting the proof of Hall's
132  * Marriage Theorem. For those unaware of Hall's Theorem, I'll
133  * recap it and its proof: it states that a bipartite graph
134  * contains a perfect matching iff every set of vertices on the
135  * left side of the graph have a neighbourhood _at least_ as big on
136  * the right.
137  * 
138  * This condition is obviously satisfied if a perfect matching does
139  * exist; each left-side node has a distinct right-side node which
140  * is the one assigned to it by the matching, and thus any set of n
141  * left vertices must have a combined neighbourhood containing at
142  * least the n corresponding right vertices, and possibly others
143  * too. Alternatively, imagine if you had (say) three left-side
144  * nodes all of which were connected to only two right-side nodes
145  * between them: any perfect matching would have to assign one of
146  * those two right nodes to each of the three left nodes, and still
147  * give the three left nodes a different right node each. This is
148  * of course impossible.
149  *
150  * To prove the converse (that if every subset of left vertices
151  * satisfies the Hall condition then a perfect matching exists),
152  * consider trying to find a proper subset of the left vertices
153  * which _exactly_ satisfies the Hall condition: that is, its right
154  * neighbourhood is precisely the same size as it. If we can find
155  * such a subset, then we can split the bipartite graph into two
156  * smaller ones: one consisting of the left subset and its right
157  * neighbourhood, the other consisting of everything else. Edges
158  * from the left side of the former graph to the right side of the
159  * latter do not exist, by construction; edges from the right side
160  * of the former to the left of the latter cannot be part of any
161  * perfect matching because otherwise the left subset would not be
162  * left with enough distinct right vertices to connect to (this is
163  * exactly the same deduction used in Solo's set analysis). You can
164  * then prove (left as an exercise) that both these smaller graphs
165  * still satisfy the Hall condition, and therefore the proof will
166  * follow by induction.
167  * 
168  * There's one other possibility, which is the case where _no_
169  * proper subset of the left vertices has a right neighbourhood of
170  * exactly the same size. That is, every left subset has a strictly
171  * _larger_ right neighbourhood. In this situation, we can simply
172  * remove an _arbitrary_ edge from the graph. This cannot reduce
173  * the size of any left subset's right neighbourhood by more than
174  * one, so if all neighbourhoods were strictly bigger than they
175  * needed to be initially, they must now still be _at least as big_
176  * as they need to be. So we can keep throwing out arbitrary edges
177  * until we find a set which exactly satisfies the Hall condition,
178  * and then proceed as above. []
179  * 
180  * That's Hall's theorem. I now build on this by examining the
181  * circumstances in which a bipartite graph can have a _unique_
182  * perfect matching. It is clear that in the second case, where no
183  * left subset exactly satisfies the Hall condition and so we can
184  * remove an arbitrary edge, there cannot be a unique perfect
185  * matching: given one perfect matching, we choose our arbitrary
186  * removed edge to be one of those contained in it, and then we can
187  * still find a perfect matching in the remaining graph, which will
188  * be a distinct perfect matching in the original.
189  * 
190  * So it is a necessary condition for a unique perfect matching
191  * that there must be at least one proper left subset which
192  * _exactly_ satisfies the Hall condition. But now consider the
193  * smaller graph constructed by taking that left subset and its
194  * neighbourhood: if the graph as a whole had a unique perfect
195  * matching, then so must this smaller one, which means we can find
196  * a proper left subset _again_, and so on. Repeating this process
197  * must eventually reduce us to a graph with only one left-side
198  * vertex (so there are no proper subsets at all); this vertex must
199  * be connected to only one right-side vertex, and hence must be so
200  * in the original graph as well (by construction). So we can
201  * discard this vertex pair from the graph, and any other edges
202  * that involved it (which will by construction be from other left
203  * vertices only), and the resulting smaller graph still has a
204  * unique perfect matching which means we can do the same thing
205  * again.
206  * 
207  * In other words, given any bipartite graph with a unique perfect
208  * matching, we can find that matching by the following extremely
209  * simple algorithm:
210  * 
211  *  - Find a left-side vertex which is only connected to one
212  *    right-side vertex.
213  *  - Assign those vertices to one another, and therefore discard
214  *    any other edges connecting to that right vertex.
215  *  - Repeat until all vertices have been matched.
216  * 
217  * This algorithm can be run in O(V+E) time (where V is the number
218  * of vertices and E is the number of edges in the graph), and the
219  * only way it can fail is if there is not a unique perfect
220  * matching (either because there is no matching at all, or because
221  * it isn't unique; but it can't distinguish those cases).
222  * 
223  * Thus, the internal solver in this source file can be confident
224  * that if the tree/tent matching is uniquely determined by the
225  * tree and tent positions, it can find it using only this kind of
226  * obvious and simple operation: assign a tree to a tent if it
227  * cannot possibly belong to any other tent, and vice versa. If the
228  * solver were _only_ trying to determine the matching, even that
229  * `vice versa' wouldn't be required; but it can come in handy when
230  * not all the tents have been placed yet. I can therefore be
231  * reasonably confident that as long as my solver doesn't need to
232  * cope with grids that have a non-unique matching, it will also
233  * not need to do anything complicated like set analysis between
234  * trees and tents.
235  */
236
237 /*
238  * In standalone solver mode, `verbose' is a variable which can be
239  * set by command-line option; in debugging mode it's simply always
240  * true.
241  */
242 #if defined STANDALONE_SOLVER
243 #define SOLVER_DIAGNOSTICS
244 int verbose = FALSE;
245 #elif defined SOLVER_DIAGNOSTICS
246 #define verbose TRUE
247 #endif
248
249 /*
250  * Difficulty levels. I do some macro ickery here to ensure that my
251  * enum and the various forms of my name list always match up.
252  */
253 #define DIFFLIST(A) \
254     A(EASY,Easy,e) \
255     A(TRICKY,Tricky,t)
256 #define ENUM(upper,title,lower) DIFF_ ## upper,
257 #define TITLE(upper,title,lower) #title,
258 #define ENCODE(upper,title,lower) #lower
259 #define CONFIG(upper,title,lower) ":" #title
260 enum { DIFFLIST(ENUM) DIFFCOUNT };
261 static char const *const tents_diffnames[] = { DIFFLIST(TITLE) };
262 static char const tents_diffchars[] = DIFFLIST(ENCODE);
263 #define DIFFCONFIG DIFFLIST(CONFIG)
264
265 enum {
266     COL_BACKGROUND,
267     COL_GRID,
268     COL_GRASS,
269     COL_TREETRUNK,
270     COL_TREELEAF,
271     COL_TENT,
272     NCOLOURS
273 };
274
275 enum { BLANK, TREE, TENT, NONTENT, MAGIC };
276
277 struct game_params {
278     int w, h;
279     int diff;
280 };
281
282 struct numbers {
283     int refcount;
284     int *numbers;
285 };
286
287 struct game_state {
288     game_params p;
289     char *grid;
290     struct numbers *numbers;
291     int completed, used_solve;
292 };
293
294 static game_params *default_params(void)
295 {
296     game_params *ret = snew(game_params);
297
298     ret->w = ret->h = 8;
299     ret->diff = DIFF_EASY;
300
301     return ret;
302 }
303
304 static const struct game_params tents_presets[] = {
305     {8, 8, DIFF_EASY},
306     {8, 8, DIFF_TRICKY},
307     {10, 10, DIFF_EASY},
308     {10, 10, DIFF_TRICKY},
309     {15, 15, DIFF_EASY},
310     {15, 15, DIFF_TRICKY},
311 };
312
313 static int game_fetch_preset(int i, char **name, game_params **params)
314 {
315     game_params *ret;
316     char str[80];
317
318     if (i < 0 || i >= lenof(tents_presets))
319         return FALSE;
320
321     ret = snew(game_params);
322     *ret = tents_presets[i];
323
324     sprintf(str, "%dx%d %s", ret->w, ret->h, tents_diffnames[ret->diff]);
325
326     *name = dupstr(str);
327     *params = ret;
328     return TRUE;
329 }
330
331 static void free_params(game_params *params)
332 {
333     sfree(params);
334 }
335
336 static game_params *dup_params(game_params *params)
337 {
338     game_params *ret = snew(game_params);
339     *ret = *params;                    /* structure copy */
340     return ret;
341 }
342
343 static void decode_params(game_params *params, char const *string)
344 {
345     params->w = params->h = atoi(string);
346     while (*string && isdigit((unsigned char)*string)) string++;
347     if (*string == 'x') {
348         string++;
349         params->h = atoi(string);
350         while (*string && isdigit((unsigned char)*string)) string++;
351     }
352     if (*string == 'd') {
353         int i;
354         string++;
355         for (i = 0; i < DIFFCOUNT; i++)
356             if (*string == tents_diffchars[i])
357                 params->diff = i;
358         if (*string) string++;
359     }
360 }
361
362 static char *encode_params(game_params *params, int full)
363 {
364     char buf[120];
365
366     sprintf(buf, "%dx%d", params->w, params->h);
367     if (full)
368         sprintf(buf + strlen(buf), "d%c",
369                 tents_diffchars[params->diff]);
370     return dupstr(buf);
371 }
372
373 static config_item *game_configure(game_params *params)
374 {
375     config_item *ret;
376     char buf[80];
377
378     ret = snewn(4, config_item);
379
380     ret[0].name = "Width";
381     ret[0].type = C_STRING;
382     sprintf(buf, "%d", params->w);
383     ret[0].sval = dupstr(buf);
384     ret[0].ival = 0;
385
386     ret[1].name = "Height";
387     ret[1].type = C_STRING;
388     sprintf(buf, "%d", params->h);
389     ret[1].sval = dupstr(buf);
390     ret[1].ival = 0;
391
392     ret[2].name = "Difficulty";
393     ret[2].type = C_CHOICES;
394     ret[2].sval = DIFFCONFIG;
395     ret[2].ival = params->diff;
396
397     ret[3].name = NULL;
398     ret[3].type = C_END;
399     ret[3].sval = NULL;
400     ret[3].ival = 0;
401
402     return ret;
403 }
404
405 static game_params *custom_params(config_item *cfg)
406 {
407     game_params *ret = snew(game_params);
408
409     ret->w = atoi(cfg[0].sval);
410     ret->h = atoi(cfg[1].sval);
411     ret->diff = cfg[2].ival;
412
413     return ret;
414 }
415
416 static char *validate_params(game_params *params, int full)
417 {
418     /*
419      * Generating anything under 4x4 runs into trouble of one kind
420      * or another.
421      */
422     if (params->w < 4 || params->h < 4)
423         return "Width and height must both be at least four";
424     return NULL;
425 }
426
427 /*
428  * Scratch space for solver.
429  */
430 enum { N, U, L, R, D, MAXDIR };        /* link directions */
431 #define dx(d) ( ((d)==R) - ((d)==L) )
432 #define dy(d) ( ((d)==D) - ((d)==U) )
433 #define F(d) ( U + D - (d) )
434 struct solver_scratch {
435     char *links;                       /* mapping between trees and tents */
436     int *locs;
437     char *place, *mrows, *trows;
438 };
439
440 static struct solver_scratch *new_scratch(int w, int h)
441 {
442     struct solver_scratch *ret = snew(struct solver_scratch);
443
444     ret->links = snewn(w*h, char);
445     ret->locs = snewn(max(w, h), int);
446     ret->place = snewn(max(w, h), char);
447     ret->mrows = snewn(3 * max(w, h), char);
448     ret->trows = snewn(3 * max(w, h), char);
449
450     return ret;
451 }
452
453 static void free_scratch(struct solver_scratch *sc)
454 {
455     sfree(sc->trows);
456     sfree(sc->mrows);
457     sfree(sc->place);
458     sfree(sc->locs);
459     sfree(sc->links);
460     sfree(sc);
461 }
462
463 /*
464  * Solver. Returns 0 for impossibility, 1 for success, 2 for
465  * ambiguity or failure to converge.
466  */
467 static int tents_solve(int w, int h, const char *grid, int *numbers,
468                        char *soln, struct solver_scratch *sc, int diff)
469 {
470     int x, y, d, i, j;
471     char *mrow, *mrow1, *mrow2, *trow, *trow1, *trow2;
472
473     /*
474      * Set up solver data.
475      */
476     memset(sc->links, N, w*h);
477
478     /*
479      * Set up solution array.
480      */
481     memcpy(soln, grid, w*h);
482
483     /*
484      * Main solver loop.
485      */
486     while (1) {
487         int done_something = FALSE;
488
489         /*
490          * Any tent which has only one unattached tree adjacent to
491          * it can be tied to that tree.
492          */
493         for (y = 0; y < h; y++)
494             for (x = 0; x < w; x++)
495                 if (soln[y*w+x] == TENT && !sc->links[y*w+x]) {
496                     int linkd = 0;
497
498                     for (d = 1; d < MAXDIR; d++) {
499                         int x2 = x + dx(d), y2 = y + dy(d);
500                         if (x2 >= 0 && x2 < w && y2 >= 0 && y2 < h &&
501                             soln[y2*w+x2] == TREE &&
502                             !sc->links[y2*w+x2]) {
503                             if (linkd)
504                                 break; /* found more than one */
505                             else
506                                 linkd = d;
507                         }
508                     }
509
510                     if (d == MAXDIR && linkd == 0) {
511 #ifdef SOLVER_DIAGNOSTICS
512                         if (verbose)
513                             printf("tent at %d,%d cannot link to anything\n",
514                                    x, y);
515 #endif
516                         return 0;      /* no solution exists */
517                     } else if (d == MAXDIR) {
518                         int x2 = x + dx(linkd), y2 = y + dy(linkd);
519
520 #ifdef SOLVER_DIAGNOSTICS
521                         if (verbose)
522                             printf("tent at %d,%d can only link to tree at"
523                                    " %d,%d\n", x, y, x2, y2);
524 #endif
525
526                         sc->links[y*w+x] = linkd;
527                         sc->links[y2*w+x2] = F(linkd);
528                         done_something = TRUE;
529                     }
530                 }
531
532         if (done_something)
533             continue;
534         if (diff < 0)
535             break;                     /* don't do anything else! */
536
537         /*
538          * Mark a blank square as NONTENT if it is not orthogonally
539          * adjacent to any unmatched tree.
540          */
541         for (y = 0; y < h; y++)
542             for (x = 0; x < w; x++)
543                 if (soln[y*w+x] == BLANK) {
544                     int can_be_tent = FALSE;
545
546                     for (d = 1; d < MAXDIR; d++) {
547                         int x2 = x + dx(d), y2 = y + dy(d);
548                         if (x2 >= 0 && x2 < w && y2 >= 0 && y2 < h &&
549                             soln[y2*w+x2] == TREE &&
550                             !sc->links[y2*w+x2])
551                             can_be_tent = TRUE;
552                     }
553
554                     if (!can_be_tent) {
555 #ifdef SOLVER_DIAGNOSTICS
556                         if (verbose)
557                             printf("%d,%d cannot be a tent (no adjacent"
558                                    " unmatched tree)\n", x, y);
559 #endif
560                         soln[y*w+x] = NONTENT;
561                         done_something = TRUE;
562                     }
563                 }
564
565         if (done_something)
566             continue;
567
568         /*
569          * Mark a blank square as NONTENT if it is (perhaps
570          * diagonally) adjacent to any other tent.
571          */
572         for (y = 0; y < h; y++)
573             for (x = 0; x < w; x++)
574                 if (soln[y*w+x] == BLANK) {
575                     int dx, dy, imposs = FALSE;
576
577                     for (dy = -1; dy <= +1; dy++)
578                         for (dx = -1; dx <= +1; dx++)
579                             if (dy || dx) {
580                                 int x2 = x + dx, y2 = y + dy;
581                                 if (x2 >= 0 && x2 < w && y2 >= 0 && y2 < h &&
582                                     soln[y2*w+x2] == TENT)
583                                     imposs = TRUE;
584                             }
585
586                     if (imposs) {
587 #ifdef SOLVER_DIAGNOSTICS
588                         if (verbose)
589                             printf("%d,%d cannot be a tent (adjacent tent)\n",
590                                    x, y);
591 #endif
592                         soln[y*w+x] = NONTENT;
593                         done_something = TRUE;
594                     }
595                 }
596
597         if (done_something)
598             continue;
599
600         /*
601          * Any tree which has exactly one {unattached tent, BLANK}
602          * adjacent to it must have its tent in that square.
603          */
604         for (y = 0; y < h; y++)
605             for (x = 0; x < w; x++)
606                 if (soln[y*w+x] == TREE && !sc->links[y*w+x]) {
607                     int linkd = 0, linkd2 = 0, nd = 0;
608
609                     for (d = 1; d < MAXDIR; d++) {
610                         int x2 = x + dx(d), y2 = y + dy(d);
611                         if (!(x2 >= 0 && x2 < w && y2 >= 0 && y2 < h))
612                             continue;
613                         if (soln[y2*w+x2] == BLANK ||
614                             (soln[y2*w+x2] == TENT && !sc->links[y2*w+x2])) {
615                             if (linkd)
616                                 linkd2 = d;
617                             else
618                                 linkd = d;
619                             nd++;
620                         }
621                     }
622
623                     if (nd == 0) {
624 #ifdef SOLVER_DIAGNOSTICS
625                         if (verbose)
626                             printf("tree at %d,%d cannot link to anything\n",
627                                    x, y);
628 #endif
629                         return 0;      /* no solution exists */
630                     } else if (nd == 1) {
631                         int x2 = x + dx(linkd), y2 = y + dy(linkd);
632
633 #ifdef SOLVER_DIAGNOSTICS
634                         if (verbose)
635                             printf("tree at %d,%d can only link to tent at"
636                                    " %d,%d\n", x, y, x2, y2);
637 #endif
638                         soln[y2*w+x2] = TENT;
639                         sc->links[y*w+x] = linkd;
640                         sc->links[y2*w+x2] = F(linkd);
641                         done_something = TRUE;
642                     } else if (nd == 2 && (!dx(linkd) != !dx(linkd2)) &&
643                                diff >= DIFF_TRICKY) {
644                         /*
645                          * If there are two possible places where
646                          * this tree's tent can go, and they are
647                          * diagonally separated rather than being
648                          * on opposite sides of the tree, then the
649                          * square (other than the tree square)
650                          * which is adjacent to both of them must
651                          * be a non-tent.
652                          */
653                         int x2 = x + dx(linkd) + dx(linkd2);
654                         int y2 = y + dy(linkd) + dy(linkd2);
655                         assert(x2 >= 0 && x2 < w && y2 >= 0 && y2 < h);
656                         if (soln[y2*w+x2] == BLANK) {
657 #ifdef SOLVER_DIAGNOSTICS
658                             if (verbose)
659                                 printf("possible tent locations for tree at"
660                                        " %d,%d rule out tent at %d,%d\n",
661                                        x, y, x2, y2);
662 #endif
663                             soln[y2*w+x2] = NONTENT;
664                             done_something = TRUE;
665                         }
666                     }
667                 }
668
669         if (done_something)
670             continue;
671
672         /*
673          * If localised deductions about the trees and tents
674          * themselves haven't helped us, it's time to resort to the
675          * numbers round the grid edge. For each row and column, we
676          * go through all possible combinations of locations for
677          * the unplaced tents, rule out any which have adjacent
678          * tents, and spot any square which is given the same state
679          * by all remaining combinations.
680          */
681         for (i = 0; i < w+h; i++) {
682             int start, step, len, start1, start2, n, k;
683
684             if (i < w) {
685                 /*
686                  * This is the number for a column.
687                  */
688                 start = i;
689                 step = w;
690                 len = h;
691                 if (i > 0)
692                     start1 = start - 1;
693                 else
694                     start1 = -1;
695                 if (i+1 < w)
696                     start2 = start + 1;
697                 else
698                     start2 = -1;
699             } else {
700                 /*
701                  * This is the number for a row.
702                  */
703                 start = (i-w)*w;
704                 step = 1;
705                 len = w;
706                 if (i > w)
707                     start1 = start - w;
708                 else
709                     start1 = -1;
710                 if (i+1 < w+h)
711                     start2 = start + w;
712                 else
713                     start2 = -1;
714             }
715
716             if (diff < DIFF_TRICKY) {
717                 /*
718                  * In Easy mode, we don't look at the effect of one
719                  * row on the next (i.e. ruling out a square if all
720                  * possibilities for an adjacent row place a tent
721                  * next to it).
722                  */
723                 start1 = start2 = -1;
724             }
725
726             k = numbers[i];
727
728             /*
729              * Count and store the locations of the free squares,
730              * and also count the number of tents already placed.
731              */
732             n = 0;
733             for (j = 0; j < len; j++) {
734                 if (soln[start+j*step] == TENT)
735                     k--;               /* one fewer tent to place */
736                 else if (soln[start+j*step] == BLANK)
737                     sc->locs[n++] = j;
738             }
739
740             if (n == 0)
741                 continue;              /* nothing left to do here */
742
743             /*
744              * Now we know we're placing k tents in n squares. Set
745              * up the first possibility.
746              */
747             for (j = 0; j < n; j++)
748                 sc->place[j] = (j < k ? TENT : NONTENT);
749
750             /*
751              * We're aiming to find squares in this row which are
752              * invariant over all valid possibilities. Thus, we
753              * maintain the current state of that invariance. We
754              * start everything off at MAGIC to indicate that it
755              * hasn't been set up yet.
756              */
757             mrow = sc->mrows;
758             mrow1 = sc->mrows + len;
759             mrow2 = sc->mrows + 2*len;
760             trow = sc->trows;
761             trow1 = sc->trows + len;
762             trow2 = sc->trows + 2*len;
763             memset(mrow, MAGIC, 3*len);
764
765             /*
766              * And iterate over all possibilities.
767              */
768             while (1) {
769                 int p, valid;
770
771                 /*
772                  * See if this possibility is valid. The only way
773                  * it can fail to be valid is if it contains two
774                  * adjacent tents. (Other forms of invalidity, such
775                  * as containing a tent adjacent to one already
776                  * placed, will have been dealt with already by
777                  * other parts of the solver.)
778                  */
779                 valid = TRUE;
780                 for (j = 0; j+1 < n; j++)
781                     if (sc->place[j] == TENT &&
782                         sc->place[j+1] == TENT &&
783                         sc->locs[j+1] == sc->locs[j]+1) {
784                         valid = FALSE;
785                         break;
786                     }
787
788                 if (valid) {
789                     /*
790                      * Merge this valid combination into mrow.
791                      */
792                     memset(trow, MAGIC, len);
793                     memset(trow+len, BLANK, 2*len);
794                     for (j = 0; j < n; j++) {
795                         trow[sc->locs[j]] = sc->place[j];
796                         if (sc->place[j] == TENT) {
797                             int jj;
798                             for (jj = sc->locs[j]-1; jj <= sc->locs[j]+1; jj++)
799                                 if (jj >= 0 && jj < len)
800                                     trow1[jj] = trow2[jj] = NONTENT;
801                         }
802                     }
803
804                     for (j = 0; j < 3*len; j++) {
805                         if (trow[j] == MAGIC)
806                             continue;
807                         if (mrow[j] == MAGIC || mrow[j] == trow[j]) {
808                             /*
809                              * Either this is the first valid
810                              * placement we've found at all, or
811                              * this square's contents are
812                              * consistent with every previous valid
813                              * combination.
814                              */
815                             mrow[j] = trow[j];
816                         } else {
817                             /*
818                              * This square's contents fail to match
819                              * what they were in a different
820                              * combination, so we cannot deduce
821                              * anything about this square.
822                              */
823                             mrow[j] = BLANK;
824                         }
825                     }
826                 }
827
828                 /*
829                  * Find the next combination of k choices from n.
830                  * We do this by finding the rightmost tent which
831                  * can be moved one place right, doing so, and
832                  * shunting all tents to the right of that as far
833                  * left as they can go.
834                  */
835                 p = 0;
836                 for (j = n-1; j > 0; j--) {
837                     if (sc->place[j] == TENT)
838                         p++;
839                     if (sc->place[j] == NONTENT && sc->place[j-1] == TENT) {
840                         sc->place[j-1] = NONTENT;
841                         sc->place[j] = TENT;
842                         while (p--)
843                             sc->place[++j] = TENT;
844                         while (++j < n)
845                             sc->place[j] = NONTENT;
846                         break;
847                     }
848                 }
849                 if (j <= 0)
850                     break;             /* we've finished */
851             }
852
853             /*
854              * It's just possible that _no_ placement was valid, in
855              * which case we have an internally inconsistent
856              * puzzle.
857              */
858             if (mrow[sc->locs[0]] == MAGIC)
859                 return 0;              /* inconsistent */
860
861             /*
862              * Now go through mrow and see if there's anything
863              * we've deduced which wasn't already mentioned in soln.
864              */
865             for (j = 0; j < len; j++) {
866                 int whichrow;
867
868                 for (whichrow = 0; whichrow < 3; whichrow++) {
869                     char *mthis = mrow + whichrow * len;
870                     int tstart = (whichrow == 0 ? start :
871                                   whichrow == 1 ? start1 : start2);
872                     if (tstart >= 0 &&
873                         mthis[j] != MAGIC && mthis[j] != BLANK &&
874                         soln[tstart+j*step] == BLANK) {
875                         int pos = tstart+j*step;
876
877 #ifdef SOLVER_DIAGNOSTICS
878                         if (verbose)
879                             printf("%s %d forces %s at %d,%d\n",
880                                    step==1 ? "row" : "column",
881                                    step==1 ? start/w : start,
882                                    mthis[j] == TENT ? "tent" : "non-tent",
883                                    pos % w, pos / w);
884 #endif
885                         soln[pos] = mthis[j];
886                         done_something = TRUE;
887                     }
888                 }
889             }
890         }
891
892         if (done_something)
893             continue;
894
895         if (!done_something)
896             break;
897     }
898
899     /*
900      * The solver has nothing further it can do. Return 1 if both
901      * soln and sc->links are completely filled in, or 2 otherwise.
902      */
903     for (y = 0; y < h; y++)
904         for (x = 0; x < w; x++) {
905             if (soln[y*w+x] == BLANK)
906                 return 2;
907             if (soln[y*w+x] != NONTENT && sc->links[y*w+x] == 0)
908                 return 2;
909         }
910
911     return 1;
912 }
913
914 static char *new_game_desc(game_params *params, random_state *rs,
915                            char **aux, int interactive)
916 {
917     int w = params->w, h = params->h;
918     int ntrees = w * h / 5;
919     char *grid = snewn(w*h, char);
920     char *puzzle = snewn(w*h, char);
921     int *numbers = snewn(w+h, int);
922     char *soln = snewn(w*h, char);
923     int *temp = snewn(2*w*h, int);
924     int maxedges = ntrees*4 + w*h;
925     int *edges = snewn(2*maxedges, int);
926     int *capacity = snewn(maxedges, int);
927     int *flow = snewn(maxedges, int);
928     struct solver_scratch *sc = new_scratch(w, h);
929     char *ret, *p;
930     int i, j, nedges;
931
932     /*
933      * Since this puzzle has many global deductions and doesn't
934      * permit limited clue sets, generating grids for this puzzle
935      * is hard enough that I see no better option than to simply
936      * generate a solution and see if it's unique and has the
937      * required difficulty. This turns out to be computationally
938      * plausible as well.
939      * 
940      * We chose our tree count (hence also tent count) by dividing
941      * the total grid area by five above. Why five? Well, w*h/4 is
942      * the maximum number of tents you can _possibly_ fit into the
943      * grid without violating the separation criterion, and to
944      * achieve that you are constrained to a very small set of
945      * possible layouts (the obvious one with a tent at every
946      * (even,even) coordinate, and trivial variations thereon). So
947      * if we reduce the tent count a bit more, we enable more
948      * random-looking placement; 5 turns out to be a plausible
949      * figure which yields sensible puzzles. Increasing the tent
950      * count would give puzzles whose solutions were too regimented
951      * and could be solved by the use of that knowledge (and would
952      * also take longer to find a viable placement); decreasing it
953      * would make the grids emptier and more boring.
954      * 
955      * Actually generating a grid is a matter of first placing the
956      * tents, and then placing the trees by the use of maxflow
957      * (finding a distinct square adjacent to every tent). We do it
958      * this way round because otherwise satisfying the tent
959      * separation condition would become onerous: most randomly
960      * chosen tent layouts do not satisfy this condition, so we'd
961      * have gone to a lot of work before finding that a candidate
962      * layout was unusable. Instead, we place the tents first and
963      * ensure they meet the separation criterion _before_ doing
964      * lots of computation; this works much better.
965      * 
966      * The maxflow algorithm is not randomised, so employed naively
967      * it would give rise to grids with clear structure and
968      * directional bias. Hence, I assign the network nodes as seen
969      * by maxflow to be a _random_ permutation of the squares of
970      * the grid, so that any bias shown by maxflow towards
971      * low-numbered nodes is turned into a random bias.
972      * 
973      * This generation strategy can fail at many points, including
974      * as early as tent placement (if you get a bad random order in
975      * which to greedily try the grid squares, you won't even
976      * manage to find enough mutually non-adjacent squares to put
977      * the tents in). Then it can fail if maxflow doesn't manage to
978      * find a good enough matching (i.e. the tent placements don't
979      * admit any adequate tree placements); and finally it can fail
980      * if the solver finds that the problem has the wrong
981      * difficulty (including being actually non-unique). All of
982      * these, however, are insufficiently frequent to cause
983      * trouble.
984      */
985
986     if (params->diff > DIFF_EASY && params->w <= 4 && params->h <= 4)
987         params->diff = DIFF_EASY;      /* downgrade to prevent tight loop */
988
989     while (1) {
990         /*
991          * Arrange the grid squares into a random order.
992          */
993         for (i = 0; i < w*h; i++)
994             temp[i] = i;
995         shuffle(temp, w*h, sizeof(*temp), rs);
996
997         /*
998          * The first `ntrees' entries in temp which we can get
999          * without making two tents adjacent will be the tent
1000          * locations.
1001          */
1002         memset(grid, BLANK, w*h);
1003         j = ntrees;
1004         for (i = 0; i < w*h && j > 0; i++) {
1005             int x = temp[i] % w, y = temp[i] / w;
1006             int dy, dx, ok = TRUE;
1007
1008             for (dy = -1; dy <= +1; dy++)
1009                 for (dx = -1; dx <= +1; dx++)
1010                     if (x+dx >= 0 && x+dx < w &&
1011                         y+dy >= 0 && y+dy < h &&
1012                         grid[(y+dy)*w+(x+dx)] == TENT)
1013                         ok = FALSE;
1014
1015             if (ok) {
1016                 grid[temp[i]] = TENT;
1017                 j--;
1018             }
1019         }
1020         if (j > 0)
1021             continue;                  /* couldn't place all the tents */
1022
1023         /*
1024          * Now we build up the list of graph edges.
1025          */
1026         nedges = 0;
1027         for (i = 0; i < w*h; i++) {
1028             if (grid[temp[i]] == TENT) {
1029                 for (j = 0; j < w*h; j++) {
1030                     if (grid[temp[j]] != TENT) {
1031                         int xi = temp[i] % w, yi = temp[i] / w;
1032                         int xj = temp[j] % w, yj = temp[j] / w;
1033                         if (abs(xi-xj) + abs(yi-yj) == 1) {
1034                             edges[nedges*2] = i;
1035                             edges[nedges*2+1] = j;
1036                             capacity[nedges] = 1;
1037                             nedges++;
1038                         }
1039                     }
1040                 }
1041             } else {
1042                 /*
1043                  * Special node w*h is the sink node; any non-tent node
1044                  * has an edge going to it.
1045                  */
1046                 edges[nedges*2] = i;
1047                 edges[nedges*2+1] = w*h;
1048                 capacity[nedges] = 1;
1049                 nedges++;
1050             }
1051         }
1052
1053         /*
1054          * Special node w*h+1 is the source node, with an edge going to
1055          * every tent.
1056          */
1057         for (i = 0; i < w*h; i++) {
1058             if (grid[temp[i]] == TENT) {
1059                 edges[nedges*2] = w*h+1;
1060                 edges[nedges*2+1] = i;
1061                 capacity[nedges] = 1;
1062                 nedges++;
1063             }
1064         }
1065
1066         assert(nedges <= maxedges);
1067
1068         /*
1069          * Now we're ready to call the maxflow algorithm to place the
1070          * trees.
1071          */
1072         j = maxflow(w*h+2, w*h+1, w*h, nedges, edges, capacity, flow, NULL);
1073
1074         if (j < ntrees)
1075             continue;                  /* couldn't place all the tents */
1076
1077         /*
1078          * We've placed the trees. Now we need to work out _where_
1079          * we've placed them, which is a matter of reading back out
1080          * from the `flow' array.
1081          */
1082         for (i = 0; i < nedges; i++) {
1083             if (edges[2*i] < w*h && edges[2*i+1] < w*h && flow[i] > 0)
1084                 grid[temp[edges[2*i+1]]] = TREE;
1085         }
1086
1087         /*
1088          * I think it looks ugly if there isn't at least one of
1089          * _something_ (tent or tree) in each row and each column
1090          * of the grid. This doesn't give any information away
1091          * since a completely empty row/column is instantly obvious
1092          * from the clues (it has no trees and a zero).
1093          */
1094         for (i = 0; i < w; i++) {
1095             for (j = 0; j < h; j++) {
1096                 if (grid[j*w+i] != BLANK)
1097                     break;             /* found something in this column */
1098             }
1099             if (j == h)
1100                 break;                 /* found empty column */
1101         }
1102         if (i < w)
1103             continue;                  /* a column was empty */
1104
1105         for (j = 0; j < h; j++) {
1106             for (i = 0; i < w; i++) {
1107                 if (grid[j*w+i] != BLANK)
1108                     break;             /* found something in this row */
1109             }
1110             if (i == w)
1111                 break;                 /* found empty row */
1112         }
1113         if (j < h)
1114             continue;                  /* a row was empty */
1115
1116         /*
1117          * Now set up the numbers round the edge.
1118          */
1119         for (i = 0; i < w; i++) {
1120             int n = 0;
1121             for (j = 0; j < h; j++)
1122                 if (grid[j*w+i] == TENT)
1123                     n++;
1124             numbers[i] = n;
1125         }
1126         for (i = 0; i < h; i++) {
1127             int n = 0;
1128             for (j = 0; j < w; j++)
1129                 if (grid[i*w+j] == TENT)
1130                     n++;
1131             numbers[w+i] = n;
1132         }
1133
1134         /*
1135          * And now actually solve the puzzle, to see whether it's
1136          * unique and has the required difficulty.
1137          */
1138         for (i = 0; i < w*h; i++)
1139             puzzle[i] = grid[i] == TREE ? TREE : BLANK;
1140         i = tents_solve(w, h, puzzle, numbers, soln, sc, params->diff-1);
1141         j = tents_solve(w, h, puzzle, numbers, soln, sc, params->diff);
1142
1143         /*
1144          * We expect solving with difficulty params->diff to have
1145          * succeeded (otherwise the problem is too hard), and
1146          * solving with diff-1 to have failed (otherwise it's too
1147          * easy).
1148          */
1149         if (i == 2 && j == 1)
1150             break;
1151     }
1152
1153     /*
1154      * That's it. Encode as a game ID.
1155      */
1156     ret = snewn((w+h)*40 + ntrees + (w*h)/26 + 1, char);
1157     p = ret;
1158     j = 0;
1159     for (i = 0; i <= w*h; i++) {
1160         int c = (i < w*h ? grid[i] == TREE : 1);
1161         if (c) {
1162             *p++ = (j == 0 ? '_' : j-1 + 'a');
1163             j = 0;
1164         } else {
1165             j++;
1166             while (j > 25) {
1167                 *p++ = 'z';
1168                 j -= 25;
1169             }
1170         }
1171     }
1172     for (i = 0; i < w+h; i++)
1173         p += sprintf(p, ",%d", numbers[i]);
1174     *p++ = '\0';
1175     ret = sresize(ret, p - ret, char);
1176
1177     /*
1178      * And encode the solution as an aux_info.
1179      */
1180     *aux = snewn(ntrees * 40, char);
1181     p = *aux;
1182     *p++ = 'S';
1183     for (i = 0; i < w*h; i++)
1184         if (grid[i] == TENT)
1185             p += sprintf(p, ";T%d,%d", i%w, i/w);
1186     *p++ = '\0';
1187     *aux = sresize(*aux, p - *aux, char);
1188
1189     free_scratch(sc);
1190     sfree(flow);
1191     sfree(capacity);
1192     sfree(edges);
1193     sfree(temp);
1194     sfree(soln);
1195     sfree(numbers);
1196     sfree(puzzle);
1197     sfree(grid);
1198
1199     return ret;
1200 }
1201
1202 static char *validate_desc(game_params *params, char *desc)
1203 {
1204     int w = params->w, h = params->h;
1205     int area, i;
1206
1207     area = 0;
1208     while (*desc && *desc != ',') {
1209         if (*desc == '_')
1210             area++;
1211         else if (*desc >= 'a' && *desc < 'z')
1212             area += *desc - 'a' + 2;
1213         else if (*desc == 'z')
1214             area += 25;
1215         else if (*desc == '!' || *desc == '-')
1216             /* do nothing */;
1217         else
1218             return "Invalid character in grid specification";
1219
1220         desc++;
1221     }
1222
1223     for (i = 0; i < w+h; i++) {
1224         if (!*desc)
1225             return "Not enough numbers given after grid specification";
1226         else if (*desc != ',')
1227             return "Invalid character in number list";
1228         desc++;
1229         while (*desc && isdigit((unsigned char)*desc)) desc++;
1230     }
1231
1232     if (*desc)
1233         return "Unexpected additional data at end of game description";
1234     return NULL;
1235 }
1236
1237 static game_state *new_game(midend *me, game_params *params, char *desc)
1238 {
1239     int w = params->w, h = params->h;
1240     game_state *state = snew(game_state);
1241     int i;
1242
1243     state->p = *params;                /* structure copy */
1244     state->grid = snewn(w*h, char);
1245     state->numbers = snew(struct numbers);
1246     state->numbers->refcount = 1;
1247     state->numbers->numbers = snewn(w+h, int);
1248     state->completed = state->used_solve = FALSE;
1249
1250     i = 0;
1251     memset(state->grid, BLANK, w*h);
1252
1253     while (*desc) {
1254         int run, type;
1255
1256         type = TREE;
1257
1258         if (*desc == '_')
1259             run = 0;
1260         else if (*desc >= 'a' && *desc < 'z')
1261             run = *desc - ('a'-1);
1262         else if (*desc == 'z') {
1263             run = 25;
1264             type = BLANK;
1265         } else {
1266             assert(*desc == '!' || *desc == '-');
1267             run = -1;
1268             type = (*desc == '!' ? TENT : NONTENT);
1269         }
1270
1271         desc++;
1272
1273         i += run;
1274         assert(i >= 0 && i <= w*h);
1275         if (i == w*h) {
1276             assert(type == TREE);
1277             break;
1278         } else {
1279             if (type != BLANK)
1280                 state->grid[i++] = type;
1281         }
1282     }
1283
1284     for (i = 0; i < w+h; i++) {
1285         assert(*desc == ',');
1286         desc++;
1287         state->numbers->numbers[i] = atoi(desc);
1288         while (*desc && isdigit((unsigned char)*desc)) desc++;
1289     }
1290
1291     assert(!*desc);
1292
1293     return state;
1294 }
1295
1296 static game_state *dup_game(game_state *state)
1297 {
1298     int w = state->p.w, h = state->p.h;
1299     game_state *ret = snew(game_state);
1300
1301     ret->p = state->p;                 /* structure copy */
1302     ret->grid = snewn(w*h, char);
1303     memcpy(ret->grid, state->grid, w*h);
1304     ret->numbers = state->numbers;
1305     state->numbers->refcount++;
1306     ret->completed = state->completed;
1307     ret->used_solve = state->used_solve;
1308
1309     return ret;
1310 }
1311
1312 static void free_game(game_state *state)
1313 {
1314     if (--state->numbers->refcount <= 0) {
1315         sfree(state->numbers->numbers);
1316         sfree(state->numbers);
1317     }
1318     sfree(state->grid);
1319     sfree(state);
1320 }
1321
1322 static char *solve_game(game_state *state, game_state *currstate,
1323                         char *aux, char **error)
1324 {
1325     int w = state->p.w, h = state->p.h;
1326
1327     if (aux) {
1328         /*
1329          * If we already have the solution, save ourselves some
1330          * time.
1331          */
1332         return dupstr(aux);
1333     } else {
1334         struct solver_scratch *sc = new_scratch(w, h);
1335         char *soln;
1336         int ret;
1337         char *move, *p;
1338         int i;
1339
1340         soln = snewn(w*h, char);
1341         ret = tents_solve(w, h, state->grid, state->numbers->numbers,
1342                           soln, sc, DIFFCOUNT-1);
1343         free_scratch(sc);
1344         if (ret != 1) {
1345             sfree(soln);
1346             if (ret == 0)
1347                 *error = "This puzzle is not self-consistent";
1348             else
1349                 *error = "Unable to find a unique solution for this puzzle";
1350             return NULL;
1351         }
1352
1353         /*
1354          * Construct a move string which turns the current state
1355          * into the solved state.
1356          */
1357         move = snewn(w*h * 40, char);
1358         p = move;
1359         *p++ = 'S';
1360         for (i = 0; i < w*h; i++)
1361             if (soln[i] == TENT)
1362                 p += sprintf(p, ";T%d,%d", i%w, i/w);
1363         *p++ = '\0';
1364         move = sresize(move, p - move, char);
1365
1366         sfree(soln);
1367
1368         return move;
1369     }
1370 }
1371
1372 static int game_can_format_as_text_now(game_params *params)
1373 {
1374     return TRUE;
1375 }
1376
1377 static char *game_text_format(game_state *state)
1378 {
1379     int w = state->p.w, h = state->p.h;
1380     char *ret, *p;
1381     int x, y;
1382
1383     /*
1384      * FIXME: We currently do not print the numbers round the edges
1385      * of the grid. I need to work out a sensible way of doing this
1386      * even when the column numbers exceed 9.
1387      * 
1388      * In the absence of those numbers, the result size is h lines
1389      * of w+1 characters each, plus a NUL.
1390      * 
1391      * This function is currently only used by the standalone
1392      * solver; until I make it look more sensible, I won't enable
1393      * it in the main game structure.
1394      */
1395     ret = snewn(h*(w+1) + 1, char);
1396     p = ret;
1397     for (y = 0; y < h; y++) {
1398         for (x = 0; x < w; x++) {
1399             *p = (state->grid[y*w+x] == BLANK ? '.' :
1400                   state->grid[y*w+x] == TREE ? 'T' :
1401                   state->grid[y*w+x] == TENT ? '*' :
1402                   state->grid[y*w+x] == NONTENT ? '-' : '?');
1403             p++;
1404         }
1405         *p++ = '\n';
1406     }
1407     *p++ = '\0';
1408
1409     return ret;
1410 }
1411
1412 struct game_ui {
1413     int dsx, dsy;                      /* coords of drag start */
1414     int dex, dey;                      /* coords of drag end */
1415     int drag_button;                   /* -1 for none, or a button code */
1416     int drag_ok;                       /* dragged off the window, to cancel */
1417 };
1418
1419 static game_ui *new_ui(game_state *state)
1420 {
1421     game_ui *ui = snew(game_ui);
1422     ui->dsx = ui->dsy = -1;
1423     ui->dex = ui->dey = -1;
1424     ui->drag_button = -1;
1425     ui->drag_ok = FALSE;
1426     return ui;
1427 }
1428
1429 static void free_ui(game_ui *ui)
1430 {
1431     sfree(ui);
1432 }
1433
1434 static char *encode_ui(game_ui *ui)
1435 {
1436     return NULL;
1437 }
1438
1439 static void decode_ui(game_ui *ui, char *encoding)
1440 {
1441 }
1442
1443 static void game_changed_state(game_ui *ui, game_state *oldstate,
1444                                game_state *newstate)
1445 {
1446 }
1447
1448 struct game_drawstate {
1449     int tilesize;
1450     int started;
1451     game_params p;
1452     char *drawn;
1453 };
1454
1455 #define PREFERRED_TILESIZE 32
1456 #define TILESIZE (ds->tilesize)
1457 #define TLBORDER (TILESIZE/2)
1458 #define BRBORDER (TILESIZE*3/2)
1459 #define COORD(x)  ( (x) * TILESIZE + TLBORDER )
1460 #define FROMCOORD(x)  ( ((x) - TLBORDER + TILESIZE) / TILESIZE - 1 )
1461
1462 #define FLASH_TIME 0.30F
1463
1464 static int drag_xform(game_ui *ui, int x, int y, int v)
1465 {
1466     int xmin, ymin, xmax, ymax;
1467
1468     xmin = min(ui->dsx, ui->dex);
1469     xmax = max(ui->dsx, ui->dex);
1470     ymin = min(ui->dsy, ui->dey);
1471     ymax = max(ui->dsy, ui->dey);
1472
1473     /*
1474      * Left-dragging has no effect, so we treat a left-drag as a
1475      * single click on dsx,dsy.
1476      */
1477     if (ui->drag_button == LEFT_BUTTON) {
1478         xmin = xmax = ui->dsx;
1479         ymin = ymax = ui->dsy;
1480     }
1481
1482     if (x < xmin || x > xmax || y < ymin || y > ymax)
1483         return v;                      /* no change outside drag area */
1484
1485     if (v == TREE)
1486         return v;                      /* trees are inviolate always */
1487
1488     if (xmin == xmax && ymin == ymax) {
1489         /*
1490          * Results of a simple click. Left button sets blanks to
1491          * tents; right button sets blanks to non-tents; either
1492          * button clears a non-blank square.
1493          */
1494         if (ui->drag_button == LEFT_BUTTON)
1495             v = (v == BLANK ? TENT : BLANK);
1496         else
1497             v = (v == BLANK ? NONTENT : BLANK);
1498     } else {
1499         /*
1500          * Results of a drag. Left-dragging has no effect.
1501          * Right-dragging sets all blank squares to non-tents and
1502          * has no effect on anything else.
1503          */
1504         if (ui->drag_button == RIGHT_BUTTON)
1505             v = (v == BLANK ? NONTENT : v);
1506         else
1507             /* do nothing */;
1508     }
1509
1510     return v;
1511 }
1512
1513 static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
1514                             int x, int y, int button)
1515 {
1516     int w = state->p.w, h = state->p.h;
1517
1518     if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
1519         x = FROMCOORD(x);
1520         y = FROMCOORD(y);
1521         if (x < 0 || y < 0 || x >= w || y >= h)
1522             return NULL;
1523
1524         ui->drag_button = button;
1525         ui->dsx = ui->dex = x;
1526         ui->dsy = ui->dey = y;
1527         ui->drag_ok = TRUE;
1528         return "";             /* ui updated */
1529     }
1530
1531     if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) &&
1532         ui->drag_button > 0) {
1533         int xmin, ymin, xmax, ymax;
1534         char *buf, *sep, tmpbuf[80];
1535         int buflen, bufsize, tmplen;
1536
1537         x = FROMCOORD(x);
1538         y = FROMCOORD(y);
1539         if (x < 0 || y < 0 || x >= w || y >= h) {
1540             ui->drag_ok = FALSE;
1541         } else {
1542             /*
1543              * Drags are limited to one row or column. Hence, we
1544              * work out which coordinate is closer to the drag
1545              * start, and move it _to_ the drag start.
1546              */
1547             if (abs(x - ui->dsx) < abs(y - ui->dsy))
1548                 x = ui->dsx;
1549             else
1550                 y = ui->dsy;
1551
1552             ui->dex = x;
1553             ui->dey = y;
1554
1555             ui->drag_ok = TRUE;
1556         }
1557
1558         if (IS_MOUSE_DRAG(button))
1559             return "";                 /* ui updated */
1560
1561         /*
1562          * The drag has been released. Enact it.
1563          */
1564         if (!ui->drag_ok) {
1565             ui->drag_button = -1;
1566             return "";                 /* drag was just cancelled */
1567         }
1568
1569         xmin = min(ui->dsx, ui->dex);
1570         xmax = max(ui->dsx, ui->dex);
1571         ymin = min(ui->dsy, ui->dey);
1572         ymax = max(ui->dsy, ui->dey);
1573         assert(0 <= xmin && xmin <= xmax && xmax < w);
1574         assert(0 <= ymin && ymin <= ymax && ymax < h);
1575
1576         buflen = 0;
1577         bufsize = 256;
1578         buf = snewn(bufsize, char);
1579         sep = "";
1580         for (y = ymin; y <= ymax; y++)
1581             for (x = xmin; x <= xmax; x++) {
1582                 int v = drag_xform(ui, x, y, state->grid[y*w+x]);
1583                 if (state->grid[y*w+x] != v) {
1584                     tmplen = sprintf(tmpbuf, "%s%c%d,%d", sep,
1585                                      (int)(v == BLANK ? 'B' :
1586                                            v == TENT ? 'T' : 'N'),
1587                                      x, y);
1588                     sep = ";";
1589
1590                     if (buflen + tmplen >= bufsize) {
1591                         bufsize = buflen + tmplen + 256;
1592                         buf = sresize(buf, bufsize, char);
1593                     }
1594
1595                     strcpy(buf+buflen, tmpbuf);
1596                     buflen += tmplen;
1597                 }
1598             }
1599
1600         ui->drag_button = -1;          /* drag is terminated */
1601
1602         if (buflen == 0) {
1603             sfree(buf);
1604             return "";                 /* ui updated (drag was terminated) */
1605         } else {
1606             buf[buflen] = '\0';
1607             return buf;
1608         }
1609     }
1610
1611     return NULL;
1612 }
1613
1614 static game_state *execute_move(game_state *state, char *move)
1615 {
1616     int w = state->p.w, h = state->p.h;
1617     char c;
1618     int x, y, m, n, i, j;
1619     game_state *ret = dup_game(state);
1620
1621     while (*move) {
1622         c = *move;
1623         if (c == 'S') {
1624             int i;
1625             ret->used_solve = TRUE;
1626             /*
1627              * Set all non-tree squares to NONTENT. The rest of the
1628              * solve move will fill the tents in over the top.
1629              */
1630             for (i = 0; i < w*h; i++)
1631                 if (ret->grid[i] != TREE)
1632                     ret->grid[i] = NONTENT;
1633             move++;
1634         } else if (c == 'B' || c == 'T' || c == 'N') {
1635             move++;
1636             if (sscanf(move, "%d,%d%n", &x, &y, &n) != 2 ||
1637                 x < 0 || y < 0 || x >= w || y >= h) {
1638                 free_game(ret);
1639                 return NULL;
1640             }
1641             if (ret->grid[y*w+x] == TREE) {
1642                 free_game(ret);
1643                 return NULL;
1644             }
1645             ret->grid[y*w+x] = (c == 'B' ? BLANK : c == 'T' ? TENT : NONTENT);
1646             move += n;
1647         } else {
1648             free_game(ret);
1649             return NULL;
1650         }
1651         if (*move == ';')
1652             move++;
1653         else if (*move) {
1654             free_game(ret);
1655             return NULL;
1656         }
1657     }
1658
1659     /*
1660      * Check for completion.
1661      */
1662     for (i = n = m = 0; i < w*h; i++) {
1663         if (ret->grid[i] == TENT)
1664             n++;
1665         else if (ret->grid[i] == TREE)
1666             m++;
1667     }
1668     if (n == m) {
1669         int nedges, maxedges, *edges, *capacity, *flow;
1670
1671         /*
1672          * We have the right number of tents, which is a
1673          * precondition for the game being complete. Now check that
1674          * the numbers add up.
1675          */
1676         for (i = 0; i < w; i++) {
1677             n = 0;
1678             for (j = 0; j < h; j++)
1679                 if (ret->grid[j*w+i] == TENT)
1680                     n++;
1681             if (ret->numbers->numbers[i] != n)
1682                 goto completion_check_done;
1683         }
1684         for (i = 0; i < h; i++) {
1685             n = 0;
1686             for (j = 0; j < w; j++)
1687                 if (ret->grid[i*w+j] == TENT)
1688                     n++;
1689             if (ret->numbers->numbers[w+i] != n)
1690                 goto completion_check_done;
1691         }
1692         /*
1693          * Also, check that no two tents are adjacent.
1694          */
1695         for (y = 0; y < h; y++)
1696             for (x = 0; x < w; x++) {
1697                 if (x+1 < w &&
1698                     ret->grid[y*w+x] == TENT && ret->grid[y*w+x+1] == TENT)
1699                     goto completion_check_done;
1700                 if (y+1 < h &&
1701                     ret->grid[y*w+x] == TENT && ret->grid[(y+1)*w+x] == TENT)
1702                     goto completion_check_done;
1703                 if (x+1 < w && y+1 < h) {
1704                     if (ret->grid[y*w+x] == TENT &&
1705                         ret->grid[(y+1)*w+(x+1)] == TENT)
1706                         goto completion_check_done;
1707                     if (ret->grid[(y+1)*w+x] == TENT &&
1708                         ret->grid[y*w+(x+1)] == TENT)
1709                         goto completion_check_done;
1710                 }
1711             }
1712
1713         /*
1714          * OK; we have the right number of tents, they match the
1715          * numeric clues, and they satisfy the non-adjacency
1716          * criterion. Finally, we need to verify that they can be
1717          * placed in a one-to-one matching with the trees such that
1718          * every tent is orthogonally adjacent to its tree.
1719          * 
1720          * This bit is where the hard work comes in: we have to do
1721          * it by finding such a matching using maxflow.
1722          * 
1723          * So we construct a network with one special source node,
1724          * one special sink node, one node per tent, and one node
1725          * per tree.
1726          */
1727         maxedges = 6 * m;
1728         edges = snewn(2 * maxedges, int);
1729         capacity = snewn(maxedges, int);
1730         flow = snewn(maxedges, int);
1731         nedges = 0;
1732         /*
1733          * Node numbering:
1734          * 
1735          * 0..w*h   trees/tents
1736          * w*h      source
1737          * w*h+1    sink
1738          */
1739         for (y = 0; y < h; y++)
1740             for (x = 0; x < w; x++)
1741                 if (ret->grid[y*w+x] == TREE) {
1742                     int d;
1743
1744                     /*
1745                      * Here we use the direction enum declared for
1746                      * the solver. We make use of the fact that the
1747                      * directions are declared in the order
1748                      * U,L,R,D, meaning that we go through the four
1749                      * neighbours of any square in numerically
1750                      * increasing order.
1751                      */
1752                     for (d = 1; d < MAXDIR; d++) {
1753                         int x2 = x + dx(d), y2 = y + dy(d);
1754                         if (x2 >= 0 && x2 < w && y2 >= 0 && y2 < h &&
1755                             ret->grid[y2*w+x2] == TENT) {
1756                             assert(nedges < maxedges);
1757                             edges[nedges*2] = y*w+x;
1758                             edges[nedges*2+1] = y2*w+x2;
1759                             capacity[nedges] = 1;
1760                             nedges++;
1761                         }
1762                     }
1763                 } else if (ret->grid[y*w+x] == TENT) {
1764                     assert(nedges < maxedges);
1765                     edges[nedges*2] = y*w+x;
1766                     edges[nedges*2+1] = w*h+1;   /* edge going to sink */
1767                     capacity[nedges] = 1;
1768                     nedges++;
1769                 }
1770         for (y = 0; y < h; y++)
1771             for (x = 0; x < w; x++)
1772                 if (ret->grid[y*w+x] == TREE) {
1773                     assert(nedges < maxedges);
1774                     edges[nedges*2] = w*h;   /* edge coming from source */
1775                     edges[nedges*2+1] = y*w+x;
1776                     capacity[nedges] = 1;
1777                     nedges++;
1778                 }
1779         n = maxflow(w*h+2, w*h, w*h+1, nedges, edges, capacity, flow, NULL);
1780
1781         sfree(flow);
1782         sfree(capacity);
1783         sfree(edges);
1784
1785         if (n != m)
1786             goto completion_check_done;
1787
1788         /*
1789          * We haven't managed to fault the grid on any count. Score!
1790          */
1791         ret->completed = TRUE;
1792     }
1793     completion_check_done:
1794
1795     return ret;
1796 }
1797
1798 /* ----------------------------------------------------------------------
1799  * Drawing routines.
1800  */
1801
1802 static void game_compute_size(game_params *params, int tilesize,
1803                               int *x, int *y)
1804 {
1805     /* fool the macros */
1806     struct dummy { int tilesize; } dummy, *ds = &dummy;
1807     dummy.tilesize = tilesize;
1808
1809     *x = TLBORDER + BRBORDER + TILESIZE * params->w;
1810     *y = TLBORDER + BRBORDER + TILESIZE * params->h;
1811 }
1812
1813 static void game_set_size(drawing *dr, game_drawstate *ds,
1814                           game_params *params, int tilesize)
1815 {
1816     ds->tilesize = tilesize;
1817 }
1818
1819 static float *game_colours(frontend *fe, int *ncolours)
1820 {
1821     float *ret = snewn(3 * NCOLOURS, float);
1822
1823     frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
1824
1825     ret[COL_GRID * 3 + 0] = 0.0F;
1826     ret[COL_GRID * 3 + 1] = 0.0F;
1827     ret[COL_GRID * 3 + 2] = 0.0F;
1828
1829     ret[COL_GRASS * 3 + 0] = 0.7F;
1830     ret[COL_GRASS * 3 + 1] = 1.0F;
1831     ret[COL_GRASS * 3 + 2] = 0.5F;
1832
1833     ret[COL_TREETRUNK * 3 + 0] = 0.6F;
1834     ret[COL_TREETRUNK * 3 + 1] = 0.4F;
1835     ret[COL_TREETRUNK * 3 + 2] = 0.0F;
1836
1837     ret[COL_TREELEAF * 3 + 0] = 0.0F;
1838     ret[COL_TREELEAF * 3 + 1] = 0.7F;
1839     ret[COL_TREELEAF * 3 + 2] = 0.0F;
1840
1841     ret[COL_TENT * 3 + 0] = 0.8F;
1842     ret[COL_TENT * 3 + 1] = 0.7F;
1843     ret[COL_TENT * 3 + 2] = 0.0F;
1844
1845     *ncolours = NCOLOURS;
1846     return ret;
1847 }
1848
1849 static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
1850 {
1851     int w = state->p.w, h = state->p.h;
1852     struct game_drawstate *ds = snew(struct game_drawstate);
1853
1854     ds->tilesize = 0;
1855     ds->started = FALSE;
1856     ds->p = state->p;                  /* structure copy */
1857     ds->drawn = snewn(w*h, char);
1858     memset(ds->drawn, MAGIC, w*h);
1859
1860     return ds;
1861 }
1862
1863 static void game_free_drawstate(drawing *dr, game_drawstate *ds)
1864 {
1865     sfree(ds->drawn);
1866     sfree(ds);
1867 }
1868
1869 static void draw_tile(drawing *dr, game_drawstate *ds,
1870                       int x, int y, int v, int printing)
1871 {
1872     int tx = COORD(x), ty = COORD(y);
1873     int cx = tx + TILESIZE/2, cy = ty + TILESIZE/2;
1874
1875     clip(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1);
1876
1877     if (!printing)
1878         draw_rect(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1,
1879                   (v == BLANK ? COL_BACKGROUND : COL_GRASS));
1880
1881     if (v == TREE) {
1882         int i;
1883
1884         (printing ? draw_rect_outline : draw_rect)
1885         (dr, cx-TILESIZE/15, ty+TILESIZE*3/10,
1886          2*(TILESIZE/15)+1, (TILESIZE*9/10 - TILESIZE*3/10),
1887          COL_TREETRUNK);
1888
1889         for (i = 0; i < (printing ? 2 : 1); i++) {
1890             int col = (i == 1 ? COL_BACKGROUND : COL_TREELEAF);
1891             int sub = i * (TILESIZE/32);
1892             draw_circle(dr, cx, ty+TILESIZE*4/10, TILESIZE/4 - sub,
1893                         col, col);
1894             draw_circle(dr, cx+TILESIZE/5, ty+TILESIZE/4, TILESIZE/8 - sub,
1895                         col, col);
1896             draw_circle(dr, cx-TILESIZE/5, ty+TILESIZE/4, TILESIZE/8 - sub,
1897                         col, col);
1898             draw_circle(dr, cx+TILESIZE/4, ty+TILESIZE*6/13, TILESIZE/8 - sub,
1899                         col, col);
1900             draw_circle(dr, cx-TILESIZE/4, ty+TILESIZE*6/13, TILESIZE/8 - sub,
1901                         col, col);
1902         }
1903     } else if (v == TENT) {
1904         int coords[6];
1905         coords[0] = cx - TILESIZE/3;
1906         coords[1] = cy + TILESIZE/3;
1907         coords[2] = cx + TILESIZE/3;
1908         coords[3] = cy + TILESIZE/3;
1909         coords[4] = cx;
1910         coords[5] = cy - TILESIZE/3;
1911         draw_polygon(dr, coords, 3, (printing ? -1 : COL_TENT), COL_TENT);
1912     }
1913
1914     unclip(dr);
1915     draw_update(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1);
1916 }
1917
1918 /*
1919  * Internal redraw function, used for printing as well as drawing.
1920  */
1921 static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
1922                        game_state *state, int dir, game_ui *ui,
1923                        float animtime, float flashtime, int printing)
1924 {
1925     int w = state->p.w, h = state->p.h;
1926     int x, y, flashing;
1927
1928     if (printing || !ds->started) {
1929         if (!printing) {
1930             int ww, wh;
1931             game_compute_size(&state->p, TILESIZE, &ww, &wh);
1932             draw_rect(dr, 0, 0, ww, wh, COL_BACKGROUND);
1933             draw_update(dr, 0, 0, ww, wh);
1934             ds->started = TRUE;
1935         }
1936
1937         if (printing)
1938             print_line_width(dr, TILESIZE/64);
1939
1940         /*
1941          * Draw the grid.
1942          */
1943         for (y = 0; y <= h; y++)
1944             draw_line(dr, COORD(0), COORD(y), COORD(w), COORD(y), COL_GRID);
1945         for (x = 0; x <= w; x++)
1946             draw_line(dr, COORD(x), COORD(0), COORD(x), COORD(h), COL_GRID);
1947
1948         /*
1949          * Draw the numbers.
1950          */
1951         for (y = 0; y < h; y++) {
1952             char buf[80];
1953             sprintf(buf, "%d", state->numbers->numbers[y+w]);
1954             draw_text(dr, COORD(w+1), COORD(y) + TILESIZE/2,
1955                       FONT_VARIABLE, TILESIZE/2, ALIGN_HRIGHT|ALIGN_VCENTRE,
1956                       COL_GRID, buf);
1957         }
1958         for (x = 0; x < w; x++) {
1959             char buf[80];
1960             sprintf(buf, "%d", state->numbers->numbers[x]);
1961             draw_text(dr, COORD(x) + TILESIZE/2, COORD(h+1),
1962                       FONT_VARIABLE, TILESIZE/2, ALIGN_HCENTRE|ALIGN_VNORMAL,
1963                       COL_GRID, buf);
1964         }
1965     }
1966
1967     if (flashtime > 0)
1968         flashing = (int)(flashtime * 3 / FLASH_TIME) != 1;
1969     else
1970         flashing = FALSE;
1971
1972     /*
1973      * Draw the grid.
1974      */
1975     for (y = 0; y < h; y++)
1976         for (x = 0; x < w; x++) {
1977             int v = state->grid[y*w+x];
1978
1979             /*
1980              * We deliberately do not take drag_ok into account
1981              * here, because user feedback suggests that it's
1982              * marginally nicer not to have the drag effects
1983              * flickering on and off disconcertingly.
1984              */
1985             if (ui && ui->drag_button >= 0)
1986                 v = drag_xform(ui, x, y, v);
1987
1988             if (flashing && (v == TREE || v == TENT))
1989                 v = NONTENT;
1990
1991             if (printing || ds->drawn[y*w+x] != v) {
1992                 draw_tile(dr, ds, x, y, v, printing);
1993                 if (!printing)
1994                     ds->drawn[y*w+x] = v;
1995             }
1996         }
1997 }
1998
1999 static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
2000                         game_state *state, int dir, game_ui *ui,
2001                         float animtime, float flashtime)
2002 {
2003     int_redraw(dr, ds, oldstate, state, dir, ui, animtime, flashtime, FALSE);
2004 }
2005
2006 static float game_anim_length(game_state *oldstate, game_state *newstate,
2007                               int dir, game_ui *ui)
2008 {
2009     return 0.0F;
2010 }
2011
2012 static float game_flash_length(game_state *oldstate, game_state *newstate,
2013                                int dir, game_ui *ui)
2014 {
2015     if (!oldstate->completed && newstate->completed &&
2016         !oldstate->used_solve && !newstate->used_solve)
2017         return FLASH_TIME;
2018
2019     return 0.0F;
2020 }
2021
2022 static int game_timing_state(game_state *state, game_ui *ui)
2023 {
2024     return TRUE;
2025 }
2026
2027 static void game_print_size(game_params *params, float *x, float *y)
2028 {
2029     int pw, ph;
2030
2031     /*
2032      * I'll use 6mm squares by default.
2033      */
2034     game_compute_size(params, 600, &pw, &ph);
2035     *x = pw / 100.0;
2036     *y = ph / 100.0;
2037 }
2038
2039 static void game_print(drawing *dr, game_state *state, int tilesize)
2040 {
2041     int c;
2042
2043     /* Ick: fake up `ds->tilesize' for macro expansion purposes */
2044     game_drawstate ads, *ds = &ads;
2045     game_set_size(dr, ds, NULL, tilesize);
2046
2047     c = print_mono_colour(dr, 1); assert(c == COL_BACKGROUND);
2048     c = print_mono_colour(dr, 0); assert(c == COL_GRID);
2049     c = print_mono_colour(dr, 1); assert(c == COL_GRASS);
2050     c = print_mono_colour(dr, 0); assert(c == COL_TREETRUNK);
2051     c = print_mono_colour(dr, 0); assert(c == COL_TREELEAF);
2052     c = print_mono_colour(dr, 0); assert(c == COL_TENT);
2053
2054     int_redraw(dr, ds, NULL, state, +1, NULL, 0.0F, 0.0F, TRUE);
2055 }
2056
2057 #ifdef COMBINED
2058 #define thegame tents
2059 #endif
2060
2061 const struct game thegame = {
2062     "Tents", "games.tents", "tents",
2063     default_params,
2064     game_fetch_preset,
2065     decode_params,
2066     encode_params,
2067     free_params,
2068     dup_params,
2069     TRUE, game_configure, custom_params,
2070     validate_params,
2071     new_game_desc,
2072     validate_desc,
2073     new_game,
2074     dup_game,
2075     free_game,
2076     TRUE, solve_game,
2077     FALSE, game_can_format_as_text_now, game_text_format,
2078     new_ui,
2079     free_ui,
2080     encode_ui,
2081     decode_ui,
2082     game_changed_state,
2083     interpret_move,
2084     execute_move,
2085     PREFERRED_TILESIZE, game_compute_size, game_set_size,
2086     game_colours,
2087     game_new_drawstate,
2088     game_free_drawstate,
2089     game_redraw,
2090     game_anim_length,
2091     game_flash_length,
2092     TRUE, FALSE, game_print_size, game_print,
2093     FALSE,                             /* wants_statusbar */
2094     FALSE, game_timing_state,
2095     REQUIRE_RBUTTON,                   /* flags */
2096 };
2097
2098 #ifdef STANDALONE_SOLVER
2099
2100 #include <stdarg.h>
2101
2102 int main(int argc, char **argv)
2103 {
2104     game_params *p;
2105     game_state *s, *s2;
2106     char *id = NULL, *desc, *err;
2107     int grade = FALSE;
2108     int ret, diff, really_verbose = FALSE;
2109     struct solver_scratch *sc;
2110
2111     while (--argc > 0) {
2112         char *p = *++argv;
2113         if (!strcmp(p, "-v")) {
2114             really_verbose = TRUE;
2115         } else if (!strcmp(p, "-g")) {
2116             grade = TRUE;
2117         } else if (*p == '-') {
2118             fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
2119             return 1;
2120         } else {
2121             id = p;
2122         }
2123     }
2124
2125     if (!id) {
2126         fprintf(stderr, "usage: %s [-g | -v] <game_id>\n", argv[0]);
2127         return 1;
2128     }
2129
2130     desc = strchr(id, ':');
2131     if (!desc) {
2132         fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
2133         return 1;
2134     }
2135     *desc++ = '\0';
2136
2137     p = default_params();
2138     decode_params(p, id);
2139     err = validate_desc(p, desc);
2140     if (err) {
2141         fprintf(stderr, "%s: %s\n", argv[0], err);
2142         return 1;
2143     }
2144     s = new_game(NULL, p, desc);
2145     s2 = new_game(NULL, p, desc);
2146
2147     sc = new_scratch(p->w, p->h);
2148
2149     /*
2150      * When solving an Easy puzzle, we don't want to bother the
2151      * user with Hard-level deductions. For this reason, we grade
2152      * the puzzle internally before doing anything else.
2153      */
2154     ret = -1;                          /* placate optimiser */
2155     for (diff = 0; diff < DIFFCOUNT; diff++) {
2156         ret = tents_solve(p->w, p->h, s->grid, s->numbers->numbers,
2157                           s2->grid, sc, diff);
2158         if (ret < 2)
2159             break;
2160     }
2161
2162     if (diff == DIFFCOUNT) {
2163         if (grade)
2164             printf("Difficulty rating: too hard to solve internally\n");
2165         else
2166             printf("Unable to find a unique solution\n");
2167     } else {
2168         if (grade) {
2169             if (ret == 0)
2170                 printf("Difficulty rating: impossible (no solution exists)\n");
2171             else if (ret == 1)
2172                 printf("Difficulty rating: %s\n", tents_diffnames[diff]);
2173         } else {
2174             verbose = really_verbose;
2175             ret = tents_solve(p->w, p->h, s->grid, s->numbers->numbers,
2176                               s2->grid, sc, diff);
2177             if (ret == 0)
2178                 printf("Puzzle is inconsistent\n");
2179             else
2180                 fputs(game_text_format(s2), stdout);
2181         }
2182     }
2183
2184     return 0;
2185 }
2186
2187 #endif