Patch from James H to make new-Loopy port more easily.
[sgt/puzzles] / tents.c
CommitLineData
86e60e3d 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
244int 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
260enum { DIFFLIST(ENUM) DIFFCOUNT };
261static char const *const tents_diffnames[] = { DIFFLIST(TITLE) };
262static char const tents_diffchars[] = DIFFLIST(ENCODE);
263#define DIFFCONFIG DIFFLIST(CONFIG)
264
265enum {
266 COL_BACKGROUND,
267 COL_GRID,
268 COL_GRASS,
269 COL_TREETRUNK,
270 COL_TREELEAF,
271 COL_TENT,
272 NCOLOURS
273};
274
275enum { BLANK, TREE, TENT, NONTENT, MAGIC };
276
277struct game_params {
278 int w, h;
279 int diff;
280};
281
282struct numbers {
283 int refcount;
284 int *numbers;
285};
286
287struct game_state {
288 game_params p;
289 char *grid;
290 struct numbers *numbers;
291 int completed, used_solve;
292};
293
294static 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
304static 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
313static 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
331static void free_params(game_params *params)
332{
333 sfree(params);
334}
335
336static 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
343static 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
362static 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
373static 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
405static 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
416static char *validate_params(game_params *params, int full)
417{
e4b6a85b 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";
86e60e3d 424 return NULL;
425}
426
427/*
428 * Scratch space for solver.
429 */
430enum { 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) )
434struct solver_scratch {
435 char *links; /* mapping between trees and tents */
436 int *locs;
437 char *place, *mrows, *trows;
438};
439
440static 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
453static 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 */
467static 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,
9d8d4f9f 882 mthis[j] == TENT ? "tent" : "non-tent",
86e60e3d 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
914static 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);
e4b6a85b 923 int *temp = snewn(2*w*h, int);
86e60e3d 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
e4b6a85b 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.
86e60e3d 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
e4b6a85b 986 if (params->diff > DIFF_EASY && params->w <= 4 && params->h <= 4)
987 params->diff = DIFF_EASY; /* downgrade to prevent tight loop */
988
86e60e3d 989 while (1) {
990 /*
e4b6a85b 991 * Arrange the grid squares into a random order.
86e60e3d 992 */
993 for (i = 0; i < w*h; i++)
994 temp[i] = i;
995 shuffle(temp, w*h, sizeof(*temp), rs);
86e60e3d 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
1202static 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
1237static 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
1296static 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
1312static 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
1322static 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
fa3abef5 1372static int game_can_format_as_text_now(game_params *params)
1373{
1374 return TRUE;
1375}
1376
86e60e3d 1377static 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
565394e7 1412struct 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
86e60e3d 1419static game_ui *new_ui(game_state *state)
1420{
565394e7 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;
86e60e3d 1427}
1428
1429static void free_ui(game_ui *ui)
1430{
565394e7 1431 sfree(ui);
86e60e3d 1432}
1433
1434static char *encode_ui(game_ui *ui)
1435{
1436 return NULL;
1437}
1438
1439static void decode_ui(game_ui *ui, char *encoding)
1440{
1441}
1442
1443static void game_changed_state(game_ui *ui, game_state *oldstate,
1444 game_state *newstate)
1445{
1446}
1447
1448struct 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
565394e7 1464static 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
86e60e3d 1513static 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) {
86e60e3d 1519 x = FROMCOORD(x);
1520 y = FROMCOORD(y);
1521 if (x < 0 || y < 0 || x >= w || y >= h)
1522 return NULL;
1523
565394e7 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 }
86e60e3d 1530
565394e7 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;
86e60e3d 1541 } else {
565394e7 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;
86e60e3d 1556 }
1557
565394e7 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);
e4b6a85b 1574 assert(0 <= ymin && ymin <= ymax && ymax < h);
565394e7 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,
626cd8ac 1585 (int)(v == BLANK ? 'B' :
1586 v == TENT ? 'T' : 'N'),
565394e7 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 }
86e60e3d 1609 }
1610
1611 return NULL;
1612}
1613
1614static 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
1802static 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 = { tilesize }, *ds = &dummy;
1807
1808 *x = TLBORDER + BRBORDER + TILESIZE * params->w;
1809 *y = TLBORDER + BRBORDER + TILESIZE * params->h;
1810}
1811
1812static void game_set_size(drawing *dr, game_drawstate *ds,
1813 game_params *params, int tilesize)
1814{
1815 ds->tilesize = tilesize;
1816}
1817
8266f3fc 1818static float *game_colours(frontend *fe, int *ncolours)
86e60e3d 1819{
1820 float *ret = snewn(3 * NCOLOURS, float);
1821
1822 frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
1823
1824 ret[COL_GRID * 3 + 0] = 0.0F;
1825 ret[COL_GRID * 3 + 1] = 0.0F;
1826 ret[COL_GRID * 3 + 2] = 0.0F;
1827
1828 ret[COL_GRASS * 3 + 0] = 0.7F;
1829 ret[COL_GRASS * 3 + 1] = 1.0F;
1830 ret[COL_GRASS * 3 + 2] = 0.5F;
1831
1832 ret[COL_TREETRUNK * 3 + 0] = 0.6F;
1833 ret[COL_TREETRUNK * 3 + 1] = 0.4F;
1834 ret[COL_TREETRUNK * 3 + 2] = 0.0F;
1835
1836 ret[COL_TREELEAF * 3 + 0] = 0.0F;
1837 ret[COL_TREELEAF * 3 + 1] = 0.7F;
1838 ret[COL_TREELEAF * 3 + 2] = 0.0F;
1839
1840 ret[COL_TENT * 3 + 0] = 0.8F;
1841 ret[COL_TENT * 3 + 1] = 0.7F;
1842 ret[COL_TENT * 3 + 2] = 0.0F;
1843
1844 *ncolours = NCOLOURS;
1845 return ret;
1846}
1847
1848static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
1849{
1850 int w = state->p.w, h = state->p.h;
1851 struct game_drawstate *ds = snew(struct game_drawstate);
1852
1853 ds->tilesize = 0;
1854 ds->started = FALSE;
1855 ds->p = state->p; /* structure copy */
1856 ds->drawn = snewn(w*h, char);
1857 memset(ds->drawn, MAGIC, w*h);
1858
1859 return ds;
1860}
1861
1862static void game_free_drawstate(drawing *dr, game_drawstate *ds)
1863{
1864 sfree(ds->drawn);
1865 sfree(ds);
1866}
1867
1868static void draw_tile(drawing *dr, game_drawstate *ds,
1869 int x, int y, int v, int printing)
1870{
1871 int tx = COORD(x), ty = COORD(y);
1872 int cx = tx + TILESIZE/2, cy = ty + TILESIZE/2;
1873
1874 clip(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1);
1875
1876 if (!printing)
1877 draw_rect(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1,
1878 (v == BLANK ? COL_BACKGROUND : COL_GRASS));
1879
1880 if (v == TREE) {
1881 int i;
1882
1883 (printing ? draw_rect_outline : draw_rect)
1884 (dr, cx-TILESIZE/15, ty+TILESIZE*3/10,
1885 2*(TILESIZE/15)+1, (TILESIZE*9/10 - TILESIZE*3/10),
1886 COL_TREETRUNK);
1887
1888 for (i = 0; i < (printing ? 2 : 1); i++) {
1889 int col = (i == 1 ? COL_BACKGROUND : COL_TREELEAF);
1890 int sub = i * (TILESIZE/32);
1891 draw_circle(dr, cx, ty+TILESIZE*4/10, TILESIZE/4 - sub,
1892 col, col);
1893 draw_circle(dr, cx+TILESIZE/5, ty+TILESIZE/4, TILESIZE/8 - sub,
1894 col, col);
1895 draw_circle(dr, cx-TILESIZE/5, ty+TILESIZE/4, TILESIZE/8 - sub,
1896 col, col);
1897 draw_circle(dr, cx+TILESIZE/4, ty+TILESIZE*6/13, TILESIZE/8 - sub,
1898 col, col);
1899 draw_circle(dr, cx-TILESIZE/4, ty+TILESIZE*6/13, TILESIZE/8 - sub,
1900 col, col);
1901 }
1902 } else if (v == TENT) {
1903 int coords[6];
1904 coords[0] = cx - TILESIZE/3;
1905 coords[1] = cy + TILESIZE/3;
1906 coords[2] = cx + TILESIZE/3;
1907 coords[3] = cy + TILESIZE/3;
1908 coords[4] = cx;
1909 coords[5] = cy - TILESIZE/3;
1910 draw_polygon(dr, coords, 3, (printing ? -1 : COL_TENT), COL_TENT);
1911 }
1912
1913 unclip(dr);
1914 draw_update(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1);
1915}
1916
1917/*
1918 * Internal redraw function, used for printing as well as drawing.
1919 */
1920static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
1921 game_state *state, int dir, game_ui *ui,
1922 float animtime, float flashtime, int printing)
1923{
1924 int w = state->p.w, h = state->p.h;
1925 int x, y, flashing;
1926
1927 if (printing || !ds->started) {
1928 if (!printing) {
1929 int ww, wh;
1930 game_compute_size(&state->p, TILESIZE, &ww, &wh);
1931 draw_rect(dr, 0, 0, ww, wh, COL_BACKGROUND);
1932 draw_update(dr, 0, 0, ww, wh);
1933 ds->started = TRUE;
1934 }
1935
1936 if (printing)
1937 print_line_width(dr, TILESIZE/64);
1938
1939 /*
1940 * Draw the grid.
1941 */
1942 for (y = 0; y <= h; y++)
1943 draw_line(dr, COORD(0), COORD(y), COORD(w), COORD(y), COL_GRID);
1944 for (x = 0; x <= w; x++)
1945 draw_line(dr, COORD(x), COORD(0), COORD(x), COORD(h), COL_GRID);
1946
1947 /*
1948 * Draw the numbers.
1949 */
1950 for (y = 0; y < h; y++) {
1951 char buf[80];
1952 sprintf(buf, "%d", state->numbers->numbers[y+w]);
1953 draw_text(dr, COORD(w+1), COORD(y) + TILESIZE/2,
1954 FONT_VARIABLE, TILESIZE/2, ALIGN_HRIGHT|ALIGN_VCENTRE,
1955 COL_GRID, buf);
1956 }
1957 for (x = 0; x < w; x++) {
1958 char buf[80];
1959 sprintf(buf, "%d", state->numbers->numbers[x]);
1960 draw_text(dr, COORD(x) + TILESIZE/2, COORD(h+1),
1961 FONT_VARIABLE, TILESIZE/2, ALIGN_HCENTRE|ALIGN_VNORMAL,
1962 COL_GRID, buf);
1963 }
1964 }
1965
1966 if (flashtime > 0)
1967 flashing = (int)(flashtime * 3 / FLASH_TIME) != 1;
1968 else
1969 flashing = FALSE;
1970
1971 /*
1972 * Draw the grid.
1973 */
1974 for (y = 0; y < h; y++)
1975 for (x = 0; x < w; x++) {
1976 int v = state->grid[y*w+x];
1977
565394e7 1978 /*
1979 * We deliberately do not take drag_ok into account
1980 * here, because user feedback suggests that it's
1981 * marginally nicer not to have the drag effects
1982 * flickering on and off disconcertingly.
1983 */
5bcb1aa3 1984 if (ui && ui->drag_button >= 0)
565394e7 1985 v = drag_xform(ui, x, y, v);
1986
86e60e3d 1987 if (flashing && (v == TREE || v == TENT))
1988 v = NONTENT;
1989
1990 if (printing || ds->drawn[y*w+x] != v) {
1991 draw_tile(dr, ds, x, y, v, printing);
1992 if (!printing)
1993 ds->drawn[y*w+x] = v;
1994 }
1995 }
1996}
1997
1998static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
1999 game_state *state, int dir, game_ui *ui,
2000 float animtime, float flashtime)
2001{
2002 int_redraw(dr, ds, oldstate, state, dir, ui, animtime, flashtime, FALSE);
2003}
2004
2005static float game_anim_length(game_state *oldstate, game_state *newstate,
2006 int dir, game_ui *ui)
2007{
2008 return 0.0F;
2009}
2010
2011static float game_flash_length(game_state *oldstate, game_state *newstate,
2012 int dir, game_ui *ui)
2013{
2014 if (!oldstate->completed && newstate->completed &&
2015 !oldstate->used_solve && !newstate->used_solve)
2016 return FLASH_TIME;
2017
2018 return 0.0F;
2019}
2020
86e60e3d 2021static int game_timing_state(game_state *state, game_ui *ui)
2022{
2023 return TRUE;
2024}
2025
2026static void game_print_size(game_params *params, float *x, float *y)
2027{
2028 int pw, ph;
2029
2030 /*
2031 * I'll use 6mm squares by default.
2032 */
2033 game_compute_size(params, 600, &pw, &ph);
2034 *x = pw / 100.0;
2035 *y = ph / 100.0;
2036}
2037
2038static void game_print(drawing *dr, game_state *state, int tilesize)
2039{
2040 int c;
2041
2042 /* Ick: fake up `ds->tilesize' for macro expansion purposes */
2043 game_drawstate ads, *ds = &ads;
2044 game_set_size(dr, ds, NULL, tilesize);
2045
2046 c = print_mono_colour(dr, 1); assert(c == COL_BACKGROUND);
2047 c = print_mono_colour(dr, 0); assert(c == COL_GRID);
2048 c = print_mono_colour(dr, 1); assert(c == COL_GRASS);
2049 c = print_mono_colour(dr, 0); assert(c == COL_TREETRUNK);
2050 c = print_mono_colour(dr, 0); assert(c == COL_TREELEAF);
2051 c = print_mono_colour(dr, 0); assert(c == COL_TENT);
2052
2053 int_redraw(dr, ds, NULL, state, +1, NULL, 0.0F, 0.0F, TRUE);
2054}
2055
2056#ifdef COMBINED
2057#define thegame tents
2058#endif
2059
2060const struct game thegame = {
750037d7 2061 "Tents", "games.tents", "tents",
86e60e3d 2062 default_params,
2063 game_fetch_preset,
2064 decode_params,
2065 encode_params,
2066 free_params,
2067 dup_params,
2068 TRUE, game_configure, custom_params,
2069 validate_params,
2070 new_game_desc,
2071 validate_desc,
2072 new_game,
2073 dup_game,
2074 free_game,
2075 TRUE, solve_game,
fa3abef5 2076 FALSE, game_can_format_as_text_now, game_text_format,
86e60e3d 2077 new_ui,
2078 free_ui,
2079 encode_ui,
2080 decode_ui,
2081 game_changed_state,
2082 interpret_move,
2083 execute_move,
2084 PREFERRED_TILESIZE, game_compute_size, game_set_size,
2085 game_colours,
2086 game_new_drawstate,
2087 game_free_drawstate,
2088 game_redraw,
2089 game_anim_length,
2090 game_flash_length,
2091 TRUE, FALSE, game_print_size, game_print,
ac9f41c4 2092 FALSE, /* wants_statusbar */
86e60e3d 2093 FALSE, game_timing_state,
cb0c7d4a 2094 REQUIRE_RBUTTON, /* flags */
86e60e3d 2095};
2096
2097#ifdef STANDALONE_SOLVER
2098
2099#include <stdarg.h>
2100
2101int main(int argc, char **argv)
2102{
2103 game_params *p;
2104 game_state *s, *s2;
2105 char *id = NULL, *desc, *err;
2106 int grade = FALSE;
2107 int ret, diff, really_verbose = FALSE;
2108 struct solver_scratch *sc;
2109
2110 while (--argc > 0) {
2111 char *p = *++argv;
2112 if (!strcmp(p, "-v")) {
2113 really_verbose = TRUE;
2114 } else if (!strcmp(p, "-g")) {
2115 grade = TRUE;
2116 } else if (*p == '-') {
2117 fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
2118 return 1;
2119 } else {
2120 id = p;
2121 }
2122 }
2123
2124 if (!id) {
2125 fprintf(stderr, "usage: %s [-g | -v] <game_id>\n", argv[0]);
2126 return 1;
2127 }
2128
2129 desc = strchr(id, ':');
2130 if (!desc) {
2131 fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
2132 return 1;
2133 }
2134 *desc++ = '\0';
2135
2136 p = default_params();
2137 decode_params(p, id);
2138 err = validate_desc(p, desc);
2139 if (err) {
2140 fprintf(stderr, "%s: %s\n", argv[0], err);
2141 return 1;
2142 }
2143 s = new_game(NULL, p, desc);
2144 s2 = new_game(NULL, p, desc);
2145
2146 sc = new_scratch(p->w, p->h);
2147
2148 /*
2149 * When solving an Easy puzzle, we don't want to bother the
2150 * user with Hard-level deductions. For this reason, we grade
2151 * the puzzle internally before doing anything else.
2152 */
2153 ret = -1; /* placate optimiser */
2154 for (diff = 0; diff < DIFFCOUNT; diff++) {
2155 ret = tents_solve(p->w, p->h, s->grid, s->numbers->numbers,
2156 s2->grid, sc, diff);
2157 if (ret < 2)
2158 break;
2159 }
2160
2161 if (diff == DIFFCOUNT) {
2162 if (grade)
2163 printf("Difficulty rating: too hard to solve internally\n");
2164 else
2165 printf("Unable to find a unique solution\n");
2166 } else {
2167 if (grade) {
2168 if (ret == 0)
2169 printf("Difficulty rating: impossible (no solution exists)\n");
2170 else if (ret == 1)
2171 printf("Difficulty rating: %s\n", tents_diffnames[diff]);
2172 } else {
2173 verbose = really_verbose;
2174 ret = tents_solve(p->w, p->h, s->grid, s->numbers->numbers,
2175 s2->grid, sc, diff);
2176 if (ret == 0)
2177 printf("Puzzle is inconsistent\n");
2178 else
2179 fputs(game_text_format(s2), stdout);
2180 }
2181 }
2182
2183 return 0;
2184}
2185
2186#endif