towers.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235
  1. /*
  2. * towers.c: the puzzle also known as 'Skyscrapers'.
  3. *
  4. * Possible future work:
  5. *
  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
  10. * word to live in
  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.
  19. */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <assert.h>
  24. #include <ctype.h>
  25. #ifdef NO_TGMATH_H
  26. # include <math.h>
  27. #else
  28. # include <tgmath.h>
  29. #endif
  30. #include "puzzles.h"
  31. #include "latin.h"
  32. /*
  33. * Difficulty levels. I do some macro ickery here to ensure that my
  34. * enum and the various forms of my name list always match up.
  35. */
  36. #define DIFFLIST(A) \
  37. A(EASY,Easy,solver_easy,e) \
  38. A(HARD,Hard,solver_hard,h) \
  39. A(EXTREME,Extreme,NULL,x) \
  40. A(UNREASONABLE,Unreasonable,NULL,u)
  41. #define ENUM(upper,title,func,lower) DIFF_ ## upper,
  42. #define TITLE(upper,title,func,lower) #title,
  43. #define ENCODE(upper,title,func,lower) #lower
  44. #define CONFIG(upper,title,func,lower) ":" #title
  45. enum { DIFFLIST(ENUM) DIFFCOUNT };
  46. static char const *const towers_diffnames[] = { DIFFLIST(TITLE) };
  47. static char const towers_diffchars[] = DIFFLIST(ENCODE);
  48. #define DIFFCONFIG DIFFLIST(CONFIG)
  49. enum {
  50. COL_BACKGROUND,
  51. COL_GRID,
  52. COL_USER,
  53. COL_HIGHLIGHT,
  54. COL_ERROR,
  55. COL_PENCIL,
  56. COL_DONE,
  57. NCOLOURS
  58. };
  59. struct game_params {
  60. int w, diff;
  61. };
  62. struct clues {
  63. int refcount;
  64. int w;
  65. /*
  66. * An array of 4w integers, of which:
  67. * - the first w run across the top
  68. * - the next w across the bottom
  69. * - the third w down the left
  70. * - the last w down the right.
  71. */
  72. int *clues;
  73. /*
  74. * An array of w*w digits.
  75. */
  76. digit *immutable;
  77. };
  78. /*
  79. * Macros to compute clue indices and coordinates.
  80. */
  81. #define STARTSTEP(start, step, index, w) do { \
  82. if (index < w) \
  83. start = index, step = w; \
  84. else if (index < 2*w) \
  85. start = (w-1)*w+(index-w), step = -w; \
  86. else if (index < 3*w) \
  87. start = w*(index-2*w), step = 1; \
  88. else \
  89. start = w*(index-3*w)+(w-1), step = -1; \
  90. } while (0)
  91. #define CSTARTSTEP(start, step, index, w) \
  92. STARTSTEP(start, step, (((index)+2*w)%(4*w)), w)
  93. #define CLUEPOS(x, y, index, w) do { \
  94. if (index < w) \
  95. x = index, y = -1; \
  96. else if (index < 2*w) \
  97. x = index-w, y = w; \
  98. else if (index < 3*w) \
  99. x = -1, y = index-2*w; \
  100. else \
  101. x = w, y = index-3*w; \
  102. } while (0)
  103. #ifdef STANDALONE_SOLVER
  104. static const char *const cluepos[] = {
  105. "above column", "below column", "left of row", "right of row"
  106. };
  107. #endif
  108. struct game_state {
  109. game_params par;
  110. struct clues *clues;
  111. bool *clues_done;
  112. digit *grid;
  113. int *pencil; /* bitmaps using bits 1<<1..1<<n */
  114. bool completed, cheated;
  115. };
  116. static game_params *default_params(void)
  117. {
  118. game_params *ret = snew(game_params);
  119. ret->w = 5;
  120. ret->diff = DIFF_EASY;
  121. return ret;
  122. }
  123. static const struct game_params towers_presets[] = {
  124. { 4, DIFF_EASY },
  125. { 5, DIFF_EASY },
  126. { 5, DIFF_HARD },
  127. { 6, DIFF_EASY },
  128. { 6, DIFF_HARD },
  129. { 6, DIFF_EXTREME },
  130. { 6, DIFF_UNREASONABLE },
  131. };
  132. static bool game_fetch_preset(int i, char **name, game_params **params)
  133. {
  134. game_params *ret;
  135. char buf[80];
  136. if (i < 0 || i >= lenof(towers_presets))
  137. return false;
  138. ret = snew(game_params);
  139. *ret = towers_presets[i]; /* structure copy */
  140. sprintf(buf, "%dx%d %s", ret->w, ret->w, towers_diffnames[ret->diff]);
  141. *name = dupstr(buf);
  142. *params = ret;
  143. return true;
  144. }
  145. static void free_params(game_params *params)
  146. {
  147. sfree(params);
  148. }
  149. static game_params *dup_params(const game_params *params)
  150. {
  151. game_params *ret = snew(game_params);
  152. *ret = *params; /* structure copy */
  153. return ret;
  154. }
  155. static void decode_params(game_params *params, char const *string)
  156. {
  157. char const *p = string;
  158. params->w = atoi(p);
  159. while (*p && isdigit((unsigned char)*p)) p++;
  160. if (*p == 'd') {
  161. int i;
  162. p++;
  163. params->diff = DIFFCOUNT+1; /* ...which is invalid */
  164. if (*p) {
  165. for (i = 0; i < DIFFCOUNT; i++) {
  166. if (*p == towers_diffchars[i])
  167. params->diff = i;
  168. }
  169. p++;
  170. }
  171. }
  172. }
  173. static char *encode_params(const game_params *params, bool full)
  174. {
  175. char ret[80];
  176. sprintf(ret, "%d", params->w);
  177. if (full)
  178. sprintf(ret + strlen(ret), "d%c", towers_diffchars[params->diff]);
  179. return dupstr(ret);
  180. }
  181. static config_item *game_configure(const game_params *params)
  182. {
  183. config_item *ret;
  184. char buf[80];
  185. ret = snewn(3, config_item);
  186. ret[0].name = "Grid size";
  187. ret[0].type = C_STRING;
  188. sprintf(buf, "%d", params->w);
  189. ret[0].u.string.sval = dupstr(buf);
  190. ret[1].name = "Difficulty";
  191. ret[1].type = C_CHOICES;
  192. ret[1].u.choices.choicenames = DIFFCONFIG;
  193. ret[1].u.choices.selected = params->diff;
  194. ret[2].name = NULL;
  195. ret[2].type = C_END;
  196. return ret;
  197. }
  198. static game_params *custom_params(const config_item *cfg)
  199. {
  200. game_params *ret = snew(game_params);
  201. ret->w = atoi(cfg[0].u.string.sval);
  202. ret->diff = cfg[1].u.choices.selected;
  203. return ret;
  204. }
  205. static const char *validate_params(const game_params *params, bool full)
  206. {
  207. if (params->w < 3 || params->w > 9)
  208. return "Grid size must be between 3 and 9";
  209. if (params->diff >= DIFFCOUNT)
  210. return "Unknown difficulty rating";
  211. return NULL;
  212. }
  213. /* ----------------------------------------------------------------------
  214. * Solver.
  215. */
  216. struct solver_ctx {
  217. int w, diff;
  218. bool started;
  219. int *clues;
  220. long *iscratch;
  221. int *dscratch;
  222. };
  223. static int solver_easy(struct latin_solver *solver, void *vctx)
  224. {
  225. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  226. int w = ctx->w;
  227. int c, i, j, n, m, furthest;
  228. int start, step, cstart, cstep, clue, pos, cpos;
  229. int ret = 0;
  230. #ifdef STANDALONE_SOLVER
  231. char prefix[256];
  232. #endif
  233. if (!ctx->started) {
  234. ctx->started = true;
  235. /*
  236. * One-off loop to help get started: when a pair of facing
  237. * clues sum to w+1, it must mean that the row consists of
  238. * two increasing sequences back to back, so we can
  239. * immediately place the highest digit by knowing the
  240. * lengths of those two sequences.
  241. */
  242. for (c = 0; c < 3*w; c = (c == w-1 ? 2*w : c+1)) {
  243. int c2 = c + w;
  244. if (ctx->clues[c] && ctx->clues[c2] &&
  245. ctx->clues[c] + ctx->clues[c2] == w+1) {
  246. STARTSTEP(start, step, c, w);
  247. CSTARTSTEP(cstart, cstep, c, w);
  248. pos = start + (ctx->clues[c]-1)*step;
  249. cpos = cstart + (ctx->clues[c]-1)*cstep;
  250. if (solver->cube[cpos*w+w-1]) {
  251. #ifdef STANDALONE_SOLVER
  252. if (solver_show_working) {
  253. printf("%*sfacing clues on %s %d are maximal:\n",
  254. solver_recurse_depth*4, "",
  255. c>=2*w ? "row" : "column", c % w + 1);
  256. printf("%*s placing %d at (%d,%d)\n",
  257. solver_recurse_depth*4, "",
  258. w, pos%w+1, pos/w+1);
  259. }
  260. #endif
  261. latin_solver_place(solver, pos%w, pos/w, w);
  262. ret = 1;
  263. } else {
  264. ret = -1;
  265. }
  266. }
  267. }
  268. if (ret)
  269. return ret;
  270. }
  271. /*
  272. * Go over every clue doing reasonably simple heuristic
  273. * deductions.
  274. */
  275. for (c = 0; c < 4*w; c++) {
  276. clue = ctx->clues[c];
  277. if (!clue)
  278. continue;
  279. STARTSTEP(start, step, c, w);
  280. CSTARTSTEP(cstart, cstep, c, w);
  281. /* Find the location of each number in the row. */
  282. for (i = 0; i < w; i++)
  283. ctx->dscratch[i] = w;
  284. for (i = 0; i < w; i++)
  285. if (solver->grid[start+i*step])
  286. ctx->dscratch[solver->grid[start+i*step]-1] = i;
  287. n = m = 0;
  288. furthest = w;
  289. for (i = w; i >= 1; i--) {
  290. if (ctx->dscratch[i-1] == w) {
  291. break;
  292. } else if (ctx->dscratch[i-1] < furthest) {
  293. furthest = ctx->dscratch[i-1];
  294. m = i;
  295. n++;
  296. }
  297. }
  298. if (clue == n+1 && furthest > 1) {
  299. #ifdef STANDALONE_SOLVER
  300. if (solver_show_working)
  301. sprintf(prefix, "%*sclue %s %d is nearly filled:\n",
  302. solver_recurse_depth*4, "",
  303. cluepos[c/w], c%w+1);
  304. else
  305. prefix[0] = '\0'; /* placate optimiser */
  306. #endif
  307. /*
  308. * We can already see an increasing sequence of the very
  309. * highest numbers, of length one less than that
  310. * specified in the clue. All of those numbers _must_ be
  311. * part of the clue sequence, so the number right next
  312. * to the clue must be the final one - i.e. it must be
  313. * bigger than any of the numbers between it and m. This
  314. * allows us to rule out small numbers in that square.
  315. *
  316. * (This is a generalisation of the obvious deduction
  317. * that when you see a clue saying 1, it must be right
  318. * next to the largest possible number; and similarly,
  319. * when you see a clue saying 2 opposite that, it must
  320. * be right next to the second-largest.)
  321. */
  322. j = furthest-1; /* number of small numbers we can rule out */
  323. for (i = 1; i <= w && j > 0; i++) {
  324. if (ctx->dscratch[i-1] < w && ctx->dscratch[i-1] >= furthest)
  325. continue; /* skip this number, it's elsewhere */
  326. j--;
  327. if (solver->cube[cstart*w+i-1]) {
  328. #ifdef STANDALONE_SOLVER
  329. if (solver_show_working) {
  330. printf("%s%*s ruling out %d at (%d,%d)\n",
  331. prefix, solver_recurse_depth*4, "",
  332. i, start%w+1, start/w+1);
  333. prefix[0] = '\0';
  334. }
  335. #endif
  336. solver->cube[cstart*w+i-1] = 0;
  337. ret = 1;
  338. }
  339. }
  340. }
  341. if (ret)
  342. return ret;
  343. #ifdef STANDALONE_SOLVER
  344. if (solver_show_working)
  345. sprintf(prefix, "%*slower bounds for clue %s %d:\n",
  346. solver_recurse_depth*4, "",
  347. cluepos[c/w], c%w+1);
  348. else
  349. prefix[0] = '\0'; /* placate optimiser */
  350. #endif
  351. i = 0;
  352. for (n = w; n > 0; n--) {
  353. /*
  354. * The largest number cannot occur in the first (clue-1)
  355. * squares of the row, or else there wouldn't be space
  356. * for a sufficiently long increasing sequence which it
  357. * terminated. The second-largest number (not counting
  358. * any that are known to be on the far side of a larger
  359. * number and hence excluded from this sequence) cannot
  360. * occur in the first (clue-2) squares, similarly, and
  361. * so on.
  362. */
  363. if (ctx->dscratch[n-1] < w) {
  364. for (m = n+1; m < w; m++)
  365. if (ctx->dscratch[m] < ctx->dscratch[n-1])
  366. break;
  367. if (m < w)
  368. continue; /* this number doesn't count */
  369. }
  370. for (j = 0; j < clue - i - 1; j++)
  371. if (solver->cube[(cstart + j*cstep)*w+n-1]) {
  372. #ifdef STANDALONE_SOLVER
  373. if (solver_show_working) {
  374. int pos = start+j*step;
  375. printf("%s%*s ruling out %d at (%d,%d)\n",
  376. prefix, solver_recurse_depth*4, "",
  377. n, pos%w+1, pos/w+1);
  378. prefix[0] = '\0';
  379. }
  380. #endif
  381. solver->cube[(cstart + j*cstep)*w+n-1] = 0;
  382. ret = 1;
  383. }
  384. i++;
  385. }
  386. }
  387. if (ret)
  388. return ret;
  389. return 0;
  390. }
  391. static int solver_hard(struct latin_solver *solver, void *vctx)
  392. {
  393. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  394. int w = ctx->w;
  395. int c, i, j, n, best, clue, start, step, ret;
  396. long bitmap;
  397. #ifdef STANDALONE_SOLVER
  398. char prefix[256];
  399. #endif
  400. /*
  401. * Go over every clue analysing all possibilities.
  402. */
  403. for (c = 0; c < 4*w; c++) {
  404. clue = ctx->clues[c];
  405. if (!clue)
  406. continue;
  407. CSTARTSTEP(start, step, c, w);
  408. for (i = 0; i < w; i++)
  409. ctx->iscratch[i] = 0;
  410. /*
  411. * Instead of a tedious physical recursion, I iterate in the
  412. * scratch array through all possibilities. At any given
  413. * moment, i indexes the element of the box that will next
  414. * be incremented.
  415. */
  416. i = 0;
  417. ctx->dscratch[i] = 0;
  418. best = n = 0;
  419. bitmap = 0;
  420. while (1) {
  421. if (i < w) {
  422. /*
  423. * Find the next valid value for cell i.
  424. */
  425. int limit = (n == clue ? best : w);
  426. int pos = start + step * i;
  427. for (j = ctx->dscratch[i] + 1; j <= limit; j++) {
  428. if (bitmap & (1L << j))
  429. continue; /* used this one already */
  430. if (!solver->cube[pos*w+j-1])
  431. continue; /* ruled out already */
  432. /* Found one. */
  433. break;
  434. }
  435. if (j > limit) {
  436. /* No valid values left; drop back. */
  437. i--;
  438. if (i < 0)
  439. break; /* overall iteration is finished */
  440. bitmap &= ~(1L << ctx->dscratch[i]);
  441. if (ctx->dscratch[i] == best) {
  442. n--;
  443. best = 0;
  444. for (j = 0; j < i; j++)
  445. if (best < ctx->dscratch[j])
  446. best = ctx->dscratch[j];
  447. }
  448. } else {
  449. /* Got a valid value; store it and move on. */
  450. bitmap |= 1L << j;
  451. ctx->dscratch[i++] = j;
  452. if (j > best) {
  453. best = j;
  454. n++;
  455. }
  456. ctx->dscratch[i] = 0;
  457. }
  458. } else {
  459. if (n == clue) {
  460. for (j = 0; j < w; j++)
  461. ctx->iscratch[j] |= 1L << ctx->dscratch[j];
  462. }
  463. i--;
  464. bitmap &= ~(1L << ctx->dscratch[i]);
  465. if (ctx->dscratch[i] == best) {
  466. n--;
  467. best = 0;
  468. for (j = 0; j < i; j++)
  469. if (best < ctx->dscratch[j])
  470. best = ctx->dscratch[j];
  471. }
  472. }
  473. }
  474. #ifdef STANDALONE_SOLVER
  475. if (solver_show_working)
  476. sprintf(prefix, "%*sexhaustive analysis of clue %s %d:\n",
  477. solver_recurse_depth*4, "",
  478. cluepos[c/w], c%w+1);
  479. else
  480. prefix[0] = '\0'; /* placate optimiser */
  481. #endif
  482. ret = 0;
  483. for (i = 0; i < w; i++) {
  484. int pos = start + step * i;
  485. for (j = 1; j <= w; j++) {
  486. if (solver->cube[pos*w+j-1] &&
  487. !(ctx->iscratch[i] & (1L << j))) {
  488. #ifdef STANDALONE_SOLVER
  489. if (solver_show_working) {
  490. printf("%s%*s ruling out %d at (%d,%d)\n",
  491. prefix, solver_recurse_depth*4, "",
  492. j, pos/w+1, pos%w+1);
  493. prefix[0] = '\0';
  494. }
  495. #endif
  496. solver->cube[pos*w+j-1] = 0;
  497. ret = 1;
  498. }
  499. }
  500. /*
  501. * Once we find one clue we can do something with in
  502. * this way, revert to trying easier deductions, so as
  503. * not to generate solver diagnostics that make the
  504. * problem look harder than it is.
  505. */
  506. if (ret)
  507. return ret;
  508. }
  509. }
  510. return 0;
  511. }
  512. #define SOLVER(upper,title,func,lower) func,
  513. static usersolver_t const towers_solvers[] = { DIFFLIST(SOLVER) };
  514. static bool towers_valid(struct latin_solver *solver, void *vctx)
  515. {
  516. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  517. int w = ctx->w;
  518. int c, i, n, best, clue, start, step;
  519. for (c = 0; c < 4*w; c++) {
  520. clue = ctx->clues[c];
  521. if (!clue)
  522. continue;
  523. STARTSTEP(start, step, c, w);
  524. n = best = 0;
  525. for (i = 0; i < w; i++) {
  526. if (solver->grid[start+i*step] > best) {
  527. best = solver->grid[start+i*step];
  528. n++;
  529. }
  530. }
  531. if (n != clue) {
  532. #ifdef STANDALONE_SOLVER
  533. if (solver_show_working)
  534. printf("%*sclue %s %d is violated\n",
  535. solver_recurse_depth*4, "",
  536. cluepos[c/w], c%w+1);
  537. #endif
  538. return false;
  539. }
  540. }
  541. return true;
  542. }
  543. static int solver(int w, int *clues, digit *soln, int maxdiff)
  544. {
  545. int ret;
  546. struct solver_ctx ctx;
  547. ctx.w = w;
  548. ctx.diff = maxdiff;
  549. ctx.clues = clues;
  550. ctx.started = false;
  551. ctx.iscratch = snewn(w, long);
  552. ctx.dscratch = snewn(w+1, int);
  553. ret = latin_solver(soln, w, maxdiff,
  554. DIFF_EASY, DIFF_HARD, DIFF_EXTREME,
  555. DIFF_EXTREME, DIFF_UNREASONABLE,
  556. towers_solvers, towers_valid, &ctx, NULL, NULL);
  557. sfree(ctx.iscratch);
  558. sfree(ctx.dscratch);
  559. return ret;
  560. }
  561. /* ----------------------------------------------------------------------
  562. * Grid generation.
  563. */
  564. static char *new_game_desc(const game_params *params, random_state *rs,
  565. char **aux, bool interactive)
  566. {
  567. int w = params->w, a = w*w;
  568. digit *grid, *soln, *soln2;
  569. int *clues, *order;
  570. int i, ret;
  571. int diff = params->diff;
  572. char *desc, *p;
  573. /*
  574. * Difficulty exceptions: some combinations of size and
  575. * difficulty cannot be satisfied, because all puzzles of at
  576. * most that difficulty are actually even easier.
  577. *
  578. * Remember to re-test this whenever a change is made to the
  579. * solver logic!
  580. *
  581. * I tested it using the following shell command:
  582. for d in e h x u; do
  583. for i in {3..9}; do
  584. echo -n "./towers --generate 1 ${i}d${d}: "
  585. perl -e 'alarm 30; exec @ARGV' ./towers --generate 1 ${i}d${d} >/dev/null \
  586. && echo ok
  587. done
  588. done
  589. * Of course, it's better to do that after taking the exceptions
  590. * _out_, so as to detect exceptions that should be removed as
  591. * well as those which should be added.
  592. */
  593. if (diff > DIFF_HARD && w <= 3)
  594. diff = DIFF_HARD;
  595. grid = NULL;
  596. clues = snewn(4*w, int);
  597. soln = snewn(a, digit);
  598. soln2 = snewn(a, digit);
  599. order = snewn(max(4*w,a), int);
  600. while (1) {
  601. /*
  602. * Construct a latin square to be the solution.
  603. */
  604. sfree(grid);
  605. grid = latin_generate(w, rs);
  606. /*
  607. * Fill in the clues.
  608. */
  609. for (i = 0; i < 4*w; i++) {
  610. int start, step, j, k, best;
  611. STARTSTEP(start, step, i, w);
  612. k = best = 0;
  613. for (j = 0; j < w; j++) {
  614. if (grid[start+j*step] > best) {
  615. best = grid[start+j*step];
  616. k++;
  617. }
  618. }
  619. clues[i] = k;
  620. }
  621. /*
  622. * Remove the grid numbers and then the clues, one by one,
  623. * for as long as the game remains soluble at the given
  624. * difficulty.
  625. */
  626. memcpy(soln, grid, a);
  627. if (diff == DIFF_EASY && w <= 5) {
  628. /*
  629. * Special case: for Easy-mode grids that are small
  630. * enough, it's nice to be able to find completely empty
  631. * grids.
  632. */
  633. memset(soln2, 0, a);
  634. ret = solver(w, clues, soln2, diff);
  635. if (ret > diff)
  636. continue;
  637. }
  638. for (i = 0; i < a; i++)
  639. order[i] = i;
  640. shuffle(order, a, sizeof(*order), rs);
  641. for (i = 0; i < a; i++) {
  642. int j = order[i];
  643. memcpy(soln2, grid, a);
  644. soln2[j] = 0;
  645. ret = solver(w, clues, soln2, diff);
  646. if (ret <= diff)
  647. grid[j] = 0;
  648. }
  649. if (diff > DIFF_EASY) { /* leave all clues on Easy mode */
  650. for (i = 0; i < 4*w; i++)
  651. order[i] = i;
  652. shuffle(order, 4*w, sizeof(*order), rs);
  653. for (i = 0; i < 4*w; i++) {
  654. int j = order[i];
  655. int clue = clues[j];
  656. memcpy(soln2, grid, a);
  657. clues[j] = 0;
  658. ret = solver(w, clues, soln2, diff);
  659. if (ret > diff)
  660. clues[j] = clue;
  661. }
  662. }
  663. /*
  664. * See if the game can be solved at the specified difficulty
  665. * level, but not at the one below.
  666. */
  667. memcpy(soln2, grid, a);
  668. ret = solver(w, clues, soln2, diff);
  669. if (ret != diff)
  670. continue; /* go round again */
  671. /*
  672. * We've got a usable puzzle!
  673. */
  674. break;
  675. }
  676. /*
  677. * Encode the puzzle description.
  678. */
  679. desc = snewn(40*a, char);
  680. p = desc;
  681. for (i = 0; i < 4*w; i++) {
  682. if (i)
  683. *p++ = '/';
  684. if (clues[i])
  685. p += sprintf(p, "%d", clues[i]);
  686. }
  687. for (i = 0; i < a; i++)
  688. if (grid[i])
  689. break;
  690. if (i < a) {
  691. int run = 0;
  692. *p++ = ',';
  693. for (i = 0; i <= a; i++) {
  694. int n = (i < a ? grid[i] : -1);
  695. if (!n)
  696. run++;
  697. else {
  698. if (run) {
  699. while (run > 0) {
  700. int thisrun = min(run, 26);
  701. *p++ = thisrun - 1 + 'a';
  702. run -= thisrun;
  703. }
  704. } else {
  705. /*
  706. * If there's a number in the very top left or
  707. * bottom right, there's no point putting an
  708. * unnecessary _ before or after it.
  709. */
  710. if (i > 0 && n > 0)
  711. *p++ = '_';
  712. }
  713. if (n > 0)
  714. p += sprintf(p, "%d", n);
  715. run = 0;
  716. }
  717. }
  718. }
  719. *p++ = '\0';
  720. desc = sresize(desc, p - desc, char);
  721. /*
  722. * Encode the solution.
  723. */
  724. *aux = snewn(a+2, char);
  725. (*aux)[0] = 'S';
  726. for (i = 0; i < a; i++)
  727. (*aux)[i+1] = '0' + soln[i];
  728. (*aux)[a+1] = '\0';
  729. sfree(grid);
  730. sfree(clues);
  731. sfree(soln);
  732. sfree(soln2);
  733. sfree(order);
  734. return desc;
  735. }
  736. /* ----------------------------------------------------------------------
  737. * Gameplay.
  738. */
  739. static const char *validate_desc(const game_params *params, const char *desc)
  740. {
  741. int w = params->w, a = w*w;
  742. const char *p = desc;
  743. int i, clue;
  744. /*
  745. * Verify that the right number of clues are given, and that
  746. * they're in range.
  747. */
  748. for (i = 0; i < 4*w; i++) {
  749. if (!*p)
  750. return "Too few clues for grid size";
  751. if (i > 0) {
  752. if (*p != '/')
  753. return "Expected commas between clues";
  754. p++;
  755. }
  756. if (isdigit((unsigned char)*p)) {
  757. clue = atoi(p);
  758. while (*p && isdigit((unsigned char)*p)) p++;
  759. if (clue <= 0 || clue > w)
  760. return "Clue number out of range";
  761. }
  762. }
  763. if (*p == '/')
  764. return "Too many clues for grid size";
  765. if (*p == ',') {
  766. /*
  767. * Verify that the right amount of grid data is given, and
  768. * that any grid elements provided are in range.
  769. */
  770. int squares = 0;
  771. p++;
  772. while (*p) {
  773. int c = *p++;
  774. if (c >= 'a' && c <= 'z') {
  775. squares += c - 'a' + 1;
  776. } else if (c == '_') {
  777. /* do nothing */;
  778. } else if (c > '0' && c <= '9') {
  779. int val = atoi(p-1);
  780. if (val < 1 || val > w)
  781. return "Out-of-range number in grid description";
  782. squares++;
  783. while (*p && isdigit((unsigned char)*p)) p++;
  784. } else
  785. return "Invalid character in game description";
  786. }
  787. if (squares < a)
  788. return "Not enough data to fill grid";
  789. if (squares > a)
  790. return "Too much data to fit in grid";
  791. }
  792. if (*p) return "Rubbish at end of game description";
  793. return NULL;
  794. }
  795. static key_label *game_request_keys(const game_params *params, int *nkeys)
  796. {
  797. int i;
  798. int w = params->w;
  799. key_label *keys = snewn(w+1, key_label);
  800. *nkeys = w + 1;
  801. for (i = 0; i < w; i++) {
  802. if (i<9) keys[i].button = '1' + i;
  803. else keys[i].button = 'a' + i - 9;
  804. keys[i].label = NULL;
  805. }
  806. keys[w].button = '\b';
  807. keys[w].label = NULL;
  808. return keys;
  809. }
  810. static game_state *new_game(midend *me, const game_params *params,
  811. const char *desc)
  812. {
  813. int w = params->w, a = w*w;
  814. game_state *state = snew(game_state);
  815. const char *p = desc;
  816. int i;
  817. state->par = *params; /* structure copy */
  818. state->clues = snew(struct clues);
  819. state->clues->refcount = 1;
  820. state->clues->w = w;
  821. state->clues->clues = snewn(4*w, int);
  822. state->clues->immutable = snewn(a, digit);
  823. state->grid = snewn(a, digit);
  824. state->clues_done = snewn(4*w, bool);
  825. state->pencil = snewn(a, int);
  826. for (i = 0; i < a; i++) {
  827. state->grid[i] = 0;
  828. state->pencil[i] = 0;
  829. }
  830. memset(state->clues->immutable, 0, a);
  831. memset(state->clues_done, 0, 4*w*sizeof(bool));
  832. for (i = 0; i < 4*w; i++) {
  833. if (i > 0) {
  834. assert(*p == '/');
  835. p++;
  836. }
  837. if (*p && isdigit((unsigned char)*p)) {
  838. state->clues->clues[i] = atoi(p);
  839. while (*p && isdigit((unsigned char)*p)) p++;
  840. } else
  841. state->clues->clues[i] = 0;
  842. }
  843. if (*p == ',') {
  844. int pos = 0;
  845. p++;
  846. while (*p) {
  847. int c = *p++;
  848. if (c >= 'a' && c <= 'z') {
  849. pos += c - 'a' + 1;
  850. } else if (c == '_') {
  851. /* do nothing */;
  852. } else if (c > '0' && c <= '9') {
  853. int val = atoi(p-1);
  854. assert(val >= 1 && val <= w);
  855. assert(pos < a);
  856. state->grid[pos] = state->clues->immutable[pos] = val;
  857. pos++;
  858. while (*p && isdigit((unsigned char)*p)) p++;
  859. } else
  860. assert(!"Corrupt game description");
  861. }
  862. assert(pos == a);
  863. }
  864. assert(!*p);
  865. state->completed = false;
  866. state->cheated = false;
  867. return state;
  868. }
  869. static game_state *dup_game(const game_state *state)
  870. {
  871. int w = state->par.w, a = w*w;
  872. game_state *ret = snew(game_state);
  873. ret->par = state->par; /* structure copy */
  874. ret->clues = state->clues;
  875. ret->clues->refcount++;
  876. ret->grid = snewn(a, digit);
  877. ret->pencil = snewn(a, int);
  878. ret->clues_done = snewn(4*w, bool);
  879. memcpy(ret->grid, state->grid, a*sizeof(digit));
  880. memcpy(ret->pencil, state->pencil, a*sizeof(int));
  881. memcpy(ret->clues_done, state->clues_done, 4*w*sizeof(bool));
  882. ret->completed = state->completed;
  883. ret->cheated = state->cheated;
  884. return ret;
  885. }
  886. static void free_game(game_state *state)
  887. {
  888. sfree(state->grid);
  889. sfree(state->pencil);
  890. sfree(state->clues_done);
  891. if (--state->clues->refcount <= 0) {
  892. sfree(state->clues->immutable);
  893. sfree(state->clues->clues);
  894. sfree(state->clues);
  895. }
  896. sfree(state);
  897. }
  898. static char *solve_game(const game_state *state, const game_state *currstate,
  899. const char *aux, const char **error)
  900. {
  901. int w = state->par.w, a = w*w;
  902. int i, ret;
  903. digit *soln;
  904. char *out;
  905. if (aux)
  906. return dupstr(aux);
  907. soln = snewn(a, digit);
  908. memcpy(soln, state->clues->immutable, a);
  909. ret = solver(w, state->clues->clues, soln, DIFFCOUNT-1);
  910. if (ret == diff_impossible) {
  911. *error = "No solution exists for this puzzle";
  912. out = NULL;
  913. } else if (ret == diff_ambiguous) {
  914. *error = "Multiple solutions exist for this puzzle";
  915. out = NULL;
  916. } else {
  917. out = snewn(a+2, char);
  918. out[0] = 'S';
  919. for (i = 0; i < a; i++)
  920. out[i+1] = '0' + soln[i];
  921. out[a+1] = '\0';
  922. }
  923. sfree(soln);
  924. return out;
  925. }
  926. static bool game_can_format_as_text_now(const game_params *params)
  927. {
  928. return true;
  929. }
  930. static char *game_text_format(const game_state *state)
  931. {
  932. int w = state->par.w /* , a = w*w */;
  933. char *ret;
  934. char *p;
  935. int x, y;
  936. int total;
  937. /*
  938. * We have:
  939. * - a top clue row, consisting of three spaces, then w clue
  940. * digits with spaces between (total 2*w+3 chars including
  941. * newline)
  942. * - a blank line (one newline)
  943. * - w main rows, consisting of a left clue digit, two spaces,
  944. * w grid digits with spaces between, two spaces and a right
  945. * clue digit (total 2*w+6 chars each including newline)
  946. * - a blank line (one newline)
  947. * - a bottom clue row (same as top clue row)
  948. * - terminating NUL.
  949. *
  950. * Total size is therefore 2*(2*w+3) + 2 + w*(2*w+6) + 1
  951. * = 2w^2+10w+9.
  952. */
  953. total = 2*w*w + 10*w + 9;
  954. ret = snewn(total, char);
  955. p = ret;
  956. /* Top clue row. */
  957. *p++ = ' '; *p++ = ' ';
  958. for (x = 0; x < w; x++) {
  959. *p++ = ' ';
  960. *p++ = (state->clues->clues[x] ? '0' + state->clues->clues[x] : ' ');
  961. }
  962. *p++ = '\n';
  963. /* Blank line. */
  964. *p++ = '\n';
  965. /* Main grid. */
  966. for (y = 0; y < w; y++) {
  967. *p++ = (state->clues->clues[y+2*w] ? '0' + state->clues->clues[y+2*w] :
  968. ' ');
  969. *p++ = ' ';
  970. for (x = 0; x < w; x++) {
  971. *p++ = ' ';
  972. *p++ = (state->grid[y*w+x] ? '0' + state->grid[y*w+x] : ' ');
  973. }
  974. *p++ = ' '; *p++ = ' ';
  975. *p++ = (state->clues->clues[y+3*w] ? '0' + state->clues->clues[y+3*w] :
  976. ' ');
  977. *p++ = '\n';
  978. }
  979. /* Blank line. */
  980. *p++ = '\n';
  981. /* Bottom clue row. */
  982. *p++ = ' '; *p++ = ' ';
  983. for (x = 0; x < w; x++) {
  984. *p++ = ' ';
  985. *p++ = (state->clues->clues[x+w] ? '0' + state->clues->clues[x+w] :
  986. ' ');
  987. }
  988. *p++ = '\n';
  989. *p++ = '\0';
  990. assert(p == ret + total);
  991. return ret;
  992. }
  993. struct game_ui {
  994. /*
  995. * These are the coordinates of the currently highlighted
  996. * square on the grid, if hshow = 1.
  997. */
  998. int hx, hy;
  999. /*
  1000. * This indicates whether the current highlight is a
  1001. * pencil-mark one or a real one.
  1002. */
  1003. bool hpencil;
  1004. /*
  1005. * This indicates whether or not we're showing the highlight
  1006. * (used to be hx = hy = -1); important so that when we're
  1007. * using the cursor keys it doesn't keep coming back at a
  1008. * fixed position. When hshow = 1, pressing a valid number
  1009. * or letter key or Space will enter that number or letter in the grid.
  1010. */
  1011. bool hshow;
  1012. /*
  1013. * This indicates whether we're using the highlight as a cursor;
  1014. * it means that it doesn't vanish on a keypress, and that it is
  1015. * allowed on immutable squares.
  1016. */
  1017. bool hcursor;
  1018. /*
  1019. * User preference option which can be set to FALSE to disable the
  1020. * 3D graphical style, and instead just display the puzzle as if
  1021. * it was a Sudoku variant, i.e. each square just has a digit in
  1022. * it.
  1023. *
  1024. * I was initially a bit uncertain about whether the 3D style
  1025. * would be the right thing, on the basis that it uses up space in
  1026. * the cells and makes it hard to use many pencil marks. Actually
  1027. * nobody seems to have complained, but having put in the option
  1028. * while I was still being uncertain, it seems silly not to leave
  1029. * it in just in case.
  1030. */
  1031. int three_d;
  1032. };
  1033. static void legacy_prefs_override(struct game_ui *ui_out)
  1034. {
  1035. static bool initialised = false;
  1036. static int three_d = -1;
  1037. if (!initialised) {
  1038. initialised = true;
  1039. three_d = getenv_bool("TOWERS_2D", -1);
  1040. }
  1041. if (three_d != -1)
  1042. ui_out->three_d = three_d;
  1043. }
  1044. static game_ui *new_ui(const game_state *state)
  1045. {
  1046. game_ui *ui = snew(game_ui);
  1047. ui->hx = ui->hy = 0;
  1048. ui->hpencil = false;
  1049. ui->hshow = ui->hcursor = getenv_bool("PUZZLES_SHOW_CURSOR", false);
  1050. ui->three_d = true;
  1051. legacy_prefs_override(ui);
  1052. return ui;
  1053. }
  1054. static void free_ui(game_ui *ui)
  1055. {
  1056. sfree(ui);
  1057. }
  1058. static config_item *get_prefs(game_ui *ui)
  1059. {
  1060. config_item *ret;
  1061. ret = snewn(2, config_item);
  1062. ret[0].name = "Puzzle appearance";
  1063. ret[0].kw = "appearance";
  1064. ret[0].type = C_CHOICES;
  1065. ret[0].u.choices.choicenames = ":2D:3D";
  1066. ret[0].u.choices.choicekws = ":2d:3d";
  1067. ret[0].u.choices.selected = ui->three_d;
  1068. ret[1].name = NULL;
  1069. ret[1].type = C_END;
  1070. return ret;
  1071. }
  1072. static void set_prefs(game_ui *ui, const config_item *cfg)
  1073. {
  1074. ui->three_d = cfg[0].u.choices.selected;
  1075. }
  1076. static void game_changed_state(game_ui *ui, const game_state *oldstate,
  1077. const game_state *newstate)
  1078. {
  1079. int w = newstate->par.w;
  1080. /*
  1081. * We prevent pencil-mode highlighting of a filled square, unless
  1082. * we're using the cursor keys. So if the user has just filled in
  1083. * a square which we had a pencil-mode highlight in (by Undo, or
  1084. * by Redo, or by Solve), then we cancel the highlight.
  1085. */
  1086. if (ui->hshow && ui->hpencil && !ui->hcursor &&
  1087. newstate->grid[ui->hy * w + ui->hx] != 0) {
  1088. ui->hshow = false;
  1089. }
  1090. }
  1091. static const char *current_key_label(const game_ui *ui,
  1092. const game_state *state, int button)
  1093. {
  1094. if (ui->hshow && (button == CURSOR_SELECT))
  1095. return ui->hpencil ? "Ink" : "Pencil";
  1096. return "";
  1097. }
  1098. #define PREFERRED_TILESIZE 48
  1099. #define TILESIZE (ds->tilesize)
  1100. #define BORDER (TILESIZE * 9 / 8)
  1101. #define COORD(x) ((x)*TILESIZE + BORDER)
  1102. #define FROMCOORD(x) (((x)+(TILESIZE-BORDER)) / TILESIZE - 1)
  1103. /* These always return positive values, though y offsets are actually -ve */
  1104. #define X_3D_DISP(height, w) ((height) * TILESIZE / (8 * (w)))
  1105. #define Y_3D_DISP(height, w) ((height) * TILESIZE / (4 * (w)))
  1106. #define FLASH_TIME 0.4F
  1107. #define DF_PENCIL_SHIFT 16
  1108. #define DF_CLUE_DONE 0x10000
  1109. #define DF_ERROR 0x8000
  1110. #define DF_HIGHLIGHT 0x4000
  1111. #define DF_HIGHLIGHT_PENCIL 0x2000
  1112. #define DF_IMMUTABLE 0x1000
  1113. #define DF_PLAYAREA 0x0800
  1114. #define DF_DIGIT_MASK 0x00FF
  1115. struct game_drawstate {
  1116. int tilesize;
  1117. long *tiles; /* (w+2)*(w+2) temp space */
  1118. long *drawn; /* (w+2)*(w+2)*4: current drawn data */
  1119. bool *errtmp;
  1120. };
  1121. static bool check_errors(const game_state *state, bool *errors)
  1122. {
  1123. int w = state->par.w /*, a = w*w */;
  1124. int W = w+2, A = W*W; /* the errors array is (w+2) square */
  1125. int *clues = state->clues->clues;
  1126. digit *grid = state->grid;
  1127. int i, x, y;
  1128. bool errs = false;
  1129. int tmp[32];
  1130. assert(w < lenof(tmp));
  1131. if (errors)
  1132. for (i = 0; i < A; i++)
  1133. errors[i] = false;
  1134. for (y = 0; y < w; y++) {
  1135. unsigned long mask = 0, errmask = 0;
  1136. for (x = 0; x < w; x++) {
  1137. unsigned long bit = 1UL << grid[y*w+x];
  1138. errmask |= (mask & bit);
  1139. mask |= bit;
  1140. }
  1141. if (mask != (1L << (w+1)) - (1L << 1)) {
  1142. errs = true;
  1143. errmask &= ~1UL;
  1144. if (errors) {
  1145. for (x = 0; x < w; x++)
  1146. if (errmask & (1UL << grid[y*w+x]))
  1147. errors[(y+1)*W+(x+1)] = true;
  1148. }
  1149. }
  1150. }
  1151. for (x = 0; x < w; x++) {
  1152. unsigned long mask = 0, errmask = 0;
  1153. for (y = 0; y < w; y++) {
  1154. unsigned long bit = 1UL << grid[y*w+x];
  1155. errmask |= (mask & bit);
  1156. mask |= bit;
  1157. }
  1158. if (mask != (1 << (w+1)) - (1 << 1)) {
  1159. errs = true;
  1160. errmask &= ~1UL;
  1161. if (errors) {
  1162. for (y = 0; y < w; y++)
  1163. if (errmask & (1UL << grid[y*w+x]))
  1164. errors[(y+1)*W+(x+1)] = true;
  1165. }
  1166. }
  1167. }
  1168. for (i = 0; i < 4*w; i++) {
  1169. int start, step, j, n, best;
  1170. STARTSTEP(start, step, i, w);
  1171. if (!clues[i])
  1172. continue;
  1173. best = n = 0;
  1174. for (j = 0; j < w; j++) {
  1175. int number = grid[start+j*step];
  1176. if (!number)
  1177. break; /* can't tell what happens next */
  1178. if (number > best) {
  1179. best = number;
  1180. n++;
  1181. }
  1182. }
  1183. if (n > clues[i] || (best == w && n < clues[i]) ||
  1184. (best < w && n == clues[i])) {
  1185. if (errors) {
  1186. int x, y;
  1187. CLUEPOS(x, y, i, w);
  1188. errors[(y+1)*W+(x+1)] = true;
  1189. }
  1190. errs = true;
  1191. }
  1192. }
  1193. return errs;
  1194. }
  1195. static int clue_index(const game_state *state, int x, int y)
  1196. {
  1197. int w = state->par.w;
  1198. if (x == -1 || x == w)
  1199. return w * (x == -1 ? 2 : 3) + y;
  1200. else if (y == -1 || y == w)
  1201. return (y == -1 ? 0 : w) + x;
  1202. return -1;
  1203. }
  1204. static bool is_clue(const game_state *state, int x, int y)
  1205. {
  1206. int w = state->par.w;
  1207. if (((x == -1 || x == w) && y >= 0 && y < w) ||
  1208. ((y == -1 || y == w) && x >= 0 && x < w))
  1209. {
  1210. if (state->clues->clues[clue_index(state, x, y)] & DF_DIGIT_MASK)
  1211. return true;
  1212. }
  1213. return false;
  1214. }
  1215. static char *interpret_move(const game_state *state, game_ui *ui,
  1216. const game_drawstate *ds,
  1217. int x, int y, int button)
  1218. {
  1219. int w = state->par.w;
  1220. bool shift_or_control = button & (MOD_SHFT | MOD_CTRL);
  1221. int tx, ty;
  1222. char buf[80];
  1223. button &= ~MOD_MASK;
  1224. tx = FROMCOORD(x);
  1225. ty = FROMCOORD(y);
  1226. if (ui->three_d) {
  1227. /*
  1228. * In 3D mode, just locating the mouse click in the natural
  1229. * square grid may not be sufficient to tell which tower the
  1230. * user clicked on. Investigate the _tops_ of the nearby
  1231. * towers to see if a click on one grid square was actually
  1232. * a click on a tower protruding into that region from
  1233. * another.
  1234. */
  1235. int dx, dy;
  1236. for (dy = 0; dy <= 1; dy++)
  1237. for (dx = 0; dx >= -1; dx--) {
  1238. int cx = tx + dx, cy = ty + dy;
  1239. if (cx >= 0 && cx < w && cy >= 0 && cy < w) {
  1240. int height = state->grid[cy*w+cx];
  1241. int bx = COORD(cx), by = COORD(cy);
  1242. int ox = bx + X_3D_DISP(height, w);
  1243. int oy = by - Y_3D_DISP(height, w);
  1244. if (/* on top face? */
  1245. (x - ox >= 0 && x - ox < TILESIZE &&
  1246. y - oy >= 0 && y - oy < TILESIZE) ||
  1247. /* in triangle between top-left corners? */
  1248. (ox > bx && x >= bx && x <= ox && y <= by &&
  1249. (by-y) * (ox-bx) <= (by-oy) * (x-bx)) ||
  1250. /* in triangle between bottom-right corners? */
  1251. (ox > bx && x >= bx+TILESIZE && x <= ox+TILESIZE &&
  1252. y >= oy+TILESIZE &&
  1253. (by-y+TILESIZE)*(ox-bx) >= (by-oy)*(x-bx-TILESIZE))) {
  1254. tx = cx;
  1255. ty = cy;
  1256. }
  1257. }
  1258. }
  1259. }
  1260. if (tx >= 0 && tx < w && ty >= 0 && ty < w) {
  1261. if (button == LEFT_BUTTON) {
  1262. if (tx == ui->hx && ty == ui->hy &&
  1263. ui->hshow && !ui->hpencil) {
  1264. ui->hshow = false;
  1265. } else {
  1266. ui->hx = tx;
  1267. ui->hy = ty;
  1268. ui->hshow = !state->clues->immutable[ty*w+tx];
  1269. ui->hpencil = false;
  1270. }
  1271. ui->hcursor = false;
  1272. return MOVE_UI_UPDATE;
  1273. }
  1274. if (button == RIGHT_BUTTON) {
  1275. /*
  1276. * Pencil-mode highlighting for non filled squares.
  1277. */
  1278. if (state->grid[ty*w+tx] == 0) {
  1279. if (tx == ui->hx && ty == ui->hy &&
  1280. ui->hshow && ui->hpencil) {
  1281. ui->hshow = false;
  1282. } else {
  1283. ui->hpencil = true;
  1284. ui->hx = tx;
  1285. ui->hy = ty;
  1286. ui->hshow = true;
  1287. }
  1288. } else {
  1289. ui->hshow = false;
  1290. }
  1291. ui->hcursor = false;
  1292. return MOVE_UI_UPDATE;
  1293. }
  1294. } else if (button == LEFT_BUTTON) {
  1295. if (is_clue(state, tx, ty)) {
  1296. sprintf(buf, "%c%d,%d", 'D', tx, ty);
  1297. return dupstr(buf);
  1298. }
  1299. }
  1300. if (IS_CURSOR_MOVE(button)) {
  1301. if (shift_or_control) {
  1302. int x = ui->hx, y = ui->hy;
  1303. switch (button) {
  1304. case CURSOR_LEFT: x = -1; break;
  1305. case CURSOR_RIGHT: x = w; break;
  1306. case CURSOR_UP: y = -1; break;
  1307. case CURSOR_DOWN: y = w; break;
  1308. }
  1309. if (is_clue(state, x, y)) {
  1310. sprintf(buf, "%c%d,%d", 'D', x, y);
  1311. return dupstr(buf);
  1312. }
  1313. return NULL;
  1314. }
  1315. move_cursor(button, &ui->hx, &ui->hy, w, w, false);
  1316. ui->hshow = true;
  1317. ui->hcursor = true;
  1318. return MOVE_UI_UPDATE;
  1319. }
  1320. if (ui->hshow &&
  1321. (button == CURSOR_SELECT)) {
  1322. ui->hpencil = !ui->hpencil;
  1323. ui->hcursor = true;
  1324. return MOVE_UI_UPDATE;
  1325. }
  1326. if (ui->hshow &&
  1327. ((button >= '0' && button <= '9' && button - '0' <= w) ||
  1328. button == CURSOR_SELECT2 || button == '\b')) {
  1329. int n = button - '0';
  1330. if (button == CURSOR_SELECT2 || button == '\b')
  1331. n = 0;
  1332. /*
  1333. * Can't make pencil marks in a filled square. This can only
  1334. * become highlighted if we're using cursor keys.
  1335. */
  1336. if (ui->hpencil && state->grid[ui->hy*w+ui->hx])
  1337. return NULL;
  1338. /*
  1339. * Can't do anything to an immutable square.
  1340. */
  1341. if (state->clues->immutable[ui->hy*w+ui->hx])
  1342. return NULL;
  1343. /*
  1344. * If you ask to fill a square with what it already contains,
  1345. * or blank it when it's already empty, that has no effect...
  1346. */
  1347. if ((!ui->hpencil || n == 0) && state->grid[ui->hy*w+ui->hx] == n &&
  1348. state->pencil[ui->hy*w+ui->hx] == 0) {
  1349. /* ... expect to remove the cursor in mouse mode. */
  1350. if (!ui->hcursor) {
  1351. ui->hshow = false;
  1352. return MOVE_UI_UPDATE;
  1353. }
  1354. return NULL;
  1355. }
  1356. sprintf(buf, "%c%d,%d,%d",
  1357. (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
  1358. if (!ui->hcursor) ui->hshow = false;
  1359. return dupstr(buf);
  1360. }
  1361. if (button == 'M' || button == 'm')
  1362. return dupstr("M");
  1363. return NULL;
  1364. }
  1365. static game_state *execute_move(const game_state *from, const char *move)
  1366. {
  1367. int w = from->par.w, a = w*w;
  1368. game_state *ret = dup_game(from);
  1369. int x, y, i, n;
  1370. if (move[0] == 'S') {
  1371. ret->completed = ret->cheated = true;
  1372. for (i = 0; i < a; i++) {
  1373. if (move[i+1] < '1' || move[i+1] > '0'+w)
  1374. goto badmove;
  1375. ret->grid[i] = move[i+1] - '0';
  1376. ret->pencil[i] = 0;
  1377. }
  1378. if (move[a+1] != '\0')
  1379. goto badmove;
  1380. return ret;
  1381. } else if ((move[0] == 'P' || move[0] == 'R') &&
  1382. sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 &&
  1383. x >= 0 && x < w && y >= 0 && y < w && n >= 0 && n <= w) {
  1384. if (from->clues->immutable[y*w+x])
  1385. goto badmove;
  1386. if (move[0] == 'P' && n > 0) {
  1387. ret->pencil[y*w+x] ^= 1L << n;
  1388. } else {
  1389. ret->grid[y*w+x] = n;
  1390. ret->pencil[y*w+x] = 0;
  1391. if (!ret->completed && !check_errors(ret, NULL))
  1392. ret->completed = true;
  1393. }
  1394. return ret;
  1395. } else if (move[0] == 'M') {
  1396. /*
  1397. * Fill in absolutely all pencil marks everywhere. (I
  1398. * wouldn't use this for actual play, but it's a handy
  1399. * starting point when following through a set of
  1400. * diagnostics output by the standalone solver.)
  1401. */
  1402. for (i = 0; i < a; i++) {
  1403. if (!ret->grid[i])
  1404. ret->pencil[i] = (1L << (w+1)) - (1L << 1);
  1405. }
  1406. return ret;
  1407. } else if (move[0] == 'D' && sscanf(move+1, "%d,%d", &x, &y) == 2 &&
  1408. is_clue(from, x, y)) {
  1409. int index = clue_index(from, x, y);
  1410. ret->clues_done[index] = !ret->clues_done[index];
  1411. return ret;
  1412. }
  1413. badmove:
  1414. /* couldn't parse move string */
  1415. free_game(ret);
  1416. return NULL;
  1417. }
  1418. /* ----------------------------------------------------------------------
  1419. * Drawing routines.
  1420. */
  1421. #define SIZE(w) ((w) * TILESIZE + 2*BORDER)
  1422. static void game_compute_size(const game_params *params, int tilesize,
  1423. const game_ui *ui, int *x, int *y)
  1424. {
  1425. /* Ick: fake up `ds->tilesize' for macro expansion purposes */
  1426. struct { int tilesize; } ads, *ds = &ads;
  1427. ads.tilesize = tilesize;
  1428. *x = *y = SIZE(params->w);
  1429. }
  1430. static void game_set_size(drawing *dr, game_drawstate *ds,
  1431. const game_params *params, int tilesize)
  1432. {
  1433. ds->tilesize = tilesize;
  1434. }
  1435. static float *game_colours(frontend *fe, int *ncolours)
  1436. {
  1437. float *ret = snewn(3 * NCOLOURS, float);
  1438. frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
  1439. ret[COL_GRID * 3 + 0] = 0.0F;
  1440. ret[COL_GRID * 3 + 1] = 0.0F;
  1441. ret[COL_GRID * 3 + 2] = 0.0F;
  1442. ret[COL_USER * 3 + 0] = 0.0F;
  1443. ret[COL_USER * 3 + 1] = 0.6F * ret[COL_BACKGROUND * 3 + 1];
  1444. ret[COL_USER * 3 + 2] = 0.0F;
  1445. ret[COL_HIGHLIGHT * 3 + 0] = 0.78F * ret[COL_BACKGROUND * 3 + 0];
  1446. ret[COL_HIGHLIGHT * 3 + 1] = 0.78F * ret[COL_BACKGROUND * 3 + 1];
  1447. ret[COL_HIGHLIGHT * 3 + 2] = 0.78F * ret[COL_BACKGROUND * 3 + 2];
  1448. ret[COL_ERROR * 3 + 0] = 1.0F;
  1449. ret[COL_ERROR * 3 + 1] = 0.0F;
  1450. ret[COL_ERROR * 3 + 2] = 0.0F;
  1451. ret[COL_PENCIL * 3 + 0] = 0.5F * ret[COL_BACKGROUND * 3 + 0];
  1452. ret[COL_PENCIL * 3 + 1] = 0.5F * ret[COL_BACKGROUND * 3 + 1];
  1453. ret[COL_PENCIL * 3 + 2] = ret[COL_BACKGROUND * 3 + 2];
  1454. ret[COL_DONE * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] / 1.5F;
  1455. ret[COL_DONE * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] / 1.5F;
  1456. ret[COL_DONE * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] / 1.5F;
  1457. *ncolours = NCOLOURS;
  1458. return ret;
  1459. }
  1460. static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
  1461. {
  1462. int w = state->par.w /*, a = w*w */;
  1463. struct game_drawstate *ds = snew(struct game_drawstate);
  1464. int i;
  1465. ds->tilesize = 0;
  1466. ds->tiles = snewn((w+2)*(w+2), long);
  1467. ds->drawn = snewn((w+2)*(w+2)*4, long);
  1468. for (i = 0; i < (w+2)*(w+2)*4; i++)
  1469. ds->drawn[i] = -1;
  1470. ds->errtmp = snewn((w+2)*(w+2), bool);
  1471. return ds;
  1472. }
  1473. static void game_free_drawstate(drawing *dr, game_drawstate *ds)
  1474. {
  1475. sfree(ds->errtmp);
  1476. sfree(ds->tiles);
  1477. sfree(ds->drawn);
  1478. sfree(ds);
  1479. }
  1480. static void draw_tile(drawing *dr, game_drawstate *ds, const game_ui *ui,
  1481. struct clues *clues, int x, int y, long tile)
  1482. {
  1483. int w = clues->w /* , a = w*w */;
  1484. int tx, ty, bg;
  1485. char str[64];
  1486. tx = COORD(x);
  1487. ty = COORD(y);
  1488. bg = (tile & DF_HIGHLIGHT) ? COL_HIGHLIGHT : COL_BACKGROUND;
  1489. /* draw tower */
  1490. if (ui->three_d && (tile & DF_PLAYAREA) && (tile & DF_DIGIT_MASK)) {
  1491. int coords[8];
  1492. int xoff = X_3D_DISP(tile & DF_DIGIT_MASK, w);
  1493. int yoff = Y_3D_DISP(tile & DF_DIGIT_MASK, w);
  1494. /* left face of tower */
  1495. coords[0] = tx;
  1496. coords[1] = ty - 1;
  1497. coords[2] = tx;
  1498. coords[3] = ty + TILESIZE - 1;
  1499. coords[4] = coords[2] + xoff;
  1500. coords[5] = coords[3] - yoff;
  1501. coords[6] = coords[0] + xoff;
  1502. coords[7] = coords[1] - yoff;
  1503. draw_polygon(dr, coords, 4, bg, COL_GRID);
  1504. /* bottom face of tower */
  1505. coords[0] = tx + TILESIZE;
  1506. coords[1] = ty + TILESIZE - 1;
  1507. coords[2] = tx;
  1508. coords[3] = ty + TILESIZE - 1;
  1509. coords[4] = coords[2] + xoff;
  1510. coords[5] = coords[3] - yoff;
  1511. coords[6] = coords[0] + xoff;
  1512. coords[7] = coords[1] - yoff;
  1513. draw_polygon(dr, coords, 4, bg, COL_GRID);
  1514. /* now offset all subsequent drawing to the top of the tower */
  1515. tx += xoff;
  1516. ty -= yoff;
  1517. }
  1518. /* erase background */
  1519. draw_rect(dr, tx, ty, TILESIZE, TILESIZE, bg);
  1520. /* pencil-mode highlight */
  1521. if (tile & DF_HIGHLIGHT_PENCIL) {
  1522. int coords[6];
  1523. coords[0] = tx;
  1524. coords[1] = ty;
  1525. coords[2] = tx+TILESIZE/2;
  1526. coords[3] = ty;
  1527. coords[4] = tx;
  1528. coords[5] = ty+TILESIZE/2;
  1529. draw_polygon(dr, coords, 3, COL_HIGHLIGHT, COL_HIGHLIGHT);
  1530. }
  1531. /* draw box outline */
  1532. if (tile & DF_PLAYAREA) {
  1533. int coords[8];
  1534. coords[0] = tx;
  1535. coords[1] = ty - 1;
  1536. coords[2] = tx + TILESIZE;
  1537. coords[3] = ty - 1;
  1538. coords[4] = tx + TILESIZE;
  1539. coords[5] = ty + TILESIZE - 1;
  1540. coords[6] = tx;
  1541. coords[7] = ty + TILESIZE - 1;
  1542. draw_polygon(dr, coords, 4, -1, COL_GRID);
  1543. }
  1544. /* new number needs drawing? */
  1545. if (tile & DF_DIGIT_MASK) {
  1546. int color;
  1547. str[1] = '\0';
  1548. str[0] = (tile & DF_DIGIT_MASK) + '0';
  1549. if (tile & DF_ERROR)
  1550. color = COL_ERROR;
  1551. else if (tile & DF_CLUE_DONE)
  1552. color = COL_DONE;
  1553. else if (x < 0 || y < 0 || x >= w || y >= w)
  1554. color = COL_GRID;
  1555. else if (tile & DF_IMMUTABLE)
  1556. color = COL_GRID;
  1557. else
  1558. color = COL_USER;
  1559. draw_text(dr, tx + TILESIZE/2, ty + TILESIZE/2, FONT_VARIABLE,
  1560. (tile & DF_PLAYAREA ? TILESIZE/2 : TILESIZE*2/5),
  1561. ALIGN_VCENTRE | ALIGN_HCENTRE, color, str);
  1562. } else {
  1563. int i, j, npencil;
  1564. int pl, pr, pt, pb;
  1565. float bestsize;
  1566. int pw, ph, minph, pbest, fontsize;
  1567. /* Count the pencil marks required. */
  1568. for (i = 1, npencil = 0; i <= w; i++)
  1569. if (tile & (1L << (i + DF_PENCIL_SHIFT)))
  1570. npencil++;
  1571. if (npencil) {
  1572. minph = 2;
  1573. /*
  1574. * Determine the bounding rectangle within which we're going
  1575. * to put the pencil marks.
  1576. */
  1577. /* Start with the whole square, minus space for impinging towers */
  1578. pl = tx + (ui->three_d ? X_3D_DISP(w,w) : 0);
  1579. pr = tx + TILESIZE;
  1580. pt = ty;
  1581. pb = ty + TILESIZE - (ui->three_d ? Y_3D_DISP(w,w) : 0);
  1582. /*
  1583. * We arrange our pencil marks in a grid layout, with
  1584. * the number of rows and columns adjusted to allow the
  1585. * maximum font size.
  1586. *
  1587. * So now we work out what the grid size ought to be.
  1588. */
  1589. bestsize = 0.0;
  1590. pbest = 0;
  1591. /* Minimum */
  1592. for (pw = 3; pw < max(npencil,4); pw++) {
  1593. float fw, fh, fs;
  1594. ph = (npencil + pw - 1) / pw;
  1595. ph = max(ph, minph);
  1596. fw = (pr - pl) / (float)pw;
  1597. fh = (pb - pt) / (float)ph;
  1598. fs = min(fw, fh);
  1599. if (fs > bestsize) {
  1600. bestsize = fs;
  1601. pbest = pw;
  1602. }
  1603. }
  1604. assert(pbest > 0);
  1605. pw = pbest;
  1606. ph = (npencil + pw - 1) / pw;
  1607. ph = max(ph, minph);
  1608. /*
  1609. * Now we've got our grid dimensions, work out the pixel
  1610. * size of a grid element, and round it to the nearest
  1611. * pixel. (We don't want rounding errors to make the
  1612. * grid look uneven at low pixel sizes.)
  1613. */
  1614. fontsize = min((pr - pl) / pw, (pb - pt) / ph);
  1615. /*
  1616. * Centre the resulting figure in the square.
  1617. */
  1618. pl = pl + (pr - pl - fontsize * pw) / 2;
  1619. pt = pt + (pb - pt - fontsize * ph) / 2;
  1620. /*
  1621. * Now actually draw the pencil marks.
  1622. */
  1623. for (i = 1, j = 0; i <= w; i++)
  1624. if (tile & (1L << (i + DF_PENCIL_SHIFT))) {
  1625. int dx = j % pw, dy = j / pw;
  1626. str[1] = '\0';
  1627. str[0] = i + '0';
  1628. draw_text(dr, pl + fontsize * (2*dx+1) / 2,
  1629. pt + fontsize * (2*dy+1) / 2,
  1630. FONT_VARIABLE, fontsize,
  1631. ALIGN_VCENTRE | ALIGN_HCENTRE, COL_PENCIL, str);
  1632. j++;
  1633. }
  1634. }
  1635. }
  1636. }
  1637. static void game_redraw(drawing *dr, game_drawstate *ds,
  1638. const game_state *oldstate, const game_state *state,
  1639. int dir, const game_ui *ui,
  1640. float animtime, float flashtime)
  1641. {
  1642. int w = state->par.w /*, a = w*w */;
  1643. int i, x, y;
  1644. check_errors(state, ds->errtmp);
  1645. /*
  1646. * Work out what data each tile should contain.
  1647. */
  1648. for (i = 0; i < (w+2)*(w+2); i++)
  1649. ds->tiles[i] = 0; /* completely blank square */
  1650. /* The clue squares... */
  1651. for (i = 0; i < 4*w; i++) {
  1652. long tile = state->clues->clues[i];
  1653. CLUEPOS(x, y, i, w);
  1654. if (ds->errtmp[(y+1)*(w+2)+(x+1)])
  1655. tile |= DF_ERROR;
  1656. else if (state->clues_done[i])
  1657. tile |= DF_CLUE_DONE;
  1658. ds->tiles[(y+1)*(w+2)+(x+1)] = tile;
  1659. }
  1660. /* ... and the main grid. */
  1661. for (y = 0; y < w; y++) {
  1662. for (x = 0; x < w; x++) {
  1663. long tile = DF_PLAYAREA;
  1664. if (state->grid[y*w+x])
  1665. tile |= state->grid[y*w+x];
  1666. else
  1667. tile |= (long)state->pencil[y*w+x] << DF_PENCIL_SHIFT;
  1668. if (ui->hshow && ui->hx == x && ui->hy == y)
  1669. tile |= (ui->hpencil ? DF_HIGHLIGHT_PENCIL : DF_HIGHLIGHT);
  1670. if (state->clues->immutable[y*w+x])
  1671. tile |= DF_IMMUTABLE;
  1672. if (flashtime > 0 &&
  1673. (flashtime <= FLASH_TIME/3 ||
  1674. flashtime >= FLASH_TIME*2/3))
  1675. tile |= DF_HIGHLIGHT; /* completion flash */
  1676. if (ds->errtmp[(y+1)*(w+2)+(x+1)])
  1677. tile |= DF_ERROR;
  1678. ds->tiles[(y+1)*(w+2)+(x+1)] = tile;
  1679. }
  1680. }
  1681. /*
  1682. * Now actually draw anything that needs to be changed.
  1683. */
  1684. for (y = 0; y < w+2; y++) {
  1685. for (x = 0; x < w+2; x++) {
  1686. long tl, tr, bl, br;
  1687. int i = y*(w+2)+x;
  1688. tr = ds->tiles[y*(w+2)+x];
  1689. tl = (x == 0 ? 0 : ds->tiles[y*(w+2)+(x-1)]);
  1690. br = (y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+x]);
  1691. bl = (x == 0 || y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+(x-1)]);
  1692. if (ds->drawn[i*4] != tl || ds->drawn[i*4+1] != tr ||
  1693. ds->drawn[i*4+2] != bl || ds->drawn[i*4+3] != br) {
  1694. clip(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE);
  1695. draw_tile(dr, ds, ui, state->clues, x-1, y-1, tr);
  1696. if (x > 0)
  1697. draw_tile(dr, ds, ui, state->clues, x-2, y-1, tl);
  1698. if (y <= w)
  1699. draw_tile(dr, ds, ui, state->clues, x-1, y, br);
  1700. if (x > 0 && y <= w)
  1701. draw_tile(dr, ds, ui, state->clues, x-2, y, bl);
  1702. unclip(dr);
  1703. draw_update(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE);
  1704. ds->drawn[i*4] = tl;
  1705. ds->drawn[i*4+1] = tr;
  1706. ds->drawn[i*4+2] = bl;
  1707. ds->drawn[i*4+3] = br;
  1708. }
  1709. }
  1710. }
  1711. }
  1712. static float game_anim_length(const game_state *oldstate,
  1713. const game_state *newstate, int dir, game_ui *ui)
  1714. {
  1715. return 0.0F;
  1716. }
  1717. static float game_flash_length(const game_state *oldstate,
  1718. const game_state *newstate, int dir, game_ui *ui)
  1719. {
  1720. if (!oldstate->completed && newstate->completed &&
  1721. !oldstate->cheated && !newstate->cheated)
  1722. return FLASH_TIME;
  1723. return 0.0F;
  1724. }
  1725. static void game_get_cursor_location(const game_ui *ui,
  1726. const game_drawstate *ds,
  1727. const game_state *state,
  1728. const game_params *params,
  1729. int *x, int *y, int *w, int *h)
  1730. {
  1731. if(ui->hshow) {
  1732. *x = COORD(ui->hx);
  1733. *y = COORD(ui->hy);
  1734. *w = *h = TILESIZE;
  1735. }
  1736. }
  1737. static int game_status(const game_state *state)
  1738. {
  1739. return state->completed ? +1 : 0;
  1740. }
  1741. static void game_print_size(const game_params *params, const game_ui *ui,
  1742. float *x, float *y)
  1743. {
  1744. int pw, ph;
  1745. /*
  1746. * We use 9mm squares by default, like Solo.
  1747. */
  1748. game_compute_size(params, 900, ui, &pw, &ph);
  1749. *x = pw / 100.0F;
  1750. *y = ph / 100.0F;
  1751. }
  1752. static void game_print(drawing *dr, const game_state *state, const game_ui *ui,
  1753. int tilesize)
  1754. {
  1755. int w = state->par.w;
  1756. int ink = print_mono_colour(dr, 0);
  1757. int i, x, y;
  1758. /* Ick: fake up `ds->tilesize' for macro expansion purposes */
  1759. game_drawstate ads, *ds = &ads;
  1760. game_set_size(dr, ds, NULL, tilesize);
  1761. /*
  1762. * Border.
  1763. */
  1764. print_line_width(dr, 3 * TILESIZE / 40);
  1765. draw_rect_outline(dr, BORDER, BORDER, w*TILESIZE, w*TILESIZE, ink);
  1766. /*
  1767. * Main grid.
  1768. */
  1769. for (x = 1; x < w; x++) {
  1770. print_line_width(dr, TILESIZE / 40);
  1771. draw_line(dr, BORDER+x*TILESIZE, BORDER,
  1772. BORDER+x*TILESIZE, BORDER+w*TILESIZE, ink);
  1773. }
  1774. for (y = 1; y < w; y++) {
  1775. print_line_width(dr, TILESIZE / 40);
  1776. draw_line(dr, BORDER, BORDER+y*TILESIZE,
  1777. BORDER+w*TILESIZE, BORDER+y*TILESIZE, ink);
  1778. }
  1779. /*
  1780. * Clues.
  1781. */
  1782. for (i = 0; i < 4*w; i++) {
  1783. char str[128];
  1784. if (!state->clues->clues[i])
  1785. continue;
  1786. CLUEPOS(x, y, i, w);
  1787. sprintf (str, "%d", state->clues->clues[i]);
  1788. draw_text(dr, BORDER + x*TILESIZE + TILESIZE/2,
  1789. BORDER + y*TILESIZE + TILESIZE/2,
  1790. FONT_VARIABLE, TILESIZE/2,
  1791. ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
  1792. }
  1793. /*
  1794. * Numbers for the solution, if any.
  1795. */
  1796. for (y = 0; y < w; y++)
  1797. for (x = 0; x < w; x++)
  1798. if (state->grid[y*w+x]) {
  1799. char str[2];
  1800. str[1] = '\0';
  1801. str[0] = state->grid[y*w+x] + '0';
  1802. draw_text(dr, BORDER + x*TILESIZE + TILESIZE/2,
  1803. BORDER + y*TILESIZE + TILESIZE/2,
  1804. FONT_VARIABLE, TILESIZE/2,
  1805. ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
  1806. }
  1807. }
  1808. #ifdef COMBINED
  1809. #define thegame towers
  1810. #endif
  1811. const struct game thegame = {
  1812. "Towers", "games.towers", "towers",
  1813. default_params,
  1814. game_fetch_preset, NULL,
  1815. decode_params,
  1816. encode_params,
  1817. free_params,
  1818. dup_params,
  1819. true, game_configure, custom_params,
  1820. validate_params,
  1821. new_game_desc,
  1822. validate_desc,
  1823. new_game,
  1824. dup_game,
  1825. free_game,
  1826. true, solve_game,
  1827. true, game_can_format_as_text_now, game_text_format,
  1828. get_prefs, set_prefs,
  1829. new_ui,
  1830. free_ui,
  1831. NULL, /* encode_ui */
  1832. NULL, /* decode_ui */
  1833. game_request_keys,
  1834. game_changed_state,
  1835. current_key_label,
  1836. interpret_move,
  1837. execute_move,
  1838. PREFERRED_TILESIZE, game_compute_size, game_set_size,
  1839. game_colours,
  1840. game_new_drawstate,
  1841. game_free_drawstate,
  1842. game_redraw,
  1843. game_anim_length,
  1844. game_flash_length,
  1845. game_get_cursor_location,
  1846. game_status,
  1847. true, false, game_print_size, game_print,
  1848. false, /* wants_statusbar */
  1849. false, NULL, /* timing_state */
  1850. REQUIRE_RBUTTON | REQUIRE_NUMPAD, /* flags */
  1851. };
  1852. #ifdef STANDALONE_SOLVER
  1853. #include <stdarg.h>
  1854. int main(int argc, char **argv)
  1855. {
  1856. game_params *p;
  1857. game_state *s;
  1858. char *id = NULL, *desc;
  1859. const char *err;
  1860. bool grade = false;
  1861. int ret, diff;
  1862. bool really_show_working = false;
  1863. while (--argc > 0) {
  1864. char *p = *++argv;
  1865. if (!strcmp(p, "-v")) {
  1866. really_show_working = true;
  1867. } else if (!strcmp(p, "-g")) {
  1868. grade = true;
  1869. } else if (*p == '-') {
  1870. fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
  1871. return 1;
  1872. } else {
  1873. id = p;
  1874. }
  1875. }
  1876. if (!id) {
  1877. fprintf(stderr, "usage: %s [-g | -v] <game_id>\n", argv[0]);
  1878. return 1;
  1879. }
  1880. desc = strchr(id, ':');
  1881. if (!desc) {
  1882. fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
  1883. return 1;
  1884. }
  1885. *desc++ = '\0';
  1886. p = default_params();
  1887. decode_params(p, id);
  1888. err = validate_desc(p, desc);
  1889. if (err) {
  1890. fprintf(stderr, "%s: %s\n", argv[0], err);
  1891. return 1;
  1892. }
  1893. s = new_game(NULL, p, desc);
  1894. /*
  1895. * When solving an Easy puzzle, we don't want to bother the
  1896. * user with Hard-level deductions. For this reason, we grade
  1897. * the puzzle internally before doing anything else.
  1898. */
  1899. ret = -1; /* placate optimiser */
  1900. solver_show_working = 0;
  1901. for (diff = 0; diff < DIFFCOUNT; diff++) {
  1902. memcpy(s->grid, s->clues->immutable, p->w * p->w);
  1903. ret = solver(p->w, s->clues->clues, s->grid, diff);
  1904. if (ret <= diff)
  1905. break;
  1906. }
  1907. if (really_show_working) {
  1908. /*
  1909. * Now run the solver again at the last difficulty level we
  1910. * tried, but this time with diagnostics enabled.
  1911. */
  1912. solver_show_working = really_show_working;
  1913. memcpy(s->grid, s->clues->immutable, p->w * p->w);
  1914. ret = solver(p->w, s->clues->clues, s->grid,
  1915. diff < DIFFCOUNT ? diff : DIFFCOUNT-1);
  1916. }
  1917. if (diff == DIFFCOUNT) {
  1918. if (grade)
  1919. printf("Difficulty rating: ambiguous\n");
  1920. else
  1921. printf("Unable to find a unique solution\n");
  1922. } else {
  1923. if (grade) {
  1924. if (ret == diff_impossible)
  1925. printf("Difficulty rating: impossible (no solution exists)\n");
  1926. else
  1927. printf("Difficulty rating: %s\n", towers_diffnames[ret]);
  1928. } else {
  1929. if (ret != diff)
  1930. printf("Puzzle is inconsistent\n");
  1931. else
  1932. fputs(game_text_format(s), stdout);
  1933. }
  1934. }
  1935. return 0;
  1936. }
  1937. #endif
  1938. /* vim: set shiftwidth=4 tabstop=8: */