2 * towers.c: the puzzle also known as 'Skyscrapers'.
4 * Possible future work:
6 * - Relax the upper bound on grid size at 9?
7 * + I'd need TOCHAR and FROMCHAR macros a bit like group's, to
8 * be used wherever this code has +'0' or -'0'
9 * + the pencil marks in the drawstate would need a separate
11 * + the clues outside the grid would have to cope with being
12 * multi-digit, meaning in particular that the text formatting
13 * would become more unpleasant
14 * + most importantly, though, the solver just isn't fast
15 * enough. Even at size 9 it can't really do the solver_hard
16 * factorial-time enumeration at a sensible rate. Easy puzzles
17 * higher than that would be possible, but more latin-squarey
18 * than skyscrapery, as it were.
32 * Difficulty levels. I do some macro ickery here to ensure that my
33 * enum and the various forms of my name list always match up.
36 A(EASY,Easy,solver_easy,e) \
37 A(HARD,Hard,solver_hard,h) \
38 A(EXTREME,Extreme,NULL,x) \
39 A(UNREASONABLE,Unreasonable,NULL,u)
40 #define ENUM(upper,title,func,lower) DIFF_ ## upper,
41 #define TITLE(upper,title,func,lower) #title,
42 #define ENCODE(upper,title,func,lower) #lower
43 #define CONFIG(upper,title,func,lower) ":" #title
44 enum { DIFFLIST(ENUM) DIFFCOUNT };
45 static char const *const towers_diffnames[] = { DIFFLIST(TITLE) };
46 static char const towers_diffchars[] = DIFFLIST(ENCODE);
47 #define DIFFCONFIG DIFFLIST(CONFIG)
68 * An array of 4w integers, of which:
69 * - the first w run across the top
70 * - the next w across the bottom
71 * - the third w down the left
72 * - the last w down the right.
77 * An array of w*w digits.
83 * Macros to compute clue indices and coordinates.
85 #define STARTSTEP(start, step, index, w) do { \
87 start = index, step = w; \
88 else if (index < 2*w) \
89 start = (w-1)*w+(index-w), step = -w; \
90 else if (index < 3*w) \
91 start = w*(index-2*w), step = 1; \
93 start = w*(index-3*w)+(w-1), step = -1; \
95 #define CSTARTSTEP(start, step, index, w) \
96 STARTSTEP(start, step, (((index)+2*w)%(4*w)), w)
97 #define CLUEPOS(x, y, index, w) do { \
100 else if (index < 2*w) \
101 x = index-w, y = w; \
102 else if (index < 3*w) \
103 x = -1, y = index-2*w; \
105 x = w, y = index-3*w; \
108 #ifdef STANDALONE_SOLVER
109 static const char *const cluepos[] = {
110 "above column", "below column", "left of row", "right of row"
119 int *pencil; /* bitmaps using bits 1<<1..1<<n */
120 bool completed, cheated;
123 static game_params *default_params(void)
125 game_params *ret = snew(game_params);
128 ret->diff = DIFF_EASY;
133 static const struct game_params towers_presets[] = {
140 { 6, DIFF_UNREASONABLE },
143 static bool game_fetch_preset(int i, char **name, game_params **params)
148 if (i < 0 || i >= lenof(towers_presets))
151 ret = snew(game_params);
152 *ret = towers_presets[i]; /* structure copy */
154 sprintf(buf, "%dx%d %s", ret->w, ret->w, towers_diffnames[ret->diff]);
161 static void free_params(game_params *params)
166 static game_params *dup_params(const game_params *params)
168 game_params *ret = snew(game_params);
169 *ret = *params; /* structure copy */
173 static void decode_params(game_params *params, char const *string)
175 char const *p = string;
178 while (*p && isdigit((unsigned char)*p)) p++;
183 params->diff = DIFFCOUNT+1; /* ...which is invalid */
185 for (i = 0; i < DIFFCOUNT; i++) {
186 if (*p == towers_diffchars[i])
194 static char *encode_params(const game_params *params, bool full)
198 sprintf(ret, "%d", params->w);
200 sprintf(ret + strlen(ret), "d%c", towers_diffchars[params->diff]);
205 static config_item *game_configure(const game_params *params)
210 ret = snewn(3, config_item);
212 ret[0].name = "Grid size";
213 ret[0].type = C_STRING;
214 sprintf(buf, "%d", params->w);
215 ret[0].u.string.sval = dupstr(buf);
217 ret[1].name = "Difficulty";
218 ret[1].type = C_CHOICES;
219 ret[1].u.choices.choicenames = DIFFCONFIG;
220 ret[1].u.choices.selected = params->diff;
228 static game_params *custom_params(const config_item *cfg)
230 game_params *ret = snew(game_params);
232 ret->w = atoi(cfg[0].u.string.sval);
233 ret->diff = cfg[1].u.choices.selected;
238 static const char *validate_params(const game_params *params, bool full)
240 if (params->w < 3 || params->w > 9)
241 return "Grid size must be between 3 and 9";
242 if (params->diff >= DIFFCOUNT)
243 return "Unknown difficulty rating";
247 /* ----------------------------------------------------------------------
259 static int solver_easy(struct latin_solver *solver, void *vctx)
261 struct solver_ctx *ctx = (struct solver_ctx *)vctx;
263 int c, i, j, n, m, furthest;
264 int start, step, cstart, cstep, clue, pos, cpos;
266 #ifdef STANDALONE_SOLVER
273 * One-off loop to help get started: when a pair of facing
274 * clues sum to w+1, it must mean that the row consists of
275 * two increasing sequences back to back, so we can
276 * immediately place the highest digit by knowing the
277 * lengths of those two sequences.
279 for (c = 0; c < 3*w; c = (c == w-1 ? 2*w : c+1)) {
282 if (ctx->clues[c] && ctx->clues[c2] &&
283 ctx->clues[c] + ctx->clues[c2] == w+1) {
284 STARTSTEP(start, step, c, w);
285 CSTARTSTEP(cstart, cstep, c, w);
286 pos = start + (ctx->clues[c]-1)*step;
287 cpos = cstart + (ctx->clues[c]-1)*cstep;
288 if (solver->cube[cpos*w+w-1]) {
289 #ifdef STANDALONE_SOLVER
290 if (solver_show_working) {
291 printf("%*sfacing clues on %s %d are maximal:\n",
292 solver_recurse_depth*4, "",
293 c>=2*w ? "row" : "column", c % w + 1);
294 printf("%*s placing %d at (%d,%d)\n",
295 solver_recurse_depth*4, "",
296 w, pos%w+1, pos/w+1);
299 latin_solver_place(solver, pos%w, pos/w, w);
312 * Go over every clue doing reasonably simple heuristic
315 for (c = 0; c < 4*w; c++) {
316 clue = ctx->clues[c];
319 STARTSTEP(start, step, c, w);
320 CSTARTSTEP(cstart, cstep, c, w);
322 /* Find the location of each number in the row. */
323 for (i = 0; i < w; i++)
324 ctx->dscratch[i] = w;
325 for (i = 0; i < w; i++)
326 if (solver->grid[start+i*step])
327 ctx->dscratch[solver->grid[start+i*step]-1] = i;
331 for (i = w; i >= 1; i--) {
332 if (ctx->dscratch[i-1] == w) {
334 } else if (ctx->dscratch[i-1] < furthest) {
335 furthest = ctx->dscratch[i-1];
340 if (clue == n+1 && furthest > 1) {
341 #ifdef STANDALONE_SOLVER
342 if (solver_show_working)
343 sprintf(prefix, "%*sclue %s %d is nearly filled:\n",
344 solver_recurse_depth*4, "",
345 cluepos[c/w], c%w+1);
347 prefix[0] = '\0'; /* placate optimiser */
350 * We can already see an increasing sequence of the very
351 * highest numbers, of length one less than that
352 * specified in the clue. All of those numbers _must_ be
353 * part of the clue sequence, so the number right next
354 * to the clue must be the final one - i.e. it must be
355 * bigger than any of the numbers between it and m. This
356 * allows us to rule out small numbers in that square.
358 * (This is a generalisation of the obvious deduction
359 * that when you see a clue saying 1, it must be right
360 * next to the largest possible number; and similarly,
361 * when you see a clue saying 2 opposite that, it must
362 * be right next to the second-largest.)
364 j = furthest-1; /* number of small numbers we can rule out */
365 for (i = 1; i <= w && j > 0; i++) {
366 if (ctx->dscratch[i-1] < w && ctx->dscratch[i-1] >= furthest)
367 continue; /* skip this number, it's elsewhere */
369 if (solver->cube[cstart*w+i-1]) {
370 #ifdef STANDALONE_SOLVER
371 if (solver_show_working) {
372 printf("%s%*s ruling out %d at (%d,%d)\n",
373 prefix, solver_recurse_depth*4, "",
374 i, start%w+1, start/w+1);
378 solver->cube[cstart*w+i-1] = 0;
387 #ifdef STANDALONE_SOLVER
388 if (solver_show_working)
389 sprintf(prefix, "%*slower bounds for clue %s %d:\n",
390 solver_recurse_depth*4, "",
391 cluepos[c/w], c%w+1);
393 prefix[0] = '\0'; /* placate optimiser */
397 for (n = w; n > 0; n--) {
399 * The largest number cannot occur in the first (clue-1)
400 * squares of the row, or else there wouldn't be space
401 * for a sufficiently long increasing sequence which it
402 * terminated. The second-largest number (not counting
403 * any that are known to be on the far side of a larger
404 * number and hence excluded from this sequence) cannot
405 * occur in the first (clue-2) squares, similarly, and
409 if (ctx->dscratch[n-1] < w) {
410 for (m = n+1; m < w; m++)
411 if (ctx->dscratch[m] < ctx->dscratch[n-1])
414 continue; /* this number doesn't count */
417 for (j = 0; j < clue - i - 1; j++)
418 if (solver->cube[(cstart + j*cstep)*w+n-1]) {
419 #ifdef STANDALONE_SOLVER
420 if (solver_show_working) {
421 int pos = start+j*step;
422 printf("%s%*s ruling out %d at (%d,%d)\n",
423 prefix, solver_recurse_depth*4, "",
424 n, pos%w+1, pos/w+1);
428 solver->cube[(cstart + j*cstep)*w+n-1] = 0;
441 static int solver_hard(struct latin_solver *solver, void *vctx)
443 struct solver_ctx *ctx = (struct solver_ctx *)vctx;
445 int c, i, j, n, best, clue, start, step, ret;
447 #ifdef STANDALONE_SOLVER
452 * Go over every clue analysing all possibilities.
454 for (c = 0; c < 4*w; c++) {
455 clue = ctx->clues[c];
458 CSTARTSTEP(start, step, c, w);
460 for (i = 0; i < w; i++)
461 ctx->iscratch[i] = 0;
464 * Instead of a tedious physical recursion, I iterate in the
465 * scratch array through all possibilities. At any given
466 * moment, i indexes the element of the box that will next
470 ctx->dscratch[i] = 0;
477 * Find the next valid value for cell i.
479 int limit = (n == clue ? best : w);
480 int pos = start + step * i;
481 for (j = ctx->dscratch[i] + 1; j <= limit; j++) {
482 if (bitmap & (1L << j))
483 continue; /* used this one already */
484 if (!solver->cube[pos*w+j-1])
485 continue; /* ruled out already */
492 /* No valid values left; drop back. */
495 break; /* overall iteration is finished */
496 bitmap &= ~(1L << ctx->dscratch[i]);
497 if (ctx->dscratch[i] == best) {
500 for (j = 0; j < i; j++)
501 if (best < ctx->dscratch[j])
502 best = ctx->dscratch[j];
505 /* Got a valid value; store it and move on. */
507 ctx->dscratch[i++] = j;
512 ctx->dscratch[i] = 0;
516 for (j = 0; j < w; j++)
517 ctx->iscratch[j] |= 1L << ctx->dscratch[j];
520 bitmap &= ~(1L << ctx->dscratch[i]);
521 if (ctx->dscratch[i] == best) {
524 for (j = 0; j < i; j++)
525 if (best < ctx->dscratch[j])
526 best = ctx->dscratch[j];
531 #ifdef STANDALONE_SOLVER
532 if (solver_show_working)
533 sprintf(prefix, "%*sexhaustive analysis of clue %s %d:\n",
534 solver_recurse_depth*4, "",
535 cluepos[c/w], c%w+1);
537 prefix[0] = '\0'; /* placate optimiser */
542 for (i = 0; i < w; i++) {
543 int pos = start + step * i;
544 for (j = 1; j <= w; j++) {
545 if (solver->cube[pos*w+j-1] &&
546 !(ctx->iscratch[i] & (1L << j))) {
547 #ifdef STANDALONE_SOLVER
548 if (solver_show_working) {
549 printf("%s%*s ruling out %d at (%d,%d)\n",
550 prefix, solver_recurse_depth*4, "",
551 j, pos/w+1, pos%w+1);
555 solver->cube[pos*w+j-1] = 0;
561 * Once we find one clue we can do something with in
562 * this way, revert to trying easier deductions, so as
563 * not to generate solver diagnostics that make the
564 * problem look harder than it is.
574 #define SOLVER(upper,title,func,lower) func,
575 static usersolver_t const towers_solvers[] = { DIFFLIST(SOLVER) };
577 static bool towers_valid(struct latin_solver *solver, void *vctx)
579 struct solver_ctx *ctx = (struct solver_ctx *)vctx;
581 int c, i, n, best, clue, start, step;
582 for (c = 0; c < 4*w; c++) {
583 clue = ctx->clues[c];
587 STARTSTEP(start, step, c, w);
589 for (i = 0; i < w; i++) {
590 if (solver->grid[start+i*step] > best) {
591 best = solver->grid[start+i*step];
597 #ifdef STANDALONE_SOLVER
598 if (solver_show_working)
599 printf("%*sclue %s %d is violated\n",
600 solver_recurse_depth*4, "",
601 cluepos[c/w], c%w+1);
609 static int solver(int w, int *clues, digit *soln, int maxdiff)
612 struct solver_ctx ctx;
618 ctx.iscratch = snewn(w, long);
619 ctx.dscratch = snewn(w+1, int);
621 ret = latin_solver(soln, w, maxdiff,
622 DIFF_EASY, DIFF_HARD, DIFF_EXTREME,
623 DIFF_EXTREME, DIFF_UNREASONABLE,
624 towers_solvers, towers_valid, &ctx, NULL, NULL);
632 /* ----------------------------------------------------------------------
636 static char *new_game_desc(const game_params *params, random_state *rs,
637 char **aux, bool interactive)
639 int w = params->w, a = w*w;
640 digit *grid, *soln, *soln2;
643 int diff = params->diff;
647 * Difficulty exceptions: some combinations of size and
648 * difficulty cannot be satisfied, because all puzzles of at
649 * most that difficulty are actually even easier.
651 * Remember to re-test this whenever a change is made to the
654 * I tested it using the following shell command:
658 echo -n "./towers --generate 1 ${i}d${d}: "
659 perl -e 'alarm 30; exec @ARGV' ./towers --generate 1 ${i}d${d} >/dev/null \
664 * Of course, it's better to do that after taking the exceptions
665 * _out_, so as to detect exceptions that should be removed as
666 * well as those which should be added.
668 if (diff > DIFF_HARD && w <= 3)
672 clues = snewn(4*w, int);
673 soln = snewn(a, digit);
674 soln2 = snewn(a, digit);
675 order = snewn(max(4*w,a), int);
679 * Construct a latin square to be the solution.
682 grid = latin_generate(w, rs);
687 for (i = 0; i < 4*w; i++) {
688 int start, step, j, k, best;
689 STARTSTEP(start, step, i, w);
691 for (j = 0; j < w; j++) {
692 if (grid[start+j*step] > best) {
693 best = grid[start+j*step];
701 * Remove the grid numbers and then the clues, one by one,
702 * for as long as the game remains soluble at the given
705 memcpy(soln, grid, a);
707 if (diff == DIFF_EASY && w <= 5) {
709 * Special case: for Easy-mode grids that are small
710 * enough, it's nice to be able to find completely empty
714 ret = solver(w, clues, soln2, diff);
719 for (i = 0; i < a; i++)
721 shuffle(order, a, sizeof(*order), rs);
722 for (i = 0; i < a; i++) {
725 memcpy(soln2, grid, a);
727 ret = solver(w, clues, soln2, diff);
732 if (diff > DIFF_EASY) { /* leave all clues on Easy mode */
733 for (i = 0; i < 4*w; i++)
735 shuffle(order, 4*w, sizeof(*order), rs);
736 for (i = 0; i < 4*w; i++) {
740 memcpy(soln2, grid, a);
742 ret = solver(w, clues, soln2, diff);
749 * See if the game can be solved at the specified difficulty
750 * level, but not at the one below.
752 memcpy(soln2, grid, a);
753 ret = solver(w, clues, soln2, diff);
755 continue; /* go round again */
758 * We've got a usable puzzle!
764 * Encode the puzzle description.
766 desc = snewn(40*a, char);
768 for (i = 0; i < 4*w; i++) {
772 p += sprintf(p, "%d", clues[i]);
774 for (i = 0; i < a; i++)
782 for (i = 0; i <= a; i++) {
783 int n = (i < a ? grid[i] : -1);
790 int thisrun = min(run, 26);
791 *p++ = thisrun - 1 + 'a';
796 * If there's a number in the very top left or
797 * bottom right, there's no point putting an
798 * unnecessary _ before or after it.
804 p += sprintf(p, "%d", n);
810 desc = sresize(desc, p - desc, char);
813 * Encode the solution.
815 *aux = snewn(a+2, char);
817 for (i = 0; i < a; i++)
818 (*aux)[i+1] = '0' + soln[i];
830 /* ----------------------------------------------------------------------
834 static const char *validate_desc(const game_params *params, const char *desc)
836 int w = params->w, a = w*w;
837 const char *p = desc;
841 * Verify that the right number of clues are given, and that
844 for (i = 0; i < 4*w; i++) {
846 return "Too few clues for grid size";
850 return "Expected commas between clues";
854 if (isdigit((unsigned char)*p)) {
856 while (*p && isdigit((unsigned char)*p)) p++;
858 if (clue <= 0 || clue > w)
859 return "Clue number out of range";
863 return "Too many clues for grid size";
867 * Verify that the right amount of grid data is given, and
868 * that any grid elements provided are in range.
875 if (c >= 'a' && c <= 'z') {
876 squares += c - 'a' + 1;
877 } else if (c == '_') {
879 } else if (c > '0' && c <= '9') {
881 if (val < 1 || val > w)
882 return "Out-of-range number in grid description";
884 while (*p && isdigit((unsigned char)*p)) p++;
886 return "Invalid character in game description";
890 return "Not enough data to fill grid";
893 return "Too much data to fit in grid";
899 static key_label *game_request_keys(const game_params *params, int *nkeys)
903 key_label *keys = snewn(w+1, key_label);
906 for (i = 0; i < w; i++) {
907 if (i<9) keys[i].button = '1' + i;
908 else keys[i].button = 'a' + i - 9;
910 keys[i].label = NULL;
912 keys[w].button = '\b';
913 keys[w].label = NULL;
918 static game_state *new_game(midend *me, const game_params *params,
921 int w = params->w, a = w*w;
922 game_state *state = snew(game_state);
923 const char *p = desc;
926 state->par = *params; /* structure copy */
927 state->clues = snew(struct clues);
928 state->clues->refcount = 1;
930 state->clues->clues = snewn(4*w, int);
931 state->clues->immutable = snewn(a, digit);
932 state->grid = snewn(a, digit);
933 state->clues_done = snewn(4*w, bool);
934 state->pencil = snewn(a, int);
936 for (i = 0; i < a; i++) {
938 state->pencil[i] = 0;
941 memset(state->clues->immutable, 0, a);
942 memset(state->clues_done, 0, 4*w*sizeof(bool));
944 for (i = 0; i < 4*w; i++) {
949 if (*p && isdigit((unsigned char)*p)) {
950 state->clues->clues[i] = atoi(p);
951 while (*p && isdigit((unsigned char)*p)) p++;
953 state->clues->clues[i] = 0;
961 if (c >= 'a' && c <= 'z') {
963 } else if (c == '_') {
965 } else if (c > '0' && c <= '9') {
967 assert(val >= 1 && val <= w);
969 state->grid[pos] = state->clues->immutable[pos] = val;
971 while (*p && isdigit((unsigned char)*p)) p++;
973 assert(!"Corrupt game description");
979 state->completed = false;
980 state->cheated = false;
985 static game_state *dup_game(const game_state *state)
987 int w = state->par.w, a = w*w;
988 game_state *ret = snew(game_state);
990 ret->par = state->par; /* structure copy */
992 ret->clues = state->clues;
993 ret->clues->refcount++;
995 ret->grid = snewn(a, digit);
996 ret->pencil = snewn(a, int);
997 ret->clues_done = snewn(4*w, bool);
998 memcpy(ret->grid, state->grid, a*sizeof(digit));
999 memcpy(ret->pencil, state->pencil, a*sizeof(int));
1000 memcpy(ret->clues_done, state->clues_done, 4*w*sizeof(bool));
1002 ret->completed = state->completed;
1003 ret->cheated = state->cheated;
1008 static void free_game(game_state *state)
1011 sfree(state->pencil);
1012 sfree(state->clues_done);
1013 if (--state->clues->refcount <= 0) {
1014 sfree(state->clues->immutable);
1015 sfree(state->clues->clues);
1016 sfree(state->clues);
1021 static char *solve_game(const game_state *state, const game_state *currstate,
1022 const char *aux, const char **error)
1024 int w = state->par.w, a = w*w;
1032 soln = snewn(a, digit);
1033 memcpy(soln, state->clues->immutable, a);
1035 ret = solver(w, state->clues->clues, soln, DIFFCOUNT-1);
1037 if (ret == diff_impossible) {
1038 *error = "No solution exists for this puzzle";
1040 } else if (ret == diff_ambiguous) {
1041 *error = "Multiple solutions exist for this puzzle";
1044 out = snewn(a+2, char);
1046 for (i = 0; i < a; i++)
1047 out[i+1] = '0' + soln[i];
1055 static bool game_can_format_as_text_now(const game_params *params)
1060 static char *game_text_format(const game_state *state)
1062 int w = state->par.w /* , a = w*w */;
1070 * - a top clue row, consisting of three spaces, then w clue
1071 * digits with spaces between (total 2*w+3 chars including
1073 * - a blank line (one newline)
1074 * - w main rows, consisting of a left clue digit, two spaces,
1075 * w grid digits with spaces between, two spaces and a right
1076 * clue digit (total 2*w+6 chars each including newline)
1077 * - a blank line (one newline)
1078 * - a bottom clue row (same as top clue row)
1079 * - terminating NUL.
1081 * Total size is therefore 2*(2*w+3) + 2 + w*(2*w+6) + 1
1084 total = 2*w*w + 10*w + 9;
1085 ret = snewn(total, char);
1089 *p++ = ' '; *p++ = ' ';
1090 for (x = 0; x < w; x++) {
1092 *p++ = (state->clues->clues[x] ? '0' + state->clues->clues[x] : ' ');
1100 for (y = 0; y < w; y++) {
1101 *p++ = (state->clues->clues[y+2*w] ? '0' + state->clues->clues[y+2*w] :
1104 for (x = 0; x < w; x++) {
1106 *p++ = (state->grid[y*w+x] ? '0' + state->grid[y*w+x] : ' ');
1108 *p++ = ' '; *p++ = ' ';
1109 *p++ = (state->clues->clues[y+3*w] ? '0' + state->clues->clues[y+3*w] :
1117 /* Bottom clue row. */
1118 *p++ = ' '; *p++ = ' ';
1119 for (x = 0; x < w; x++) {
1121 *p++ = (state->clues->clues[x+w] ? '0' + state->clues->clues[x+w] :
1127 assert(p == ret + total);
1134 * These are the coordinates of the currently highlighted
1135 * square on the grid, if hshow = 1.
1139 * This indicates whether the current highlight is a
1140 * pencil-mark one or a real one.
1144 * This indicates whether or not we're showing the highlight
1145 * (used to be hx = hy = -1); important so that when we're
1146 * using the cursor keys it doesn't keep coming back at a
1147 * fixed position. When hshow = 1, pressing a valid number
1148 * or letter key or Space will enter that number or letter in the grid.
1152 * This indicates whether we're using the highlight as a cursor;
1153 * it means that it doesn't vanish on a keypress, and that it is
1154 * allowed on immutable squares.
1159 static game_ui *new_ui(const game_state *state)
1161 game_ui *ui = snew(game_ui);
1163 ui->hx = ui->hy = 0;
1164 ui->hpencil = false;
1166 ui->hcursor = false;
1171 static void free_ui(game_ui *ui)
1176 static char *encode_ui(const game_ui *ui)
1181 static void decode_ui(game_ui *ui, const char *encoding)
1185 static void game_changed_state(game_ui *ui, const game_state *oldstate,
1186 const game_state *newstate)
1188 int w = newstate->par.w;
1190 * We prevent pencil-mode highlighting of a filled square, unless
1191 * we're using the cursor keys. So if the user has just filled in
1192 * a square which we had a pencil-mode highlight in (by Undo, or
1193 * by Redo, or by Solve), then we cancel the highlight.
1195 if (ui->hshow && ui->hpencil && !ui->hcursor &&
1196 newstate->grid[ui->hy * w + ui->hx] != 0) {
1201 #define PREFERRED_TILESIZE 48
1202 #define TILESIZE (ds->tilesize)
1203 #define BORDER (TILESIZE * 9 / 8)
1204 #define COORD(x) ((x)*TILESIZE + BORDER)
1205 #define FROMCOORD(x) (((x)+(TILESIZE-BORDER)) / TILESIZE - 1)
1207 /* These always return positive values, though y offsets are actually -ve */
1208 #define X_3D_DISP(height, w) ((height) * TILESIZE / (8 * (w)))
1209 #define Y_3D_DISP(height, w) ((height) * TILESIZE / (4 * (w)))
1211 #define FLASH_TIME 0.4F
1213 #define DF_PENCIL_SHIFT 16
1214 #define DF_CLUE_DONE 0x10000
1215 #define DF_ERROR 0x8000
1216 #define DF_HIGHLIGHT 0x4000
1217 #define DF_HIGHLIGHT_PENCIL 0x2000
1218 #define DF_IMMUTABLE 0x1000
1219 #define DF_PLAYAREA 0x0800
1220 #define DF_DIGIT_MASK 0x00FF
1222 struct game_drawstate {
1224 bool three_d; /* default 3D graphics are user-disableable */
1226 long *tiles; /* (w+2)*(w+2) temp space */
1227 long *drawn; /* (w+2)*(w+2)*4: current drawn data */
1231 static bool check_errors(const game_state *state, bool *errors)
1233 int w = state->par.w /*, a = w*w */;
1234 int W = w+2, A = W*W; /* the errors array is (w+2) square */
1235 int *clues = state->clues->clues;
1236 digit *grid = state->grid;
1241 assert(w < lenof(tmp));
1244 for (i = 0; i < A; i++)
1247 for (y = 0; y < w; y++) {
1248 unsigned long mask = 0, errmask = 0;
1249 for (x = 0; x < w; x++) {
1250 unsigned long bit = 1UL << grid[y*w+x];
1251 errmask |= (mask & bit);
1255 if (mask != (1L << (w+1)) - (1L << 1)) {
1259 for (x = 0; x < w; x++)
1260 if (errmask & (1UL << grid[y*w+x]))
1261 errors[(y+1)*W+(x+1)] = true;
1266 for (x = 0; x < w; x++) {
1267 unsigned long mask = 0, errmask = 0;
1268 for (y = 0; y < w; y++) {
1269 unsigned long bit = 1UL << grid[y*w+x];
1270 errmask |= (mask & bit);
1274 if (mask != (1 << (w+1)) - (1 << 1)) {
1278 for (y = 0; y < w; y++)
1279 if (errmask & (1UL << grid[y*w+x]))
1280 errors[(y+1)*W+(x+1)] = true;
1285 for (i = 0; i < 4*w; i++) {
1286 int start, step, j, n, best;
1287 STARTSTEP(start, step, i, w);
1293 for (j = 0; j < w; j++) {
1294 int number = grid[start+j*step];
1296 break; /* can't tell what happens next */
1297 if (number > best) {
1303 if (n > clues[i] || (best == w && n < clues[i]) ||
1304 (best < w && n == clues[i])) {
1307 CLUEPOS(x, y, i, w);
1308 errors[(y+1)*W+(x+1)] = true;
1317 static int clue_index(const game_state *state, int x, int y)
1319 int w = state->par.w;
1321 if (x == -1 || x == w)
1322 return w * (x == -1 ? 2 : 3) + y;
1323 else if (y == -1 || y == w)
1324 return (y == -1 ? 0 : w) + x;
1329 static bool is_clue(const game_state *state, int x, int y)
1331 int w = state->par.w;
1333 if (((x == -1 || x == w) && y >= 0 && y < w) ||
1334 ((y == -1 || y == w) && x >= 0 && x < w))
1336 if (state->clues->clues[clue_index(state, x, y)] & DF_DIGIT_MASK)
1343 static char *interpret_move(const game_state *state, game_ui *ui,
1344 const game_drawstate *ds,
1345 int x, int y, int button)
1347 int w = state->par.w;
1348 bool shift_or_control = button & (MOD_SHFT | MOD_CTRL);
1352 button &= ~MOD_MASK;
1359 * In 3D mode, just locating the mouse click in the natural
1360 * square grid may not be sufficient to tell which tower the
1361 * user clicked on. Investigate the _tops_ of the nearby
1362 * towers to see if a click on one grid square was actually
1363 * a click on a tower protruding into that region from
1367 for (dy = 0; dy <= 1; dy++)
1368 for (dx = 0; dx >= -1; dx--) {
1369 int cx = tx + dx, cy = ty + dy;
1370 if (cx >= 0 && cx < w && cy >= 0 && cy < w) {
1371 int height = state->grid[cy*w+cx];
1372 int bx = COORD(cx), by = COORD(cy);
1373 int ox = bx + X_3D_DISP(height, w);
1374 int oy = by - Y_3D_DISP(height, w);
1375 if (/* on top face? */
1376 (x - ox >= 0 && x - ox < TILESIZE &&
1377 y - oy >= 0 && y - oy < TILESIZE) ||
1378 /* in triangle between top-left corners? */
1379 (ox > bx && x >= bx && x <= ox && y <= by &&
1380 (by-y) * (ox-bx) <= (by-oy) * (x-bx)) ||
1381 /* in triangle between bottom-right corners? */
1382 (ox > bx && x >= bx+TILESIZE && x <= ox+TILESIZE &&
1384 (by-y+TILESIZE)*(ox-bx) >= (by-oy)*(x-bx-TILESIZE))) {
1392 if (tx >= 0 && tx < w && ty >= 0 && ty < w) {
1393 if (button == LEFT_BUTTON) {
1394 if (tx == ui->hx && ty == ui->hy &&
1395 ui->hshow && !ui->hpencil) {
1400 ui->hshow = !state->clues->immutable[ty*w+tx];
1401 ui->hpencil = false;
1403 ui->hcursor = false;
1406 if (button == RIGHT_BUTTON) {
1408 * Pencil-mode highlighting for non filled squares.
1410 if (state->grid[ty*w+tx] == 0) {
1411 if (tx == ui->hx && ty == ui->hy &&
1412 ui->hshow && ui->hpencil) {
1423 ui->hcursor = false;
1426 } else if (button == LEFT_BUTTON) {
1427 if (is_clue(state, tx, ty)) {
1428 sprintf(buf, "%c%d,%d", 'D', tx, ty);
1432 if (IS_CURSOR_MOVE(button)) {
1433 if (shift_or_control) {
1434 int x = ui->hx, y = ui->hy;
1436 case CURSOR_LEFT: x = -1; break;
1437 case CURSOR_RIGHT: x = w; break;
1438 case CURSOR_UP: y = -1; break;
1439 case CURSOR_DOWN: y = w; break;
1441 if (is_clue(state, x, y)) {
1442 sprintf(buf, "%c%d,%d", 'D', x, y);
1447 move_cursor(button, &ui->hx, &ui->hy, w, w, false);
1453 (button == CURSOR_SELECT)) {
1454 ui->hpencil = !ui->hpencil;
1460 ((button >= '0' && button <= '9' && button - '0' <= w) ||
1461 button == CURSOR_SELECT2 || button == '\b')) {
1462 int n = button - '0';
1463 if (button == CURSOR_SELECT2 || button == '\b')
1467 * Can't make pencil marks in a filled square. This can only
1468 * become highlighted if we're using cursor keys.
1470 if (ui->hpencil && state->grid[ui->hy*w+ui->hx])
1474 * Can't do anything to an immutable square.
1476 if (state->clues->immutable[ui->hy*w+ui->hx])
1479 sprintf(buf, "%c%d,%d,%d",
1480 (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
1482 if (!ui->hcursor) ui->hshow = false;
1487 if (button == 'M' || button == 'm')
1493 static game_state *execute_move(const game_state *from, const char *move)
1495 int w = from->par.w, a = w*w;
1496 game_state *ret = dup_game(from);
1499 if (move[0] == 'S') {
1500 ret->completed = ret->cheated = true;
1502 for (i = 0; i < a; i++) {
1503 if (move[i+1] < '1' || move[i+1] > '0'+w)
1505 ret->grid[i] = move[i+1] - '0';
1509 if (move[a+1] != '\0')
1513 } else if ((move[0] == 'P' || move[0] == 'R') &&
1514 sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 &&
1515 x >= 0 && x < w && y >= 0 && y < w && n >= 0 && n <= w) {
1516 if (from->clues->immutable[y*w+x])
1519 if (move[0] == 'P' && n > 0) {
1520 ret->pencil[y*w+x] ^= 1L << n;
1522 ret->grid[y*w+x] = n;
1523 ret->pencil[y*w+x] = 0;
1525 if (!ret->completed && !check_errors(ret, NULL))
1526 ret->completed = true;
1529 } else if (move[0] == 'M') {
1531 * Fill in absolutely all pencil marks everywhere. (I
1532 * wouldn't use this for actual play, but it's a handy
1533 * starting point when following through a set of
1534 * diagnostics output by the standalone solver.)
1536 for (i = 0; i < a; i++) {
1538 ret->pencil[i] = (1L << (w+1)) - (1L << 1);
1541 } else if (move[0] == 'D' && sscanf(move+1, "%d,%d", &x, &y) == 2 &&
1542 is_clue(from, x, y)) {
1543 int index = clue_index(from, x, y);
1544 ret->clues_done[index] = !ret->clues_done[index];
1549 /* couldn't parse move string */
1554 /* ----------------------------------------------------------------------
1558 #define SIZE(w) ((w) * TILESIZE + 2*BORDER)
1560 static void game_compute_size(const game_params *params, int tilesize,
1563 /* Ick: fake up `ds->tilesize' for macro expansion purposes */
1564 struct { int tilesize; } ads, *ds = &ads;
1565 ads.tilesize = tilesize;
1567 *x = *y = SIZE(params->w);
1570 static void game_set_size(drawing *dr, game_drawstate *ds,
1571 const game_params *params, int tilesize)
1573 ds->tilesize = tilesize;
1576 static float *game_colours(frontend *fe, int *ncolours)
1578 float *ret = snewn(3 * NCOLOURS, float);
1580 frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
1582 ret[COL_GRID * 3 + 0] = 0.0F;
1583 ret[COL_GRID * 3 + 1] = 0.0F;
1584 ret[COL_GRID * 3 + 2] = 0.0F;
1586 ret[COL_USER * 3 + 0] = 0.0F;
1587 ret[COL_USER * 3 + 1] = 0.6F * ret[COL_BACKGROUND * 3 + 1];
1588 ret[COL_USER * 3 + 2] = 0.0F;
1590 ret[COL_HIGHLIGHT * 3 + 0] = 0.78F * ret[COL_BACKGROUND * 3 + 0];
1591 ret[COL_HIGHLIGHT * 3 + 1] = 0.78F * ret[COL_BACKGROUND * 3 + 1];
1592 ret[COL_HIGHLIGHT * 3 + 2] = 0.78F * ret[COL_BACKGROUND * 3 + 2];
1594 ret[COL_ERROR * 3 + 0] = 1.0F;
1595 ret[COL_ERROR * 3 + 1] = 0.0F;
1596 ret[COL_ERROR * 3 + 2] = 0.0F;
1598 ret[COL_PENCIL * 3 + 0] = 0.5F * ret[COL_BACKGROUND * 3 + 0];
1599 ret[COL_PENCIL * 3 + 1] = 0.5F * ret[COL_BACKGROUND * 3 + 1];
1600 ret[COL_PENCIL * 3 + 2] = ret[COL_BACKGROUND * 3 + 2];
1602 ret[COL_DONE * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] / 1.5F;
1603 ret[COL_DONE * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] / 1.5F;
1604 ret[COL_DONE * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] / 1.5F;
1606 *ncolours = NCOLOURS;
1610 static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
1612 int w = state->par.w /*, a = w*w */;
1613 struct game_drawstate *ds = snew(struct game_drawstate);
1617 ds->three_d = !getenv("TOWERS_2D");
1618 ds->started = false;
1619 ds->tiles = snewn((w+2)*(w+2), long);
1620 ds->drawn = snewn((w+2)*(w+2)*4, long);
1621 for (i = 0; i < (w+2)*(w+2)*4; i++)
1623 ds->errtmp = snewn((w+2)*(w+2), bool);
1628 static void game_free_drawstate(drawing *dr, game_drawstate *ds)
1636 static void draw_tile(drawing *dr, game_drawstate *ds, struct clues *clues,
1637 int x, int y, long tile)
1639 int w = clues->w /* , a = w*w */;
1646 bg = (tile & DF_HIGHLIGHT) ? COL_HIGHLIGHT : COL_BACKGROUND;
1649 if (ds->three_d && (tile & DF_PLAYAREA) && (tile & DF_DIGIT_MASK)) {
1651 int xoff = X_3D_DISP(tile & DF_DIGIT_MASK, w);
1652 int yoff = Y_3D_DISP(tile & DF_DIGIT_MASK, w);
1654 /* left face of tower */
1658 coords[3] = ty + TILESIZE - 1;
1659 coords[4] = coords[2] + xoff;
1660 coords[5] = coords[3] - yoff;
1661 coords[6] = coords[0] + xoff;
1662 coords[7] = coords[1] - yoff;
1663 draw_polygon(dr, coords, 4, bg, COL_GRID);
1665 /* bottom face of tower */
1666 coords[0] = tx + TILESIZE;
1667 coords[1] = ty + TILESIZE - 1;
1669 coords[3] = ty + TILESIZE - 1;
1670 coords[4] = coords[2] + xoff;
1671 coords[5] = coords[3] - yoff;
1672 coords[6] = coords[0] + xoff;
1673 coords[7] = coords[1] - yoff;
1674 draw_polygon(dr, coords, 4, bg, COL_GRID);
1676 /* now offset all subsequent drawing to the top of the tower */
1681 /* erase background */
1682 draw_rect(dr, tx, ty, TILESIZE, TILESIZE, bg);
1684 /* pencil-mode highlight */
1685 if (tile & DF_HIGHLIGHT_PENCIL) {
1689 coords[2] = tx+TILESIZE/2;
1692 coords[5] = ty+TILESIZE/2;
1693 draw_polygon(dr, coords, 3, COL_HIGHLIGHT, COL_HIGHLIGHT);
1696 /* draw box outline */
1697 if (tile & DF_PLAYAREA) {
1701 coords[2] = tx + TILESIZE;
1703 coords[4] = tx + TILESIZE;
1704 coords[5] = ty + TILESIZE - 1;
1706 coords[7] = ty + TILESIZE - 1;
1707 draw_polygon(dr, coords, 4, -1, COL_GRID);
1710 /* new number needs drawing? */
1711 if (tile & DF_DIGIT_MASK) {
1715 str[0] = (tile & DF_DIGIT_MASK) + '0';
1717 if (tile & DF_ERROR)
1719 else if (tile & DF_CLUE_DONE)
1721 else if (x < 0 || y < 0 || x >= w || y >= w)
1723 else if (tile & DF_IMMUTABLE)
1728 draw_text(dr, tx + TILESIZE/2, ty + TILESIZE/2, FONT_VARIABLE,
1729 (tile & DF_PLAYAREA ? TILESIZE/2 : TILESIZE*2/5),
1730 ALIGN_VCENTRE | ALIGN_HCENTRE, color, str);
1735 int pw, ph, minph, pbest, fontsize;
1737 /* Count the pencil marks required. */
1738 for (i = 1, npencil = 0; i <= w; i++)
1739 if (tile & (1L << (i + DF_PENCIL_SHIFT)))
1746 * Determine the bounding rectangle within which we're going
1747 * to put the pencil marks.
1749 /* Start with the whole square, minus space for impinging towers */
1750 pl = tx + (ds->three_d ? X_3D_DISP(w,w) : 0);
1753 pb = ty + TILESIZE - (ds->three_d ? Y_3D_DISP(w,w) : 0);
1756 * We arrange our pencil marks in a grid layout, with
1757 * the number of rows and columns adjusted to allow the
1758 * maximum font size.
1760 * So now we work out what the grid size ought to be.
1765 for (pw = 3; pw < max(npencil,4); pw++) {
1768 ph = (npencil + pw - 1) / pw;
1769 ph = max(ph, minph);
1770 fw = (pr - pl) / (float)pw;
1771 fh = (pb - pt) / (float)ph;
1773 if (fs > bestsize) {
1780 ph = (npencil + pw - 1) / pw;
1781 ph = max(ph, minph);
1784 * Now we've got our grid dimensions, work out the pixel
1785 * size of a grid element, and round it to the nearest
1786 * pixel. (We don't want rounding errors to make the
1787 * grid look uneven at low pixel sizes.)
1789 fontsize = min((pr - pl) / pw, (pb - pt) / ph);
1792 * Centre the resulting figure in the square.
1794 pl = pl + (pr - pl - fontsize * pw) / 2;
1795 pt = pt + (pb - pt - fontsize * ph) / 2;
1798 * Now actually draw the pencil marks.
1800 for (i = 1, j = 0; i <= w; i++)
1801 if (tile & (1L << (i + DF_PENCIL_SHIFT))) {
1802 int dx = j % pw, dy = j / pw;
1806 draw_text(dr, pl + fontsize * (2*dx+1) / 2,
1807 pt + fontsize * (2*dy+1) / 2,
1808 FONT_VARIABLE, fontsize,
1809 ALIGN_VCENTRE | ALIGN_HCENTRE, COL_PENCIL, str);
1816 static void game_redraw(drawing *dr, game_drawstate *ds,
1817 const game_state *oldstate, const game_state *state,
1818 int dir, const game_ui *ui,
1819 float animtime, float flashtime)
1821 int w = state->par.w /*, a = w*w */;
1826 * The initial contents of the window are not guaranteed and
1827 * can vary with front ends. To be on the safe side, all
1828 * games should start by drawing a big background-colour
1829 * rectangle covering the whole window.
1831 draw_rect(dr, 0, 0, SIZE(w), SIZE(w), COL_BACKGROUND);
1833 draw_update(dr, 0, 0, SIZE(w), SIZE(w));
1838 check_errors(state, ds->errtmp);
1841 * Work out what data each tile should contain.
1843 for (i = 0; i < (w+2)*(w+2); i++)
1844 ds->tiles[i] = 0; /* completely blank square */
1845 /* The clue squares... */
1846 for (i = 0; i < 4*w; i++) {
1847 long tile = state->clues->clues[i];
1849 CLUEPOS(x, y, i, w);
1851 if (ds->errtmp[(y+1)*(w+2)+(x+1)])
1853 else if (state->clues_done[i])
1854 tile |= DF_CLUE_DONE;
1856 ds->tiles[(y+1)*(w+2)+(x+1)] = tile;
1858 /* ... and the main grid. */
1859 for (y = 0; y < w; y++) {
1860 for (x = 0; x < w; x++) {
1861 long tile = DF_PLAYAREA;
1863 if (state->grid[y*w+x])
1864 tile |= state->grid[y*w+x];
1866 tile |= (long)state->pencil[y*w+x] << DF_PENCIL_SHIFT;
1868 if (ui->hshow && ui->hx == x && ui->hy == y)
1869 tile |= (ui->hpencil ? DF_HIGHLIGHT_PENCIL : DF_HIGHLIGHT);
1871 if (state->clues->immutable[y*w+x])
1872 tile |= DF_IMMUTABLE;
1874 if (flashtime > 0 &&
1875 (flashtime <= FLASH_TIME/3 ||
1876 flashtime >= FLASH_TIME*2/3))
1877 tile |= DF_HIGHLIGHT; /* completion flash */
1879 if (ds->errtmp[(y+1)*(w+2)+(x+1)])
1882 ds->tiles[(y+1)*(w+2)+(x+1)] = tile;
1887 * Now actually draw anything that needs to be changed.
1889 for (y = 0; y < w+2; y++) {
1890 for (x = 0; x < w+2; x++) {
1891 long tl, tr, bl, br;
1894 tr = ds->tiles[y*(w+2)+x];
1895 tl = (x == 0 ? 0 : ds->tiles[y*(w+2)+(x-1)]);
1896 br = (y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+x]);
1897 bl = (x == 0 || y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+(x-1)]);
1899 if (ds->drawn[i*4] != tl || ds->drawn[i*4+1] != tr ||
1900 ds->drawn[i*4+2] != bl || ds->drawn[i*4+3] != br) {
1901 clip(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE);
1903 draw_tile(dr, ds, state->clues, x-1, y-1, tr);
1905 draw_tile(dr, ds, state->clues, x-2, y-1, tl);
1907 draw_tile(dr, ds, state->clues, x-1, y, br);
1908 if (x > 0 && y <= w)
1909 draw_tile(dr, ds, state->clues, x-2, y, bl);
1912 draw_update(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE);
1914 ds->drawn[i*4] = tl;
1915 ds->drawn[i*4+1] = tr;
1916 ds->drawn[i*4+2] = bl;
1917 ds->drawn[i*4+3] = br;
1923 static float game_anim_length(const game_state *oldstate,
1924 const game_state *newstate, int dir, game_ui *ui)
1929 static float game_flash_length(const game_state *oldstate,
1930 const game_state *newstate, int dir, game_ui *ui)
1932 if (!oldstate->completed && newstate->completed &&
1933 !oldstate->cheated && !newstate->cheated)
1938 static void game_get_cursor_location(const game_ui *ui,
1939 const game_drawstate *ds,
1940 const game_state *state,
1941 const game_params *params,
1942 int *x, int *y, int *w, int *h)
1951 static int game_status(const game_state *state)
1953 return state->completed ? +1 : 0;
1956 static bool game_timing_state(const game_state *state, game_ui *ui)
1958 if (state->completed)
1963 static void game_print_size(const game_params *params, float *x, float *y)
1968 * We use 9mm squares by default, like Solo.
1970 game_compute_size(params, 900, &pw, &ph);
1975 static void game_print(drawing *dr, const game_state *state, int tilesize)
1977 int w = state->par.w;
1978 int ink = print_mono_colour(dr, 0);
1981 /* Ick: fake up `ds->tilesize' for macro expansion purposes */
1982 game_drawstate ads, *ds = &ads;
1983 game_set_size(dr, ds, NULL, tilesize);
1988 print_line_width(dr, 3 * TILESIZE / 40);
1989 draw_rect_outline(dr, BORDER, BORDER, w*TILESIZE, w*TILESIZE, ink);
1994 for (x = 1; x < w; x++) {
1995 print_line_width(dr, TILESIZE / 40);
1996 draw_line(dr, BORDER+x*TILESIZE, BORDER,
1997 BORDER+x*TILESIZE, BORDER+w*TILESIZE, ink);
1999 for (y = 1; y < w; y++) {
2000 print_line_width(dr, TILESIZE / 40);
2001 draw_line(dr, BORDER, BORDER+y*TILESIZE,
2002 BORDER+w*TILESIZE, BORDER+y*TILESIZE, ink);
2008 for (i = 0; i < 4*w; i++) {
2011 if (!state->clues->clues[i])
2014 CLUEPOS(x, y, i, w);
2016 sprintf (str, "%d", state->clues->clues[i]);
2018 draw_text(dr, BORDER + x*TILESIZE + TILESIZE/2,
2019 BORDER + y*TILESIZE + TILESIZE/2,
2020 FONT_VARIABLE, TILESIZE/2,
2021 ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
2025 * Numbers for the solution, if any.
2027 for (y = 0; y < w; y++)
2028 for (x = 0; x < w; x++)
2029 if (state->grid[y*w+x]) {
2032 str[0] = state->grid[y*w+x] + '0';
2033 draw_text(dr, BORDER + x*TILESIZE + TILESIZE/2,
2034 BORDER + y*TILESIZE + TILESIZE/2,
2035 FONT_VARIABLE, TILESIZE/2,
2036 ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
2041 #define thegame towers
2044 const struct game thegame = {
2045 "Towers", "games.towers", "towers",
2047 game_fetch_preset, NULL,
2052 true, game_configure, custom_params,
2060 true, game_can_format_as_text_now, game_text_format,
2069 PREFERRED_TILESIZE, game_compute_size, game_set_size,
2072 game_free_drawstate,
2076 game_get_cursor_location,
2078 true, false, game_print_size, game_print,
2079 false, /* wants_statusbar */
2080 false, game_timing_state,
2081 REQUIRE_RBUTTON | REQUIRE_NUMPAD, /* flags */
2084 #ifdef STANDALONE_SOLVER
2088 int main(int argc, char **argv)
2092 char *id = NULL, *desc;
2096 bool really_show_working = false;
2098 while (--argc > 0) {
2100 if (!strcmp(p, "-v")) {
2101 really_show_working = true;
2102 } else if (!strcmp(p, "-g")) {
2104 } else if (*p == '-') {
2105 fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
2113 fprintf(stderr, "usage: %s [-g | -v] <game_id>\n", argv[0]);
2117 desc = strchr(id, ':');
2119 fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
2124 p = default_params();
2125 decode_params(p, id);
2126 err = validate_desc(p, desc);
2128 fprintf(stderr, "%s: %s\n", argv[0], err);
2131 s = new_game(NULL, p, desc);
2134 * When solving an Easy puzzle, we don't want to bother the
2135 * user with Hard-level deductions. For this reason, we grade
2136 * the puzzle internally before doing anything else.
2138 ret = -1; /* placate optimiser */
2139 solver_show_working = 0;
2140 for (diff = 0; diff < DIFFCOUNT; diff++) {
2141 memcpy(s->grid, s->clues->immutable, p->w * p->w);
2142 ret = solver(p->w, s->clues->clues, s->grid, diff);
2147 if (really_show_working) {
2149 * Now run the solver again at the last difficulty level we
2150 * tried, but this time with diagnostics enabled.
2152 solver_show_working = really_show_working;
2153 memcpy(s->grid, s->clues->immutable, p->w * p->w);
2154 ret = solver(p->w, s->clues->clues, s->grid,
2155 diff < DIFFCOUNT ? diff : DIFFCOUNT-1);
2158 if (diff == DIFFCOUNT) {
2160 printf("Difficulty rating: ambiguous\n");
2162 printf("Unable to find a unique solution\n");
2165 if (ret == diff_impossible)
2166 printf("Difficulty rating: impossible (no solution exists)\n");
2168 printf("Difficulty rating: %s\n", towers_diffnames[ret]);
2171 printf("Puzzle is inconsistent\n");
2173 fputs(game_text_format(s), stdout);
2182 /* vim: set shiftwidth=4 tabstop=8: */