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