unequal.c 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422
  1. /*
  2. * unequal.c
  3. *
  4. * Implementation of 'Futoshiki', a puzzle featured in the Guardian.
  5. *
  6. * TTD:
  7. * add multiple-links-on-same-col/row solver nous
  8. * Optimise set solver to use bit operations instead
  9. *
  10. * Guardian puzzles of note:
  11. * #1: 5:0,0L,0L,0,0,0R,0,0L,0D,0L,0R,0,2,0D,0,0,0,0,0,0,0U,0,0,0,0U,
  12. * #2: 5:0,0,0,4L,0L,0,2LU,0L,0U,0,0,0U,0,0,0,0,0D,0,3LRUD,0,0R,3,0L,0,0,
  13. * #3: (reprint of #2)
  14. * #4:
  15. * #5: 5:0,0,0,0,0,0,2,0U,3U,0U,0,0,3,0,0,0,3,0D,4,0,0,0L,0R,0,0,
  16. * #6: 5:0D,0L,0,0R,0,0,0D,0,3,0D,0,0R,0,0R,0D,0U,0L,0,1,2,0,0,0U,0,0L,
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <assert.h>
  22. #include <ctype.h>
  23. #ifdef NO_TGMATH_H
  24. # include <math.h>
  25. #else
  26. # include <tgmath.h>
  27. #endif
  28. #include "puzzles.h"
  29. #include "latin.h" /* contains typedef for digit */
  30. /* ----------------------------------------------------------
  31. * Constant and structure definitions
  32. */
  33. #define FLASH_TIME 0.4F
  34. #define PREFERRED_TILE_SIZE 32
  35. #define TILE_SIZE (ds->tilesize)
  36. #define GAP_SIZE (TILE_SIZE/2)
  37. #define SQUARE_SIZE (TILE_SIZE + GAP_SIZE)
  38. #define BORDER (TILE_SIZE / 2)
  39. #define COORD(x) ( (x) * SQUARE_SIZE + BORDER )
  40. #define FROMCOORD(x) ( ((x) - BORDER + SQUARE_SIZE) / SQUARE_SIZE - 1 )
  41. #define GRID(p,w,x,y) ((p)->w[((y)*(p)->order)+(x)])
  42. #define GRID3(p,w,x,y,z) ((p)->w[ (((x)*(p)->order+(y))*(p)->order+(z)) ])
  43. #define HINT(p,x,y,n) GRID3(p, hints, x, y, n)
  44. enum {
  45. COL_BACKGROUND,
  46. COL_GRID,
  47. COL_TEXT, COL_GUESS, COL_ERROR, COL_PENCIL,
  48. COL_HIGHLIGHT, COL_LOWLIGHT, COL_SPENT = COL_LOWLIGHT,
  49. NCOLOURS
  50. };
  51. typedef enum {
  52. MODE_UNEQUAL, /* Puzzle indicators are 'greater-than'. */
  53. MODE_ADJACENT /* Puzzle indicators are 'adjacent number'. */
  54. } Mode;
  55. struct game_params {
  56. int order; /* Size of latin square */
  57. int diff; /* Difficulty */
  58. Mode mode;
  59. };
  60. #define F_IMMUTABLE 1 /* passed in as game description */
  61. #define F_ADJ_UP 2
  62. #define F_ADJ_RIGHT 4
  63. #define F_ADJ_DOWN 8
  64. #define F_ADJ_LEFT 16
  65. #define F_ERROR 32
  66. #define F_ERROR_UP 64
  67. #define F_ERROR_RIGHT 128
  68. #define F_ERROR_DOWN 256
  69. #define F_ERROR_LEFT 512
  70. #define F_SPENT_UP 1024
  71. #define F_SPENT_RIGHT 2048
  72. #define F_SPENT_DOWN 4096
  73. #define F_SPENT_LEFT 8192
  74. #define ADJ_TO_SPENT(x) ((x) << 9)
  75. #define F_ERROR_MASK (F_ERROR|F_ERROR_UP|F_ERROR_RIGHT|F_ERROR_DOWN|F_ERROR_LEFT)
  76. #define F_SPENT_MASK (F_SPENT_UP|F_SPENT_RIGHT|F_SPENT_DOWN|F_SPENT_LEFT)
  77. struct game_state {
  78. int order;
  79. bool completed, cheated;
  80. Mode mode;
  81. digit *nums; /* actual numbers (size order^2) */
  82. unsigned char *hints; /* remaining possiblities (size order^3) */
  83. unsigned int *flags; /* flags (size order^2) */
  84. };
  85. /* ----------------------------------------------------------
  86. * Game parameters and presets
  87. */
  88. /* Steal the method from map.c for difficulty levels. */
  89. #define DIFFLIST(A) \
  90. A(LATIN,Trivial,NULL,t) \
  91. A(EASY,Easy,solver_easy, e) \
  92. A(SET,Tricky,solver_set, k) \
  93. A(EXTREME,Extreme,NULL,x) \
  94. A(RECURSIVE,Recursive,NULL,r)
  95. #define ENUM(upper,title,func,lower) DIFF_ ## upper,
  96. #define TITLE(upper,title,func,lower) #title,
  97. #define ENCODE(upper,title,func,lower) #lower
  98. #define CONFIG(upper,title,func,lower) ":" #title
  99. enum { DIFFLIST(ENUM) DIFFCOUNT, DIFF_IMPOSSIBLE = diff_impossible, DIFF_AMBIGUOUS = diff_ambiguous, DIFF_UNFINISHED = diff_unfinished };
  100. static char const *const unequal_diffnames[] = { DIFFLIST(TITLE) };
  101. static char const unequal_diffchars[] = DIFFLIST(ENCODE);
  102. #define DIFFCONFIG DIFFLIST(CONFIG)
  103. #define DEFAULT_PRESET 0
  104. static const struct game_params unequal_presets[] = {
  105. { 4, DIFF_EASY, 0 },
  106. { 5, DIFF_EASY, 0 },
  107. { 5, DIFF_SET, 0 },
  108. { 5, DIFF_SET, 1 },
  109. { 5, DIFF_EXTREME, 0 },
  110. { 6, DIFF_EASY, 0 },
  111. { 6, DIFF_SET, 0 },
  112. { 6, DIFF_SET, 1 },
  113. { 6, DIFF_EXTREME, 0 },
  114. { 7, DIFF_SET, 0 },
  115. { 7, DIFF_SET, 1 },
  116. { 7, DIFF_EXTREME, 0 }
  117. };
  118. static bool game_fetch_preset(int i, char **name, game_params **params)
  119. {
  120. game_params *ret;
  121. char buf[80];
  122. if (i < 0 || i >= lenof(unequal_presets))
  123. return false;
  124. ret = snew(game_params);
  125. *ret = unequal_presets[i]; /* structure copy */
  126. sprintf(buf, "%s: %dx%d %s",
  127. ret->mode == MODE_ADJACENT ? "Adjacent" : "Unequal",
  128. ret->order, ret->order,
  129. unequal_diffnames[ret->diff]);
  130. *name = dupstr(buf);
  131. *params = ret;
  132. return true;
  133. }
  134. static game_params *default_params(void)
  135. {
  136. game_params *ret;
  137. char *name;
  138. if (!game_fetch_preset(DEFAULT_PRESET, &name, &ret)) return NULL;
  139. sfree(name);
  140. return ret;
  141. }
  142. static void free_params(game_params *params)
  143. {
  144. sfree(params);
  145. }
  146. static game_params *dup_params(const game_params *params)
  147. {
  148. game_params *ret = snew(game_params);
  149. *ret = *params; /* structure copy */
  150. return ret;
  151. }
  152. static void decode_params(game_params *ret, char const *string)
  153. {
  154. char const *p = string;
  155. ret->order = atoi(p);
  156. while (*p && isdigit((unsigned char)*p)) p++;
  157. if (*p == 'a') {
  158. p++;
  159. ret->mode = MODE_ADJACENT;
  160. } else
  161. ret->mode = MODE_UNEQUAL;
  162. if (*p == 'd') {
  163. int i;
  164. p++;
  165. ret->diff = DIFFCOUNT+1; /* ...which is invalid */
  166. if (*p) {
  167. for (i = 0; i < DIFFCOUNT; i++) {
  168. if (*p == unequal_diffchars[i])
  169. ret->diff = i;
  170. }
  171. p++;
  172. }
  173. }
  174. }
  175. static char *encode_params(const game_params *params, bool full)
  176. {
  177. char ret[80];
  178. sprintf(ret, "%d", params->order);
  179. if (params->mode == MODE_ADJACENT)
  180. sprintf(ret + strlen(ret), "a");
  181. if (full)
  182. sprintf(ret + strlen(ret), "d%c", unequal_diffchars[params->diff]);
  183. return dupstr(ret);
  184. }
  185. static config_item *game_configure(const game_params *params)
  186. {
  187. config_item *ret;
  188. char buf[80];
  189. ret = snewn(4, config_item);
  190. ret[0].name = "Mode";
  191. ret[0].type = C_CHOICES;
  192. ret[0].u.choices.choicenames = ":Unequal:Adjacent";
  193. ret[0].u.choices.selected = params->mode;
  194. ret[1].name = "Size (s*s)";
  195. ret[1].type = C_STRING;
  196. sprintf(buf, "%d", params->order);
  197. ret[1].u.string.sval = dupstr(buf);
  198. ret[2].name = "Difficulty";
  199. ret[2].type = C_CHOICES;
  200. ret[2].u.choices.choicenames = DIFFCONFIG;
  201. ret[2].u.choices.selected = params->diff;
  202. ret[3].name = NULL;
  203. ret[3].type = C_END;
  204. return ret;
  205. }
  206. static game_params *custom_params(const config_item *cfg)
  207. {
  208. game_params *ret = snew(game_params);
  209. ret->mode = cfg[0].u.choices.selected;
  210. ret->order = atoi(cfg[1].u.string.sval);
  211. ret->diff = cfg[2].u.choices.selected;
  212. return ret;
  213. }
  214. static const char *validate_params(const game_params *params, bool full)
  215. {
  216. if (params->order < 3 || params->order > 32)
  217. return "Order must be between 3 and 32";
  218. if (params->diff >= DIFFCOUNT)
  219. return "Unknown difficulty rating";
  220. if (params->order < 5 && params->mode == MODE_ADJACENT &&
  221. params->diff >= DIFF_SET)
  222. return "Order must be at least 5 for Adjacent puzzles of this difficulty.";
  223. return NULL;
  224. }
  225. /* ----------------------------------------------------------
  226. * Various utility functions
  227. */
  228. static const struct { unsigned int f, fo, fe; int dx, dy; char c, ac; } adjthan[] = {
  229. { F_ADJ_UP, F_ADJ_DOWN, F_ERROR_UP, 0, -1, '^', '-' },
  230. { F_ADJ_RIGHT, F_ADJ_LEFT, F_ERROR_RIGHT, 1, 0, '>', '|' },
  231. { F_ADJ_DOWN, F_ADJ_UP, F_ERROR_DOWN, 0, 1, 'v', '-' },
  232. { F_ADJ_LEFT, F_ADJ_RIGHT, F_ERROR_LEFT, -1, 0, '<', '|' }
  233. };
  234. static game_state *blank_game(int order, Mode mode)
  235. {
  236. game_state *state = snew(game_state);
  237. int o2 = order*order, o3 = o2*order;
  238. state->order = order;
  239. state->mode = mode;
  240. state->completed = false;
  241. state->cheated = false;
  242. state->nums = snewn(o2, digit);
  243. state->hints = snewn(o3, unsigned char);
  244. state->flags = snewn(o2, unsigned int);
  245. memset(state->nums, 0, o2 * sizeof(digit));
  246. memset(state->hints, 0, o3);
  247. memset(state->flags, 0, o2 * sizeof(unsigned int));
  248. return state;
  249. }
  250. static game_state *dup_game(const game_state *state)
  251. {
  252. game_state *ret = blank_game(state->order, state->mode);
  253. int o2 = state->order*state->order, o3 = o2*state->order;
  254. memcpy(ret->nums, state->nums, o2 * sizeof(digit));
  255. memcpy(ret->hints, state->hints, o3);
  256. memcpy(ret->flags, state->flags, o2 * sizeof(unsigned int));
  257. return ret;
  258. }
  259. static void free_game(game_state *state)
  260. {
  261. sfree(state->nums);
  262. sfree(state->hints);
  263. sfree(state->flags);
  264. sfree(state);
  265. }
  266. #define CHECKG(x,y) grid[(y)*o+(x)]
  267. /* Returns false if it finds an error, true if ok. */
  268. static bool check_num_adj(digit *grid, game_state *state,
  269. int x, int y, bool me)
  270. {
  271. unsigned int f = GRID(state, flags, x, y);
  272. bool ret = true;
  273. int i, o = state->order;
  274. for (i = 0; i < 4; i++) {
  275. int dx = adjthan[i].dx, dy = adjthan[i].dy, n, dn;
  276. if (x+dx < 0 || x+dx >= o || y+dy < 0 || y+dy >= o)
  277. continue;
  278. n = CHECKG(x, y);
  279. dn = CHECKG(x+dx, y+dy);
  280. assert (n != 0);
  281. if (dn == 0) continue;
  282. if (state->mode == MODE_ADJACENT) {
  283. int gd = abs(n-dn);
  284. if ((f & adjthan[i].f) && (gd != 1)) {
  285. debug(("check_adj error (%d,%d):%d should be | (%d,%d):%d",
  286. x, y, n, x+dx, y+dy, dn));
  287. if (me) GRID(state, flags, x, y) |= adjthan[i].fe;
  288. ret = false;
  289. }
  290. if (!(f & adjthan[i].f) && (gd == 1)) {
  291. debug(("check_adj error (%d,%d):%d should not be | (%d,%d):%d",
  292. x, y, n, x+dx, y+dy, dn));
  293. if (me) GRID(state, flags, x, y) |= adjthan[i].fe;
  294. ret = false;
  295. }
  296. } else {
  297. if ((f & adjthan[i].f) && (n <= dn)) {
  298. debug(("check_adj error (%d,%d):%d not > (%d,%d):%d",
  299. x, y, n, x+dx, y+dy, dn));
  300. if (me) GRID(state, flags, x, y) |= adjthan[i].fe;
  301. ret = false;
  302. }
  303. }
  304. }
  305. return ret;
  306. }
  307. /* Returns false if it finds an error, true if ok. */
  308. static bool check_num_error(digit *grid, game_state *state,
  309. int x, int y, bool mark_errors)
  310. {
  311. int o = state->order;
  312. int xx, yy, val = CHECKG(x,y);
  313. bool ret = true;
  314. assert(val != 0);
  315. /* check for dups in same column. */
  316. for (yy = 0; yy < state->order; yy++) {
  317. if (yy == y) continue;
  318. if (CHECKG(x,yy) == val) ret = false;
  319. }
  320. /* check for dups in same row. */
  321. for (xx = 0; xx < state->order; xx++) {
  322. if (xx == x) continue;
  323. if (CHECKG(xx,y) == val) ret = false;
  324. }
  325. if (!ret) {
  326. debug(("check_num_error (%d,%d) duplicate %d", x, y, val));
  327. if (mark_errors) GRID(state, flags, x, y) |= F_ERROR;
  328. }
  329. return ret;
  330. }
  331. /* Returns: -1 for 'wrong'
  332. * 0 for 'incomplete'
  333. * 1 for 'complete and correct'
  334. */
  335. static int check_complete(digit *grid, game_state *state, bool mark_errors)
  336. {
  337. int x, y, ret = 1, o = state->order;
  338. if (mark_errors)
  339. assert(grid == state->nums);
  340. for (x = 0; x < state->order; x++) {
  341. for (y = 0; y < state->order; y++) {
  342. if (mark_errors)
  343. GRID(state, flags, x, y) &= ~F_ERROR_MASK;
  344. if (grid[y*o+x] == 0) {
  345. ret = 0;
  346. } else {
  347. if (!check_num_error(grid, state, x, y, mark_errors)) ret = -1;
  348. if (!check_num_adj(grid, state, x, y, mark_errors)) ret = -1;
  349. }
  350. }
  351. }
  352. if (ret == 1 && latin_check(grid, o))
  353. ret = -1;
  354. return ret;
  355. }
  356. static char n2c(digit n, int order) {
  357. if (n == 0) return ' ';
  358. if (order < 10) {
  359. if (n < 10) return '0' + n;
  360. } else {
  361. if (n < 11) return '0' + n-1;
  362. n -= 11;
  363. if (n <= 26) return 'A' + n;
  364. }
  365. return '?';
  366. }
  367. /* should be 'digit', but includes -1 for 'not a digit'.
  368. * Includes keypresses (0 especially) for interpret_move. */
  369. static int c2n(int c, int order) {
  370. if (c < 0 || c > 0xff)
  371. return -1;
  372. if (c == ' ' || c == '\b')
  373. return 0;
  374. if (order < 10) {
  375. if (c >= '0' && c <= '9')
  376. return (int)(c - '0');
  377. } else {
  378. if (c >= '0' && c <= '9')
  379. return (int)(c - '0' + 1);
  380. if (c >= 'A' && c <= 'Z')
  381. return (int)(c - 'A' + 11);
  382. if (c >= 'a' && c <= 'z')
  383. return (int)(c - 'a' + 11);
  384. }
  385. return -1;
  386. }
  387. static bool game_can_format_as_text_now(const game_params *params)
  388. {
  389. return true;
  390. }
  391. static char *game_text_format(const game_state *state)
  392. {
  393. int x, y, len, n;
  394. char *ret, *p;
  395. len = (state->order*2) * (state->order*2-1) + 1;
  396. ret = snewn(len, char);
  397. p = ret;
  398. for (y = 0; y < state->order; y++) {
  399. for (x = 0; x < state->order; x++) {
  400. n = GRID(state, nums, x, y);
  401. *p++ = n > 0 ? n2c(n, state->order) : '.';
  402. if (x < (state->order-1)) {
  403. if (state->mode == MODE_ADJACENT) {
  404. *p++ = (GRID(state, flags, x, y) & F_ADJ_RIGHT) ? '|' : ' ';
  405. } else {
  406. if (GRID(state, flags, x, y) & F_ADJ_RIGHT)
  407. *p++ = '>';
  408. else if (GRID(state, flags, x+1, y) & F_ADJ_LEFT)
  409. *p++ = '<';
  410. else
  411. *p++ = ' ';
  412. }
  413. }
  414. }
  415. *p++ = '\n';
  416. if (y < (state->order-1)) {
  417. for (x = 0; x < state->order; x++) {
  418. if (state->mode == MODE_ADJACENT) {
  419. *p++ = (GRID(state, flags, x, y) & F_ADJ_DOWN) ? '-' : ' ';
  420. } else {
  421. if (GRID(state, flags, x, y) & F_ADJ_DOWN)
  422. *p++ = 'v';
  423. else if (GRID(state, flags, x, y+1) & F_ADJ_UP)
  424. *p++ = '^';
  425. else
  426. *p++ = ' ';
  427. }
  428. if (x < state->order-1)
  429. *p++ = ' ';
  430. }
  431. *p++ = '\n';
  432. }
  433. }
  434. *p++ = '\0';
  435. assert(p - ret == len);
  436. return ret;
  437. }
  438. #ifdef STANDALONE_SOLVER
  439. static void game_debug(game_state *state)
  440. {
  441. char *dbg = game_text_format(state);
  442. printf("%s", dbg);
  443. sfree(dbg);
  444. }
  445. #endif
  446. /* ----------------------------------------------------------
  447. * Solver.
  448. */
  449. struct solver_link {
  450. int len, gx, gy, lx, ly;
  451. };
  452. struct solver_ctx {
  453. game_state *state;
  454. int nlinks, alinks;
  455. struct solver_link *links;
  456. };
  457. static void solver_add_link(struct solver_ctx *ctx,
  458. int gx, int gy, int lx, int ly, int len)
  459. {
  460. if (ctx->alinks < ctx->nlinks+1) {
  461. ctx->alinks = ctx->alinks*2 + 1;
  462. /*debug(("resizing ctx->links, new size %d", ctx->alinks));*/
  463. ctx->links = sresize(ctx->links, ctx->alinks, struct solver_link);
  464. }
  465. ctx->links[ctx->nlinks].gx = gx;
  466. ctx->links[ctx->nlinks].gy = gy;
  467. ctx->links[ctx->nlinks].lx = lx;
  468. ctx->links[ctx->nlinks].ly = ly;
  469. ctx->links[ctx->nlinks].len = len;
  470. ctx->nlinks++;
  471. /*debug(("Adding new link: len %d (%d,%d) < (%d,%d), nlinks now %d",
  472. len, lx, ly, gx, gy, ctx->nlinks));*/
  473. }
  474. static struct solver_ctx *new_ctx(game_state *state)
  475. {
  476. struct solver_ctx *ctx = snew(struct solver_ctx);
  477. int o = state->order;
  478. int i, x, y;
  479. unsigned int f;
  480. ctx->nlinks = ctx->alinks = 0;
  481. ctx->links = NULL;
  482. ctx->state = state;
  483. if (state->mode == MODE_ADJACENT)
  484. return ctx; /* adjacent mode doesn't use links. */
  485. for (x = 0; x < o; x++) {
  486. for (y = 0; y < o; y++) {
  487. f = GRID(state, flags, x, y);
  488. for (i = 0; i < 4; i++) {
  489. if (f & adjthan[i].f)
  490. solver_add_link(ctx, x, y, x+adjthan[i].dx, y+adjthan[i].dy, 1);
  491. }
  492. }
  493. }
  494. return ctx;
  495. }
  496. static void *clone_ctx(void *vctx)
  497. {
  498. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  499. return new_ctx(ctx->state);
  500. }
  501. static void free_ctx(void *vctx)
  502. {
  503. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  504. if (ctx->links) sfree(ctx->links);
  505. sfree(ctx);
  506. }
  507. static void solver_nminmax(struct latin_solver *solver,
  508. int x, int y, int *min_r, int *max_r,
  509. unsigned char **ns_r)
  510. {
  511. int o = solver->o, min = o, max = 0, n;
  512. unsigned char *ns;
  513. assert(x >= 0 && y >= 0 && x < o && y < o);
  514. ns = solver->cube + cubepos(x,y,1);
  515. if (grid(x,y) > 0) {
  516. min = max = grid(x,y)-1;
  517. } else {
  518. for (n = 0; n < o; n++) {
  519. if (ns[n]) {
  520. if (n > max) max = n;
  521. if (n < min) min = n;
  522. }
  523. }
  524. }
  525. if (min_r) *min_r = min;
  526. if (max_r) *max_r = max;
  527. if (ns_r) *ns_r = ns;
  528. }
  529. static int solver_links(struct latin_solver *solver, void *vctx)
  530. {
  531. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  532. int i, j, lmin, gmax, nchanged = 0;
  533. unsigned char *gns, *lns;
  534. struct solver_link *link;
  535. for (i = 0; i < ctx->nlinks; i++) {
  536. link = &ctx->links[i];
  537. solver_nminmax(solver, link->gx, link->gy, NULL, &gmax, &gns);
  538. solver_nminmax(solver, link->lx, link->ly, &lmin, NULL, &lns);
  539. for (j = 0; j < solver->o; j++) {
  540. /* For the 'greater' end of the link, discount all numbers
  541. * too small to satisfy the inequality. */
  542. if (gns[j]) {
  543. if (j < (lmin+link->len)) {
  544. #ifdef STANDALONE_SOLVER
  545. if (solver_show_working) {
  546. printf("%*slink elimination, (%d,%d) > (%d,%d):\n",
  547. solver_recurse_depth*4, "",
  548. link->gx+1, link->gy+1, link->lx+1, link->ly+1);
  549. printf("%*s ruling out %d at (%d,%d)\n",
  550. solver_recurse_depth*4, "",
  551. j+1, link->gx+1, link->gy+1);
  552. }
  553. #endif
  554. cube(link->gx, link->gy, j+1) = false;
  555. nchanged++;
  556. }
  557. }
  558. /* For the 'lesser' end of the link, discount all numbers
  559. * too large to satisfy inequality. */
  560. if (lns[j]) {
  561. if (j > (gmax-link->len)) {
  562. #ifdef STANDALONE_SOLVER
  563. if (solver_show_working) {
  564. printf("%*slink elimination, (%d,%d) > (%d,%d):\n",
  565. solver_recurse_depth*4, "",
  566. link->gx+1, link->gy+1, link->lx+1, link->ly+1);
  567. printf("%*s ruling out %d at (%d,%d)\n",
  568. solver_recurse_depth*4, "",
  569. j+1, link->lx+1, link->ly+1);
  570. }
  571. #endif
  572. cube(link->lx, link->ly, j+1) = false;
  573. nchanged++;
  574. }
  575. }
  576. }
  577. }
  578. return nchanged;
  579. }
  580. static int solver_adjacent(struct latin_solver *solver, void *vctx)
  581. {
  582. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  583. int nchanged = 0, x, y, i, n, o = solver->o, nx, ny, gd;
  584. /* Update possible values based on known values and adjacency clues. */
  585. for (x = 0; x < o; x++) {
  586. for (y = 0; y < o; y++) {
  587. if (grid(x, y) == 0) continue;
  588. /* We have a definite number here. Make sure that any
  589. * adjacent possibles reflect the adjacent/non-adjacent clue. */
  590. for (i = 0; i < 4; i++) {
  591. bool isadjacent =
  592. (GRID(ctx->state, flags, x, y) & adjthan[i].f);
  593. nx = x + adjthan[i].dx, ny = y + adjthan[i].dy;
  594. if (nx < 0 || ny < 0 || nx >= o || ny >= o)
  595. continue;
  596. for (n = 0; n < o; n++) {
  597. /* Continue past numbers the adjacent square _could_ be,
  598. * given the clue we have. */
  599. gd = abs((n+1) - grid(x, y));
  600. if (isadjacent && (gd == 1)) continue;
  601. if (!isadjacent && (gd != 1)) continue;
  602. if (!cube(nx, ny, n+1))
  603. continue; /* already discounted this possibility. */
  604. #ifdef STANDALONE_SOLVER
  605. if (solver_show_working) {
  606. printf("%*sadjacent elimination, (%d,%d):%d %s (%d,%d):\n",
  607. solver_recurse_depth*4, "",
  608. x+1, y+1, grid(x, y), isadjacent ? "|" : "!|", nx+1, ny+1);
  609. printf("%*s ruling out %d at (%d,%d)\n",
  610. solver_recurse_depth*4, "", n+1, nx+1, ny+1);
  611. }
  612. #endif
  613. cube(nx, ny, n+1) = false;
  614. nchanged++;
  615. }
  616. }
  617. }
  618. }
  619. return nchanged;
  620. }
  621. static int solver_adjacent_set(struct latin_solver *solver, void *vctx)
  622. {
  623. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  624. int x, y, i, n, nn, o = solver->o, nx, ny, gd;
  625. int nchanged = 0, *scratch = snewn(o, int);
  626. /* Update possible values based on other possible values
  627. * of adjacent squares, and adjacency clues. */
  628. for (x = 0; x < o; x++) {
  629. for (y = 0; y < o; y++) {
  630. for (i = 0; i < 4; i++) {
  631. bool isadjacent =
  632. (GRID(ctx->state, flags, x, y) & adjthan[i].f);
  633. nx = x + adjthan[i].dx, ny = y + adjthan[i].dy;
  634. if (nx < 0 || ny < 0 || nx >= o || ny >= o)
  635. continue;
  636. /* We know the current possibles for the square (x,y)
  637. * and also the adjacency clue from (x,y) to (nx,ny).
  638. * Construct a maximum set of possibles for (nx,ny)
  639. * in scratch, based on these constraints... */
  640. memset(scratch, 0, o*sizeof(int));
  641. for (n = 0; n < o; n++) {
  642. if (!cube(x, y, n+1)) continue;
  643. for (nn = 0; nn < o; nn++) {
  644. if (n == nn) continue;
  645. gd = abs(nn - n);
  646. if (isadjacent && (gd != 1)) continue;
  647. if (!isadjacent && (gd == 1)) continue;
  648. scratch[nn] = 1;
  649. }
  650. }
  651. /* ...and remove any possibilities for (nx,ny) that are
  652. * currently set but are not indicated in scratch. */
  653. for (n = 0; n < o; n++) {
  654. if (scratch[n] == 1) continue;
  655. if (!cube(nx, ny, n+1)) continue;
  656. #ifdef STANDALONE_SOLVER
  657. if (solver_show_working) {
  658. printf("%*sadjacent possible elimination, (%d,%d) %s (%d,%d):\n",
  659. solver_recurse_depth*4, "",
  660. x+1, y+1, isadjacent ? "|" : "!|", nx+1, ny+1);
  661. printf("%*s ruling out %d at (%d,%d)\n",
  662. solver_recurse_depth*4, "", n+1, nx+1, ny+1);
  663. }
  664. #endif
  665. cube(nx, ny, n+1) = false;
  666. nchanged++;
  667. }
  668. }
  669. }
  670. }
  671. return nchanged;
  672. }
  673. static int solver_easy(struct latin_solver *solver, void *vctx)
  674. {
  675. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  676. if (ctx->state->mode == MODE_ADJACENT)
  677. return solver_adjacent(solver, vctx);
  678. else
  679. return solver_links(solver, vctx);
  680. }
  681. static int solver_set(struct latin_solver *solver, void *vctx)
  682. {
  683. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  684. if (ctx->state->mode == MODE_ADJACENT)
  685. return solver_adjacent_set(solver, vctx);
  686. else
  687. return 0;
  688. }
  689. #define SOLVER(upper,title,func,lower) func,
  690. static usersolver_t const unequal_solvers[] = { DIFFLIST(SOLVER) };
  691. static bool unequal_valid(struct latin_solver *solver, void *vctx)
  692. {
  693. struct solver_ctx *ctx = (struct solver_ctx *)vctx;
  694. if (ctx->state->mode == MODE_ADJACENT) {
  695. int o = solver->o;
  696. int x, y, nx, ny, v, nv, i;
  697. for (x = 0; x+1 < o; x++) {
  698. for (y = 0; y+1 < o; y++) {
  699. v = grid(x, y);
  700. for (i = 0; i < 4; i++) {
  701. bool is_adj, should_be_adj;
  702. should_be_adj =
  703. (GRID(ctx->state, flags, x, y) & adjthan[i].f);
  704. nx = x + adjthan[i].dx, ny = y + adjthan[i].dy;
  705. if (nx < 0 || ny < 0 || nx >= o || ny >= o)
  706. continue;
  707. nv = grid(nx, ny);
  708. is_adj = (labs(v - nv) == 1);
  709. if (is_adj && !should_be_adj) {
  710. #ifdef STANDALONE_SOLVER
  711. if (solver_show_working)
  712. printf("%*s(%d,%d):%d and (%d,%d):%d have "
  713. "adjacent values, but should not\n",
  714. solver_recurse_depth*4, "",
  715. x+1, y+1, v, nx+1, ny+1, nv);
  716. #endif
  717. return false;
  718. }
  719. if (!is_adj && should_be_adj) {
  720. #ifdef STANDALONE_SOLVER
  721. if (solver_show_working)
  722. printf("%*s(%d,%d):%d and (%d,%d):%d do not have "
  723. "adjacent values, but should\n",
  724. solver_recurse_depth*4, "",
  725. x+1, y+1, v, nx+1, ny+1, nv);
  726. #endif
  727. return false;
  728. }
  729. }
  730. }
  731. }
  732. } else {
  733. int i;
  734. for (i = 0; i < ctx->nlinks; i++) {
  735. struct solver_link *link = &ctx->links[i];
  736. int gv = grid(link->gx, link->gy);
  737. int lv = grid(link->lx, link->ly);
  738. if (gv <= lv) {
  739. #ifdef STANDALONE_SOLVER
  740. if (solver_show_working)
  741. printf("%*s(%d,%d):%d should be greater than (%d,%d):%d, "
  742. "but is not\n", solver_recurse_depth*4, "",
  743. link->gx+1, link->gy+1, gv,
  744. link->lx+1, link->ly+1, lv);
  745. #endif
  746. return false;
  747. }
  748. }
  749. }
  750. return true;
  751. }
  752. static int solver_state(game_state *state, int maxdiff)
  753. {
  754. struct solver_ctx *ctx = new_ctx(state);
  755. struct latin_solver solver;
  756. int diff;
  757. if (latin_solver_alloc(&solver, state->nums, state->order))
  758. diff = latin_solver_main(&solver, maxdiff,
  759. DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
  760. DIFF_EXTREME, DIFF_RECURSIVE,
  761. unequal_solvers, unequal_valid, ctx,
  762. clone_ctx, free_ctx);
  763. else
  764. diff = DIFF_IMPOSSIBLE;
  765. memcpy(state->hints, solver.cube, state->order*state->order*state->order);
  766. free_ctx(ctx);
  767. latin_solver_free(&solver);
  768. if (diff == DIFF_IMPOSSIBLE)
  769. return -1;
  770. if (diff == DIFF_UNFINISHED)
  771. return 0;
  772. if (diff == DIFF_AMBIGUOUS)
  773. return 2;
  774. return 1;
  775. }
  776. static game_state *solver_hint(const game_state *state, int *diff_r,
  777. int mindiff, int maxdiff)
  778. {
  779. game_state *ret = dup_game(state);
  780. int diff, r = 0;
  781. for (diff = mindiff; diff <= maxdiff; diff++) {
  782. r = solver_state(ret, diff);
  783. debug(("solver_state after %s %d", unequal_diffnames[diff], r));
  784. if (r != 0) goto done;
  785. }
  786. done:
  787. if (diff_r) *diff_r = (r > 0) ? diff : -1;
  788. return ret;
  789. }
  790. /* ----------------------------------------------------------
  791. * Game generation.
  792. */
  793. static char *latin_desc(digit *sq, size_t order)
  794. {
  795. int o2 = order*order, i;
  796. char *soln = snewn(o2+2, char);
  797. soln[0] = 'S';
  798. for (i = 0; i < o2; i++)
  799. soln[i+1] = n2c(sq[i], order);
  800. soln[o2+1] = '\0';
  801. return soln;
  802. }
  803. /* returns true if it placed (or could have placed) clue. */
  804. static bool gg_place_clue(game_state *state, int ccode, digit *latin, bool checkonly)
  805. {
  806. int loc = ccode / 5, which = ccode % 5;
  807. int x = loc % state->order, y = loc / state->order;
  808. assert(loc < state->order*state->order);
  809. if (which == 4) { /* add number */
  810. if (state->nums[loc] != 0) {
  811. #ifdef STANDALONE_SOLVER
  812. if (state->nums[loc] != latin[loc]) {
  813. printf("inconsistency for (%d,%d): state %d latin %d\n",
  814. x+1, y+1, state->nums[loc], latin[loc]);
  815. }
  816. #endif
  817. assert(state->nums[loc] == latin[loc]);
  818. return false;
  819. }
  820. if (!checkonly) {
  821. state->nums[loc] = latin[loc];
  822. }
  823. } else { /* add flag */
  824. int lx, ly, lloc;
  825. if (state->mode == MODE_ADJACENT)
  826. return false; /* never add flag clues in adjacent mode
  827. (they're always all present) */
  828. if (state->flags[loc] & adjthan[which].f)
  829. return false; /* already has flag. */
  830. lx = x + adjthan[which].dx;
  831. ly = y + adjthan[which].dy;
  832. if (lx < 0 || ly < 0 || lx >= state->order || ly >= state->order)
  833. return false; /* flag compares to off grid */
  834. lloc = loc + adjthan[which].dx + adjthan[which].dy*state->order;
  835. if (latin[loc] <= latin[lloc])
  836. return false; /* flag would be incorrect */
  837. if (!checkonly) {
  838. state->flags[loc] |= adjthan[which].f;
  839. }
  840. }
  841. return true;
  842. }
  843. /* returns true if it removed (or could have removed) the clue. */
  844. static bool gg_remove_clue(game_state *state, int ccode, bool checkonly)
  845. {
  846. int loc = ccode / 5, which = ccode % 5;
  847. #ifdef STANDALONE_SOLVER
  848. int x = loc % state->order, y = loc / state->order;
  849. #endif
  850. assert(loc < state->order*state->order);
  851. if (which == 4) { /* remove number. */
  852. if (state->nums[loc] == 0) return false;
  853. if (!checkonly) {
  854. #ifdef STANDALONE_SOLVER
  855. if (solver_show_working)
  856. printf("gg_remove_clue: removing %d at (%d,%d)",
  857. state->nums[loc], x+1, y+1);
  858. #endif
  859. state->nums[loc] = 0;
  860. }
  861. } else { /* remove flag */
  862. if (state->mode == MODE_ADJACENT)
  863. return false; /* never remove clues in adjacent mode. */
  864. if (!(state->flags[loc] & adjthan[which].f)) return false;
  865. if (!checkonly) {
  866. #ifdef STANDALONE_SOLVER
  867. if (solver_show_working)
  868. printf("gg_remove_clue: removing %c at (%d,%d)",
  869. adjthan[which].c, x+1, y+1);
  870. #endif
  871. state->flags[loc] &= ~adjthan[which].f;
  872. }
  873. }
  874. return true;
  875. }
  876. static int gg_best_clue(game_state *state, int *scratch, digit *latin)
  877. {
  878. int ls = state->order * state->order * 5;
  879. int maxposs = 0, minclues = 5, best = -1, i, j;
  880. int nposs, nclues, loc;
  881. #ifdef STANDALONE_SOLVER
  882. if (solver_show_working) {
  883. game_debug(state);
  884. latin_solver_debug(state->hints, state->order);
  885. }
  886. #endif
  887. for (i = ls; i-- > 0 ;) {
  888. if (!gg_place_clue(state, scratch[i], latin, true)) continue;
  889. loc = scratch[i] / 5;
  890. for (j = nposs = 0; j < state->order; j++) {
  891. if (state->hints[loc*state->order + j]) nposs++;
  892. }
  893. for (j = nclues = 0; j < 4; j++) {
  894. if (state->flags[loc] & adjthan[j].f) nclues++;
  895. }
  896. if ((nposs > maxposs) ||
  897. (nposs == maxposs && nclues < minclues)) {
  898. best = i; maxposs = nposs; minclues = nclues;
  899. #ifdef STANDALONE_SOLVER
  900. if (solver_show_working) {
  901. int x = loc % state->order, y = loc / state->order;
  902. printf("gg_best_clue: b%d (%d,%d) new best [%d poss, %d clues].\n",
  903. best, x+1, y+1, nposs, nclues);
  904. }
  905. #endif
  906. }
  907. }
  908. /* if we didn't solve, we must have 1 clue to place! */
  909. assert(best != -1);
  910. return best;
  911. }
  912. #ifdef STANDALONE_SOLVER
  913. static int maxtries;
  914. #define MAXTRIES maxtries
  915. #else
  916. #define MAXTRIES 50
  917. #endif
  918. static int gg_solved;
  919. static int game_assemble(game_state *new, int *scratch, digit *latin,
  920. int difficulty)
  921. {
  922. game_state *copy = dup_game(new);
  923. int best;
  924. if (difficulty >= DIFF_RECURSIVE) {
  925. /* We mustn't use any solver that might guess answers;
  926. * if it guesses wrongly but solves, gg_place_clue will
  927. * get mighty confused. We will always trim clues down
  928. * (making it more difficult) in game_strip, which doesn't
  929. * have this problem. */
  930. difficulty = DIFF_RECURSIVE-1;
  931. }
  932. #ifdef STANDALONE_SOLVER
  933. if (solver_show_working) {
  934. game_debug(new);
  935. latin_solver_debug(new->hints, new->order);
  936. }
  937. #endif
  938. while(1) {
  939. gg_solved++;
  940. if (solver_state(copy, difficulty) == 1) break;
  941. best = gg_best_clue(copy, scratch, latin);
  942. gg_place_clue(new, scratch[best], latin, false);
  943. gg_place_clue(copy, scratch[best], latin, false);
  944. }
  945. free_game(copy);
  946. #ifdef STANDALONE_SOLVER
  947. if (solver_show_working) {
  948. char *dbg = game_text_format(new);
  949. printf("game_assemble: done, %d solver iterations:\n%s\n", gg_solved, dbg);
  950. sfree(dbg);
  951. }
  952. #endif
  953. return 0;
  954. }
  955. static void game_strip(game_state *new, int *scratch, digit *latin,
  956. int difficulty)
  957. {
  958. int o = new->order, o2 = o*o, lscratch = o2*5, i;
  959. game_state *copy = blank_game(new->order, new->mode);
  960. /* For each symbol (if it exists in new), try and remove it and
  961. * solve again; if we couldn't solve without it put it back. */
  962. for (i = 0; i < lscratch; i++) {
  963. if (!gg_remove_clue(new, scratch[i], false)) continue;
  964. memcpy(copy->nums, new->nums, o2 * sizeof(digit));
  965. memcpy(copy->flags, new->flags, o2 * sizeof(unsigned int));
  966. gg_solved++;
  967. if (solver_state(copy, difficulty) != 1) {
  968. /* put clue back, we can't solve without it. */
  969. bool ret = gg_place_clue(new, scratch[i], latin, false);
  970. assert(ret);
  971. } else {
  972. #ifdef STANDALONE_SOLVER
  973. if (solver_show_working)
  974. printf("game_strip: clue was redundant.");
  975. #endif
  976. }
  977. }
  978. free_game(copy);
  979. #ifdef STANDALONE_SOLVER
  980. if (solver_show_working) {
  981. char *dbg = game_text_format(new);
  982. debug(("game_strip: done, %d solver iterations.", gg_solved));
  983. debug(("%s", dbg));
  984. sfree(dbg);
  985. }
  986. #endif
  987. }
  988. static void add_adjacent_flags(game_state *state, digit *latin)
  989. {
  990. int x, y, o = state->order;
  991. /* All clues in adjacent mode are always present (the only variables are
  992. * the numbers). This adds all the flags to state based on the supplied
  993. * latin square. */
  994. for (y = 0; y < o; y++) {
  995. for (x = 0; x < o; x++) {
  996. if (x < (o-1) && (abs(latin[y*o+x] - latin[y*o+x+1]) == 1)) {
  997. GRID(state, flags, x, y) |= F_ADJ_RIGHT;
  998. GRID(state, flags, x+1, y) |= F_ADJ_LEFT;
  999. }
  1000. if (y < (o-1) && (abs(latin[y*o+x] - latin[(y+1)*o+x]) == 1)) {
  1001. GRID(state, flags, x, y) |= F_ADJ_DOWN;
  1002. GRID(state, flags, x, y+1) |= F_ADJ_UP;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. static char *new_game_desc(const game_params *params_in, random_state *rs,
  1008. char **aux, bool interactive)
  1009. {
  1010. game_params params_copy = *params_in; /* structure copy */
  1011. game_params *params = &params_copy;
  1012. digit *sq = NULL;
  1013. int i, x, y, retlen, k, nsol;
  1014. int o2 = params->order * params->order, ntries = 1;
  1015. int *scratch, lscratch = o2*5;
  1016. char *ret, buf[80];
  1017. game_state *state = blank_game(params->order, params->mode);
  1018. /* Generate a list of 'things to strip' (randomised later) */
  1019. scratch = snewn(lscratch, int);
  1020. /* Put the numbers (4 mod 5) before the inequalities (0-3 mod 5) */
  1021. for (i = 0; i < lscratch; i++) scratch[i] = (i%o2)*5 + 4 - (i/o2);
  1022. generate:
  1023. #ifdef STANDALONE_SOLVER
  1024. if (solver_show_working)
  1025. printf("new_game_desc: generating %s puzzle, ntries so far %d\n",
  1026. unequal_diffnames[params->diff], ntries);
  1027. #endif
  1028. if (sq) sfree(sq);
  1029. sq = latin_generate(params->order, rs);
  1030. latin_debug(sq, params->order);
  1031. /* Separately shuffle the numeric and inequality clues */
  1032. shuffle(scratch, lscratch/5, sizeof(int), rs);
  1033. shuffle(scratch+lscratch/5, 4*lscratch/5, sizeof(int), rs);
  1034. memset(state->nums, 0, o2 * sizeof(digit));
  1035. memset(state->flags, 0, o2 * sizeof(unsigned int));
  1036. if (state->mode == MODE_ADJACENT) {
  1037. /* All adjacency flags are always present. */
  1038. add_adjacent_flags(state, sq);
  1039. }
  1040. gg_solved = 0;
  1041. if (game_assemble(state, scratch, sq, params->diff) < 0)
  1042. goto generate;
  1043. game_strip(state, scratch, sq, params->diff);
  1044. if (params->diff > 0) {
  1045. game_state *copy = dup_game(state);
  1046. nsol = solver_state(copy, params->diff-1);
  1047. free_game(copy);
  1048. if (nsol > 0) {
  1049. #ifdef STANDALONE_SOLVER
  1050. if (solver_show_working)
  1051. printf("game_assemble: puzzle as generated is too easy.\n");
  1052. #endif
  1053. if (ntries < MAXTRIES) {
  1054. ntries++;
  1055. goto generate;
  1056. }
  1057. #ifdef STANDALONE_SOLVER
  1058. if (solver_show_working)
  1059. printf("Unable to generate %s %dx%d after %d attempts.\n",
  1060. unequal_diffnames[params->diff],
  1061. params->order, params->order, MAXTRIES);
  1062. #endif
  1063. params->diff--;
  1064. }
  1065. }
  1066. #ifdef STANDALONE_SOLVER
  1067. if (solver_show_working)
  1068. printf("new_game_desc: generated %s puzzle; %d attempts (%d solver).\n",
  1069. unequal_diffnames[params->diff], ntries, gg_solved);
  1070. #endif
  1071. ret = NULL; retlen = 0;
  1072. for (y = 0; y < params->order; y++) {
  1073. for (x = 0; x < params->order; x++) {
  1074. unsigned int f = GRID(state, flags, x, y);
  1075. k = sprintf(buf, "%d%s%s%s%s,",
  1076. GRID(state, nums, x, y),
  1077. (f & F_ADJ_UP) ? "U" : "",
  1078. (f & F_ADJ_RIGHT) ? "R" : "",
  1079. (f & F_ADJ_DOWN) ? "D" : "",
  1080. (f & F_ADJ_LEFT) ? "L" : "");
  1081. ret = sresize(ret, retlen + k + 1, char);
  1082. strcpy(ret + retlen, buf);
  1083. retlen += k;
  1084. }
  1085. }
  1086. *aux = latin_desc(sq, params->order);
  1087. free_game(state);
  1088. sfree(sq);
  1089. sfree(scratch);
  1090. return ret;
  1091. }
  1092. static game_state *load_game(const game_params *params, const char *desc,
  1093. const char **why_r)
  1094. {
  1095. game_state *state = blank_game(params->order, params->mode);
  1096. const char *p = desc;
  1097. int i = 0, n, o = params->order, x, y;
  1098. const char *why = NULL;
  1099. while (*p) {
  1100. while (*p >= 'a' && *p <= 'z') {
  1101. i += *p - 'a' + 1;
  1102. p++;
  1103. }
  1104. if (i >= o*o) {
  1105. why = "Too much data to fill grid"; goto fail;
  1106. }
  1107. if (*p < '0' || *p > '9') {
  1108. why = "Expecting number in game description"; goto fail;
  1109. }
  1110. n = atoi(p);
  1111. if (n < 0 || n > o) {
  1112. why = "Out-of-range number in game description"; goto fail;
  1113. }
  1114. state->nums[i] = (digit)n;
  1115. while (*p >= '0' && *p <= '9') p++; /* skip number */
  1116. if (state->nums[i] != 0)
  1117. state->flags[i] |= F_IMMUTABLE; /* === number set by game description */
  1118. while (*p == 'U' || *p == 'R' || *p == 'D' || *p == 'L') {
  1119. switch (*p) {
  1120. case 'U': state->flags[i] |= F_ADJ_UP; break;
  1121. case 'R': state->flags[i] |= F_ADJ_RIGHT; break;
  1122. case 'D': state->flags[i] |= F_ADJ_DOWN; break;
  1123. case 'L': state->flags[i] |= F_ADJ_LEFT; break;
  1124. default: why = "Expecting flag URDL in game description"; goto fail;
  1125. }
  1126. p++;
  1127. }
  1128. i++;
  1129. if (i < o*o && *p != ',') {
  1130. why = "Missing separator"; goto fail;
  1131. }
  1132. if (*p == ',') p++;
  1133. }
  1134. if (i < o*o) {
  1135. why = "Not enough data to fill grid"; goto fail;
  1136. }
  1137. i = 0;
  1138. for (y = 0; y < o; y++) {
  1139. for (x = 0; x < o; x++) {
  1140. for (n = 0; n < 4; n++) {
  1141. if (GRID(state, flags, x, y) & adjthan[n].f) {
  1142. int nx = x + adjthan[n].dx;
  1143. int ny = y + adjthan[n].dy;
  1144. /* a flag must not point us off the grid. */
  1145. if (nx < 0 || ny < 0 || nx >= o || ny >= o) {
  1146. why = "Flags go off grid"; goto fail;
  1147. }
  1148. if (params->mode == MODE_ADJACENT) {
  1149. /* if one cell is adjacent to another, the other must
  1150. * also be adjacent to the first. */
  1151. if (!(GRID(state, flags, nx, ny) & adjthan[n].fo)) {
  1152. why = "Flags contradicting each other"; goto fail;
  1153. }
  1154. } else {
  1155. /* if one cell is GT another, the other must _not_ also
  1156. * be GT the first. */
  1157. if (GRID(state, flags, nx, ny) & adjthan[n].fo) {
  1158. why = "Flags contradicting each other"; goto fail;
  1159. }
  1160. }
  1161. }
  1162. }
  1163. }
  1164. }
  1165. return state;
  1166. fail:
  1167. free_game(state);
  1168. if (why_r) *why_r = why;
  1169. return NULL;
  1170. }
  1171. static key_label *game_request_keys(const game_params *params, int *nkeys)
  1172. {
  1173. int i;
  1174. int order = params->order;
  1175. char off = (order > 9) ? '0' : '1';
  1176. key_label *keys = snewn(order + 1, key_label);
  1177. *nkeys = order + 1;
  1178. for(i = 0; i < order; i++) {
  1179. if (i==10) off = 'a'-10;
  1180. keys[i].button = i + off;
  1181. keys[i].label = NULL;
  1182. }
  1183. keys[order].button = '\b';
  1184. keys[order].label = NULL;
  1185. return keys;
  1186. }
  1187. static game_state *new_game(midend *me, const game_params *params,
  1188. const char *desc)
  1189. {
  1190. game_state *state = load_game(params, desc, NULL);
  1191. if (!state) {
  1192. assert("Unable to load ?validated game.");
  1193. return NULL;
  1194. }
  1195. return state;
  1196. }
  1197. static const char *validate_desc(const game_params *params, const char *desc)
  1198. {
  1199. const char *why = NULL;
  1200. game_state *dummy = load_game(params, desc, &why);
  1201. if (dummy) {
  1202. free_game(dummy);
  1203. assert(!why);
  1204. } else
  1205. assert(why);
  1206. return why;
  1207. }
  1208. static char *solve_game(const game_state *state, const game_state *currstate,
  1209. const char *aux, const char **error)
  1210. {
  1211. game_state *solved;
  1212. int r;
  1213. char *ret = NULL;
  1214. if (aux) return dupstr(aux);
  1215. solved = dup_game(state);
  1216. for (r = 0; r < state->order*state->order; r++) {
  1217. if (!(solved->flags[r] & F_IMMUTABLE))
  1218. solved->nums[r] = 0;
  1219. }
  1220. r = solver_state(solved, DIFFCOUNT-1); /* always use full solver */
  1221. if (r > 0) ret = latin_desc(solved->nums, solved->order);
  1222. free_game(solved);
  1223. return ret;
  1224. }
  1225. /* ----------------------------------------------------------
  1226. * Game UI input processing.
  1227. */
  1228. struct game_ui {
  1229. int hx, hy; /* as for solo.c, highlight pos */
  1230. bool hshow, hpencil, hcursor; /* show state, type, and ?cursor. */
  1231. };
  1232. static game_ui *new_ui(const game_state *state)
  1233. {
  1234. game_ui *ui = snew(game_ui);
  1235. ui->hx = ui->hy = 0;
  1236. ui->hpencil = false;
  1237. ui->hshow = ui->hcursor = getenv_bool("PUZZLES_SHOW_CURSOR", false);
  1238. return ui;
  1239. }
  1240. static void free_ui(game_ui *ui)
  1241. {
  1242. sfree(ui);
  1243. }
  1244. static void game_changed_state(game_ui *ui, const game_state *oldstate,
  1245. const game_state *newstate)
  1246. {
  1247. /* See solo.c; if we were pencil-mode highlighting and
  1248. * somehow a square has just been properly filled, cancel
  1249. * pencil mode. */
  1250. if (ui->hshow && ui->hpencil && !ui->hcursor &&
  1251. GRID(newstate, nums, ui->hx, ui->hy) != 0) {
  1252. ui->hshow = false;
  1253. }
  1254. }
  1255. static const char *current_key_label(const game_ui *ui,
  1256. const game_state *state, int button)
  1257. {
  1258. if (ui->hshow && IS_CURSOR_SELECT(button))
  1259. return ui->hpencil ? "Ink" : "Pencil";
  1260. return "";
  1261. }
  1262. struct game_drawstate {
  1263. int tilesize, order;
  1264. bool started;
  1265. Mode mode;
  1266. digit *nums; /* copy of nums, o^2 */
  1267. unsigned char *hints; /* copy of hints, o^3 */
  1268. unsigned int *flags; /* o^2 */
  1269. int hx, hy;
  1270. bool hshow, hpencil; /* as for game_ui. */
  1271. bool hflash;
  1272. };
  1273. static char *interpret_move(const game_state *state, game_ui *ui,
  1274. const game_drawstate *ds,
  1275. int ox, int oy, int button)
  1276. {
  1277. int x = FROMCOORD(ox), y = FROMCOORD(oy), n;
  1278. char buf[80];
  1279. bool shift_or_control = button & (MOD_SHFT | MOD_CTRL);
  1280. button &= ~MOD_MASK;
  1281. if (x >= 0 && x < ds->order && y >= 0 && y < ds->order && IS_MOUSE_DOWN(button)) {
  1282. if (oy - COORD(y) > TILE_SIZE && ox - COORD(x) > TILE_SIZE)
  1283. return NULL;
  1284. if (oy - COORD(y) > TILE_SIZE) {
  1285. if (GRID(state, flags, x, y) & F_ADJ_DOWN)
  1286. sprintf(buf, "F%d,%d,%d", x, y, F_SPENT_DOWN);
  1287. else if (y + 1 < ds->order && GRID(state, flags, x, y + 1) & F_ADJ_UP)
  1288. sprintf(buf, "F%d,%d,%d", x, y + 1, F_SPENT_UP);
  1289. else return NULL;
  1290. return dupstr(buf);
  1291. }
  1292. if (ox - COORD(x) > TILE_SIZE) {
  1293. if (GRID(state, flags, x, y) & F_ADJ_RIGHT)
  1294. sprintf(buf, "F%d,%d,%d", x, y, F_SPENT_RIGHT);
  1295. else if (x + 1 < ds->order && GRID(state, flags, x + 1, y) & F_ADJ_LEFT)
  1296. sprintf(buf, "F%d,%d,%d", x + 1, y, F_SPENT_LEFT);
  1297. else return NULL;
  1298. return dupstr(buf);
  1299. }
  1300. if (button == LEFT_BUTTON) {
  1301. /* normal highlighting for non-immutable squares */
  1302. if (GRID(state, flags, x, y) & F_IMMUTABLE)
  1303. ui->hshow = false;
  1304. else if (x == ui->hx && y == ui->hy &&
  1305. ui->hshow && !ui->hpencil)
  1306. ui->hshow = false;
  1307. else {
  1308. ui->hx = x; ui->hy = y; ui->hpencil = false;
  1309. ui->hshow = true;
  1310. }
  1311. ui->hcursor = false;
  1312. return MOVE_UI_UPDATE;
  1313. }
  1314. if (button == RIGHT_BUTTON) {
  1315. /* pencil highlighting for non-filled squares */
  1316. if (GRID(state, nums, x, y) != 0)
  1317. ui->hshow = false;
  1318. else if (x == ui->hx && y == ui->hy &&
  1319. ui->hshow && ui->hpencil)
  1320. ui->hshow = false;
  1321. else {
  1322. ui->hx = x; ui->hy = y; ui->hpencil = true;
  1323. ui->hshow = true;
  1324. }
  1325. ui->hcursor = false;
  1326. return MOVE_UI_UPDATE;
  1327. }
  1328. }
  1329. if (IS_CURSOR_MOVE(button)) {
  1330. if (shift_or_control) {
  1331. int nx = ui->hx, ny = ui->hy, i;
  1332. bool self;
  1333. move_cursor(button, &nx, &ny, ds->order, ds->order, false);
  1334. ui->hshow = true;
  1335. ui->hcursor = true;
  1336. for (i = 0; i < 4 && (nx != ui->hx + adjthan[i].dx ||
  1337. ny != ui->hy + adjthan[i].dy); ++i);
  1338. if (i == 4)
  1339. return MOVE_UI_UPDATE; /* invalid direction, i.e. out of
  1340. * the board */
  1341. if (!(GRID(state, flags, ui->hx, ui->hy) & adjthan[i].f ||
  1342. GRID(state, flags, nx, ny ) & adjthan[i].fo))
  1343. return MOVE_UI_UPDATE; /* no clue to toggle */
  1344. if (state->mode == MODE_ADJACENT)
  1345. self = (adjthan[i].dx >= 0 && adjthan[i].dy >= 0);
  1346. else
  1347. self = (GRID(state, flags, ui->hx, ui->hy) & adjthan[i].f);
  1348. if (self)
  1349. sprintf(buf, "F%d,%d,%u", ui->hx, ui->hy,
  1350. ADJ_TO_SPENT(adjthan[i].f));
  1351. else
  1352. sprintf(buf, "F%d,%d,%u", nx, ny,
  1353. ADJ_TO_SPENT(adjthan[i].fo));
  1354. return dupstr(buf);
  1355. } else {
  1356. move_cursor(button, &ui->hx, &ui->hy, ds->order, ds->order, false);
  1357. ui->hshow = true;
  1358. ui->hcursor = true;
  1359. return MOVE_UI_UPDATE;
  1360. }
  1361. }
  1362. if (ui->hshow && IS_CURSOR_SELECT(button)) {
  1363. ui->hpencil = !ui->hpencil;
  1364. ui->hcursor = true;
  1365. return MOVE_UI_UPDATE;
  1366. }
  1367. n = c2n(button, state->order);
  1368. if (ui->hshow && n >= 0 && n <= ds->order) {
  1369. debug(("button %d, cbutton %d", button, (int)((char)button)));
  1370. debug(("n %d, h (%d,%d) p %d flags 0x%x nums %d",
  1371. n, ui->hx, ui->hy, ui->hpencil,
  1372. GRID(state, flags, ui->hx, ui->hy),
  1373. GRID(state, nums, ui->hx, ui->hy)));
  1374. if (GRID(state, flags, ui->hx, ui->hy) & F_IMMUTABLE)
  1375. return NULL; /* can't edit immutable square (!) */
  1376. if (ui->hpencil && GRID(state, nums, ui->hx, ui->hy) > 0)
  1377. return NULL; /* can't change hints on filled square (!) */
  1378. /*
  1379. * If you ask to fill a square with what it already contains,
  1380. * or blank it when it's already empty, that has no effect...
  1381. */
  1382. if ((!ui->hpencil || n == 0) &&
  1383. GRID(state, nums, ui->hx, ui->hy) == n) {
  1384. bool anypencil = false;
  1385. int i;
  1386. for (i = 0; i < state->order; i++)
  1387. anypencil = anypencil || HINT(state, ui->hx, ui->hy, i);
  1388. if (!anypencil) {
  1389. /* ... expect to remove the cursor in mouse mode. */
  1390. if (!ui->hcursor) {
  1391. ui->hshow = false;
  1392. return MOVE_UI_UPDATE;
  1393. }
  1394. return NULL;
  1395. }
  1396. }
  1397. sprintf(buf, "%c%d,%d,%d",
  1398. (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
  1399. if (!ui->hcursor) ui->hshow = false;
  1400. return dupstr(buf);
  1401. }
  1402. if (button == 'H' || button == 'h')
  1403. return dupstr("H");
  1404. if (button == 'M' || button == 'm')
  1405. return dupstr("M");
  1406. return NULL;
  1407. }
  1408. static game_state *execute_move(const game_state *state, const char *move)
  1409. {
  1410. game_state *ret = NULL;
  1411. int x, y, n, i;
  1412. debug(("execute_move: %s", move));
  1413. if ((move[0] == 'P' || move[0] == 'R') &&
  1414. sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 &&
  1415. x >= 0 && x < state->order && y >= 0 && y < state->order &&
  1416. n >= 0 && n <= state->order) {
  1417. ret = dup_game(state);
  1418. if (move[0] == 'P' && n > 0)
  1419. HINT(ret, x, y, n-1) = !HINT(ret, x, y, n-1);
  1420. else {
  1421. GRID(ret, nums, x, y) = n;
  1422. for (i = 0; i < state->order; i++)
  1423. HINT(ret, x, y, i) = 0;
  1424. /* real change to grid; check for completion */
  1425. if (!ret->completed && check_complete(ret->nums, ret, true) > 0)
  1426. ret->completed = true;
  1427. }
  1428. return ret;
  1429. } else if (move[0] == 'S') {
  1430. const char *p;
  1431. ret = dup_game(state);
  1432. ret->cheated = true;
  1433. p = move+1;
  1434. for (i = 0; i < state->order*state->order; i++) {
  1435. n = c2n((int)*p, state->order);
  1436. if (!*p || n <= 0 || n > state->order)
  1437. goto badmove;
  1438. ret->nums[i] = n;
  1439. p++;
  1440. }
  1441. if (*p) goto badmove;
  1442. if (!ret->completed && check_complete(ret->nums, ret, true) > 0)
  1443. ret->completed = true;
  1444. return ret;
  1445. } else if (move[0] == 'M') {
  1446. ret = dup_game(state);
  1447. for (x = 0; x < state->order; x++) {
  1448. for (y = 0; y < state->order; y++) {
  1449. for (n = 0; n < state->order; n++) {
  1450. HINT(ret, x, y, n) = 1;
  1451. }
  1452. }
  1453. }
  1454. return ret;
  1455. } else if (move[0] == 'H') {
  1456. ret = solver_hint(state, NULL, DIFF_EASY, DIFF_EASY);
  1457. check_complete(ret->nums, ret, true);
  1458. return ret;
  1459. } else if (move[0] == 'F' && sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 &&
  1460. x >= 0 && x < state->order && y >= 0 && y < state->order &&
  1461. (n & ~F_SPENT_MASK) == 0) {
  1462. ret = dup_game(state);
  1463. GRID(ret, flags, x, y) ^= n;
  1464. return ret;
  1465. }
  1466. badmove:
  1467. if (ret) free_game(ret);
  1468. return NULL;
  1469. }
  1470. /* ----------------------------------------------------------------------
  1471. * Drawing/printing routines.
  1472. */
  1473. #define DRAW_SIZE (TILE_SIZE*ds->order + GAP_SIZE*(ds->order-1) + BORDER*2)
  1474. static void game_compute_size(const game_params *params, int tilesize,
  1475. const game_ui *ui, int *x, int *y)
  1476. {
  1477. /* Ick: fake up `ds->tilesize' for macro expansion purposes */
  1478. struct { int tilesize, order; } ads, *ds = &ads;
  1479. ads.tilesize = tilesize;
  1480. ads.order = params->order;
  1481. *x = *y = DRAW_SIZE;
  1482. }
  1483. static void game_set_size(drawing *dr, game_drawstate *ds,
  1484. const game_params *params, int tilesize)
  1485. {
  1486. ds->tilesize = tilesize;
  1487. }
  1488. static float *game_colours(frontend *fe, int *ncolours)
  1489. {
  1490. float *ret = snewn(3 * NCOLOURS, float);
  1491. int i;
  1492. game_mkhighlight(fe, ret, COL_BACKGROUND, COL_HIGHLIGHT, COL_LOWLIGHT);
  1493. for (i = 0; i < 3; i++) {
  1494. ret[COL_TEXT * 3 + i] = 0.0F;
  1495. ret[COL_GRID * 3 + i] = 0.5F;
  1496. }
  1497. /* Lots of these were taken from solo.c. */
  1498. ret[COL_GUESS * 3 + 0] = 0.0F;
  1499. ret[COL_GUESS * 3 + 1] = 0.6F * ret[COL_BACKGROUND * 3 + 1];
  1500. ret[COL_GUESS * 3 + 2] = 0.0F;
  1501. ret[COL_ERROR * 3 + 0] = 1.0F;
  1502. ret[COL_ERROR * 3 + 1] = 0.0F;
  1503. ret[COL_ERROR * 3 + 2] = 0.0F;
  1504. ret[COL_PENCIL * 3 + 0] = 0.5F * ret[COL_BACKGROUND * 3 + 0];
  1505. ret[COL_PENCIL * 3 + 1] = 0.5F * ret[COL_BACKGROUND * 3 + 1];
  1506. ret[COL_PENCIL * 3 + 2] = ret[COL_BACKGROUND * 3 + 2];
  1507. *ncolours = NCOLOURS;
  1508. return ret;
  1509. }
  1510. static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
  1511. {
  1512. struct game_drawstate *ds = snew(struct game_drawstate);
  1513. int o2 = state->order*state->order, o3 = o2*state->order;
  1514. ds->tilesize = 0;
  1515. ds->order = state->order;
  1516. ds->mode = state->mode;
  1517. ds->nums = snewn(o2, digit);
  1518. ds->hints = snewn(o3, unsigned char);
  1519. ds->flags = snewn(o2, unsigned int);
  1520. memset(ds->nums, 0, o2*sizeof(digit));
  1521. memset(ds->hints, 0, o3);
  1522. memset(ds->flags, 0, o2*sizeof(unsigned int));
  1523. ds->hx = ds->hy = 0;
  1524. ds->started = false;
  1525. ds->hshow = false;
  1526. ds->hpencil = false;
  1527. ds->hflash = false;
  1528. return ds;
  1529. }
  1530. static void game_free_drawstate(drawing *dr, game_drawstate *ds)
  1531. {
  1532. sfree(ds->nums);
  1533. sfree(ds->hints);
  1534. sfree(ds->flags);
  1535. sfree(ds);
  1536. }
  1537. static void draw_gt(drawing *dr, int ox, int oy,
  1538. int dx1, int dy1, int dx2, int dy2, int col)
  1539. {
  1540. int coords[12];
  1541. int xdx = (dx1+dx2 ? 0 : 1), xdy = (dx1+dx2 ? 1 : 0);
  1542. coords[0] = ox + xdx;
  1543. coords[1] = oy + xdy;
  1544. coords[2] = ox + xdx + dx1;
  1545. coords[3] = oy + xdy + dy1;
  1546. coords[4] = ox + xdx + dx1 + dx2;
  1547. coords[5] = oy + xdy + dy1 + dy2;
  1548. coords[6] = ox - xdx + dx1 + dx2;
  1549. coords[7] = oy - xdy + dy1 + dy2;
  1550. coords[8] = ox - xdx + dx1;
  1551. coords[9] = oy - xdy + dy1;
  1552. coords[10] = ox - xdx;
  1553. coords[11] = oy - xdy;
  1554. draw_polygon(dr, coords, 6, col, col);
  1555. }
  1556. #define COLOUR(direction) (f & (F_ERROR_##direction) ? COL_ERROR : \
  1557. f & (F_SPENT_##direction) ? COL_SPENT : fg)
  1558. static void draw_gts(drawing *dr, game_drawstate *ds, int ox, int oy,
  1559. unsigned int f, int bg, int fg)
  1560. {
  1561. int g = GAP_SIZE, g2 = (g+1)/2, g4 = (g+1)/4;
  1562. /* Draw all the greater-than signs emanating from this tile. */
  1563. if (f & F_ADJ_UP) {
  1564. if (bg >= 0) draw_rect(dr, ox, oy - g, TILE_SIZE, g, bg);
  1565. draw_gt(dr, ox+g2, oy-g4, g2, -g2, g2, g2, COLOUR(UP));
  1566. draw_update(dr, ox, oy-g, TILE_SIZE, g);
  1567. }
  1568. if (f & F_ADJ_RIGHT) {
  1569. if (bg >= 0) draw_rect(dr, ox + TILE_SIZE, oy, g, TILE_SIZE, bg);
  1570. draw_gt(dr, ox+TILE_SIZE+g4, oy+g2, g2, g2, -g2, g2, COLOUR(RIGHT));
  1571. draw_update(dr, ox+TILE_SIZE, oy, g, TILE_SIZE);
  1572. }
  1573. if (f & F_ADJ_DOWN) {
  1574. if (bg >= 0) draw_rect(dr, ox, oy + TILE_SIZE, TILE_SIZE, g, bg);
  1575. draw_gt(dr, ox+g2, oy+TILE_SIZE+g4, g2, g2, g2, -g2, COLOUR(DOWN));
  1576. draw_update(dr, ox, oy+TILE_SIZE, TILE_SIZE, g);
  1577. }
  1578. if (f & F_ADJ_LEFT) {
  1579. if (bg >= 0) draw_rect(dr, ox - g, oy, g, TILE_SIZE, bg);
  1580. draw_gt(dr, ox-g4, oy+g2, -g2, g2, g2, g2, COLOUR(LEFT));
  1581. draw_update(dr, ox-g, oy, g, TILE_SIZE);
  1582. }
  1583. }
  1584. static void draw_adjs(drawing *dr, game_drawstate *ds, int ox, int oy,
  1585. unsigned int f, int bg, int fg)
  1586. {
  1587. int g = GAP_SIZE, g38 = 3*(g+1)/8, g4 = (g+1)/4;
  1588. /* Draw all the adjacency bars relevant to this tile; we only have
  1589. * to worry about F_ADJ_RIGHT and F_ADJ_DOWN.
  1590. *
  1591. * If we _only_ have the error flag set (i.e. it's not supposed to be
  1592. * adjacent, but adjacent numbers were entered) draw an outline red bar.
  1593. */
  1594. if (f & (F_ADJ_RIGHT|F_ERROR_RIGHT)) {
  1595. if (f & F_ADJ_RIGHT) {
  1596. draw_rect(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, COLOUR(RIGHT));
  1597. } else {
  1598. draw_rect_outline(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, COL_ERROR);
  1599. }
  1600. } else if (bg >= 0) {
  1601. draw_rect(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, bg);
  1602. }
  1603. draw_update(dr, ox+TILE_SIZE, oy, g, TILE_SIZE);
  1604. if (f & (F_ADJ_DOWN|F_ERROR_DOWN)) {
  1605. if (f & F_ADJ_DOWN) {
  1606. draw_rect(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, COLOUR(DOWN));
  1607. } else {
  1608. draw_rect_outline(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, COL_ERROR);
  1609. }
  1610. } else if (bg >= 0) {
  1611. draw_rect(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, bg);
  1612. }
  1613. draw_update(dr, ox, oy+TILE_SIZE, TILE_SIZE, g);
  1614. }
  1615. static void draw_furniture(drawing *dr, game_drawstate *ds,
  1616. const game_state *state, const game_ui *ui,
  1617. int x, int y, bool hflash)
  1618. {
  1619. int ox = COORD(x), oy = COORD(y), bg;
  1620. bool hon;
  1621. unsigned int f = GRID(state, flags, x, y);
  1622. bg = hflash ? COL_HIGHLIGHT : COL_BACKGROUND;
  1623. hon = (ui->hshow && x == ui->hx && y == ui->hy);
  1624. /* Clear square. */
  1625. draw_rect(dr, ox, oy, TILE_SIZE, TILE_SIZE,
  1626. (hon && !ui->hpencil) ? COL_HIGHLIGHT : bg);
  1627. /* Draw the highlight (pencil or full), if we're the highlight */
  1628. if (hon && ui->hpencil) {
  1629. int coords[6];
  1630. coords[0] = ox;
  1631. coords[1] = oy;
  1632. coords[2] = ox + TILE_SIZE/2;
  1633. coords[3] = oy;
  1634. coords[4] = ox;
  1635. coords[5] = oy + TILE_SIZE/2;
  1636. draw_polygon(dr, coords, 3, COL_HIGHLIGHT, COL_HIGHLIGHT);
  1637. }
  1638. /* Draw the square outline (which is the cursor, if we're the cursor). */
  1639. draw_rect_outline(dr, ox, oy, TILE_SIZE, TILE_SIZE, COL_GRID);
  1640. draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE);
  1641. /* Draw the adjacent clue signs. */
  1642. if (ds->mode == MODE_ADJACENT)
  1643. draw_adjs(dr, ds, ox, oy, f, COL_BACKGROUND, COL_GRID);
  1644. else
  1645. draw_gts(dr, ds, ox, oy, f, COL_BACKGROUND, COL_TEXT);
  1646. }
  1647. static void draw_num(drawing *dr, game_drawstate *ds, int x, int y)
  1648. {
  1649. int ox = COORD(x), oy = COORD(y);
  1650. unsigned int f = GRID(ds,flags,x,y);
  1651. char str[2];
  1652. /* (can assume square has just been cleared) */
  1653. /* Draw number, choosing appropriate colour */
  1654. str[0] = n2c(GRID(ds, nums, x, y), ds->order);
  1655. str[1] = '\0';
  1656. draw_text(dr, ox + TILE_SIZE/2, oy + TILE_SIZE/2,
  1657. FONT_VARIABLE, 3*TILE_SIZE/4, ALIGN_VCENTRE | ALIGN_HCENTRE,
  1658. (f & F_IMMUTABLE) ? COL_TEXT : (f & F_ERROR) ? COL_ERROR : COL_GUESS, str);
  1659. }
  1660. static void draw_hints(drawing *dr, game_drawstate *ds, int x, int y)
  1661. {
  1662. int ox = COORD(x), oy = COORD(y);
  1663. int nhints, i, j, hw, hh, hmax, fontsz;
  1664. char str[2];
  1665. /* (can assume square has just been cleared) */
  1666. /* Draw hints; steal ingenious algorithm (basically)
  1667. * from solo.c:draw_number() */
  1668. for (i = nhints = 0; i < ds->order; i++) {
  1669. if (HINT(ds, x, y, i)) nhints++;
  1670. }
  1671. for (hw = 1; hw * hw < nhints; hw++);
  1672. if (hw < 3) hw = 3;
  1673. hh = (nhints + hw - 1) / hw;
  1674. if (hh < 2) hh = 2;
  1675. hmax = max(hw, hh);
  1676. fontsz = TILE_SIZE/(hmax*(11-hmax)/8);
  1677. for (i = j = 0; i < ds->order; i++) {
  1678. if (HINT(ds,x,y,i)) {
  1679. int hx = j % hw, hy = j / hw;
  1680. str[0] = n2c(i+1, ds->order);
  1681. str[1] = '\0';
  1682. draw_text(dr,
  1683. ox + (4*hx+3) * TILE_SIZE / (4*hw+2),
  1684. oy + (4*hy+3) * TILE_SIZE / (4*hh+2),
  1685. FONT_VARIABLE, fontsz,
  1686. ALIGN_VCENTRE | ALIGN_HCENTRE, COL_PENCIL, str);
  1687. j++;
  1688. }
  1689. }
  1690. }
  1691. static void game_redraw(drawing *dr, game_drawstate *ds,
  1692. const game_state *oldstate, const game_state *state,
  1693. int dir, const game_ui *ui,
  1694. float animtime, float flashtime)
  1695. {
  1696. int x, y, i;
  1697. bool hchanged = false, stale, hflash = false;
  1698. debug(("highlight old (%d,%d), new (%d,%d)", ds->hx, ds->hy, ui->hx, ui->hy));
  1699. if (flashtime > 0 &&
  1700. (flashtime <= FLASH_TIME/3 || flashtime >= FLASH_TIME*2/3))
  1701. hflash = true;
  1702. if (!ds->started) {
  1703. draw_rect(dr, 0, 0, DRAW_SIZE, DRAW_SIZE, COL_BACKGROUND);
  1704. draw_update(dr, 0, 0, DRAW_SIZE, DRAW_SIZE);
  1705. }
  1706. if (ds->hx != ui->hx || ds->hy != ui->hy ||
  1707. ds->hshow != ui->hshow || ds->hpencil != ui->hpencil)
  1708. hchanged = true;
  1709. for (x = 0; x < ds->order; x++) {
  1710. for (y = 0; y < ds->order; y++) {
  1711. if (!ds->started)
  1712. stale = true;
  1713. else if (hflash != ds->hflash)
  1714. stale = true;
  1715. else
  1716. stale = false;
  1717. if (hchanged) {
  1718. if ((x == ui->hx && y == ui->hy) ||
  1719. (x == ds->hx && y == ds->hy))
  1720. stale = true;
  1721. }
  1722. if (GRID(state, nums, x, y) != GRID(ds, nums, x, y)) {
  1723. GRID(ds, nums, x, y) = GRID(state, nums, x, y);
  1724. stale = true;
  1725. }
  1726. if (GRID(state, flags, x, y) != GRID(ds, flags, x, y)) {
  1727. GRID(ds, flags, x, y) = GRID(state, flags, x, y);
  1728. stale = true;
  1729. }
  1730. if (GRID(ds, nums, x, y) == 0) {
  1731. /* We're not a number square (therefore we might
  1732. * display hints); do we need to update? */
  1733. for (i = 0; i < ds->order; i++) {
  1734. if (HINT(state, x, y, i) != HINT(ds, x, y, i)) {
  1735. HINT(ds, x, y, i) = HINT(state, x, y, i);
  1736. stale = true;
  1737. }
  1738. }
  1739. }
  1740. if (stale) {
  1741. draw_furniture(dr, ds, state, ui, x, y, hflash);
  1742. if (GRID(ds, nums, x, y) > 0)
  1743. draw_num(dr, ds, x, y);
  1744. else
  1745. draw_hints(dr, ds, x, y);
  1746. }
  1747. }
  1748. }
  1749. ds->hx = ui->hx; ds->hy = ui->hy;
  1750. ds->hshow = ui->hshow;
  1751. ds->hpencil = ui->hpencil;
  1752. ds->started = true;
  1753. ds->hflash = hflash;
  1754. }
  1755. static float game_anim_length(const game_state *oldstate,
  1756. const game_state *newstate, int dir, game_ui *ui)
  1757. {
  1758. return 0.0F;
  1759. }
  1760. static float game_flash_length(const game_state *oldstate,
  1761. const game_state *newstate, int dir, game_ui *ui)
  1762. {
  1763. if (!oldstate->completed && newstate->completed &&
  1764. !oldstate->cheated && !newstate->cheated)
  1765. return FLASH_TIME;
  1766. return 0.0F;
  1767. }
  1768. static void game_get_cursor_location(const game_ui *ui,
  1769. const game_drawstate *ds,
  1770. const game_state *state,
  1771. const game_params *params,
  1772. int *x, int *y, int *w, int *h)
  1773. {
  1774. if(ui->hshow) {
  1775. *x = COORD(ui->hx);
  1776. *y = COORD(ui->hy);
  1777. *w = *h = TILE_SIZE;
  1778. }
  1779. }
  1780. static int game_status(const game_state *state)
  1781. {
  1782. return state->completed ? +1 : 0;
  1783. }
  1784. static void game_print_size(const game_params *params, const game_ui *ui,
  1785. float *x, float *y)
  1786. {
  1787. int pw, ph;
  1788. /* 10mm squares by default, roughly the same as Grauniad. */
  1789. game_compute_size(params, 1000, ui, &pw, &ph);
  1790. *x = pw / 100.0F;
  1791. *y = ph / 100.0F;
  1792. }
  1793. static void game_print(drawing *dr, const game_state *state, const game_ui *ui,
  1794. int tilesize)
  1795. {
  1796. int ink = print_mono_colour(dr, 0);
  1797. int x, y, o = state->order, ox, oy, n;
  1798. char str[2];
  1799. /* Ick: fake up `ds->tilesize' for macro expansion purposes */
  1800. game_drawstate ads, *ds = &ads;
  1801. game_set_size(dr, ds, NULL, tilesize);
  1802. print_line_width(dr, 2 * TILE_SIZE / 40);
  1803. /* Squares, numbers, gt signs */
  1804. for (y = 0; y < o; y++) {
  1805. for (x = 0; x < o; x++) {
  1806. ox = COORD(x); oy = COORD(y);
  1807. n = GRID(state, nums, x, y);
  1808. draw_rect_outline(dr, ox, oy, TILE_SIZE, TILE_SIZE, ink);
  1809. str[0] = n ? n2c(n, state->order) : ' ';
  1810. str[1] = '\0';
  1811. draw_text(dr, ox + TILE_SIZE/2, oy + TILE_SIZE/2,
  1812. FONT_VARIABLE, TILE_SIZE/2, ALIGN_VCENTRE | ALIGN_HCENTRE,
  1813. ink, str);
  1814. if (state->mode == MODE_ADJACENT)
  1815. draw_adjs(dr, ds, ox, oy, GRID(state, flags, x, y), -1, ink);
  1816. else
  1817. draw_gts(dr, ds, ox, oy, GRID(state, flags, x, y), -1, ink);
  1818. }
  1819. }
  1820. }
  1821. /* ----------------------------------------------------------------------
  1822. * Housekeeping.
  1823. */
  1824. #ifdef COMBINED
  1825. #define thegame unequal
  1826. #endif
  1827. const struct game thegame = {
  1828. "Unequal", "games.unequal", "unequal",
  1829. default_params,
  1830. game_fetch_preset, NULL,
  1831. decode_params,
  1832. encode_params,
  1833. free_params,
  1834. dup_params,
  1835. true, game_configure, custom_params,
  1836. validate_params,
  1837. new_game_desc,
  1838. validate_desc,
  1839. new_game,
  1840. dup_game,
  1841. free_game,
  1842. true, solve_game,
  1843. true, game_can_format_as_text_now, game_text_format,
  1844. NULL, NULL, /* get_prefs, set_prefs */
  1845. new_ui,
  1846. free_ui,
  1847. NULL, /* encode_ui */
  1848. NULL, /* decode_ui */
  1849. game_request_keys,
  1850. game_changed_state,
  1851. current_key_label,
  1852. interpret_move,
  1853. execute_move,
  1854. PREFERRED_TILE_SIZE, game_compute_size, game_set_size,
  1855. game_colours,
  1856. game_new_drawstate,
  1857. game_free_drawstate,
  1858. game_redraw,
  1859. game_anim_length,
  1860. game_flash_length,
  1861. game_get_cursor_location,
  1862. game_status,
  1863. true, false, game_print_size, game_print,
  1864. false, /* wants_statusbar */
  1865. false, NULL, /* timing_state */
  1866. REQUIRE_RBUTTON | REQUIRE_NUMPAD, /* flags */
  1867. };
  1868. /* ----------------------------------------------------------------------
  1869. * Standalone solver.
  1870. */
  1871. #ifdef STANDALONE_SOLVER
  1872. #include <time.h>
  1873. #include <stdarg.h>
  1874. static const char *quis = NULL;
  1875. #if 0 /* currently unused */
  1876. static void debug_printf(const char *fmt, ...)
  1877. {
  1878. char buf[4096];
  1879. va_list ap;
  1880. va_start(ap, fmt);
  1881. vsprintf(buf, fmt, ap);
  1882. puts(buf);
  1883. va_end(ap);
  1884. }
  1885. static void game_printf(game_state *state)
  1886. {
  1887. char *dbg = game_text_format(state);
  1888. printf("%s", dbg);
  1889. sfree(dbg);
  1890. }
  1891. static void game_printf_wide(game_state *state)
  1892. {
  1893. int x, y, i, n;
  1894. for (y = 0; y < state->order; y++) {
  1895. for (x = 0; x < state->order; x++) {
  1896. n = GRID(state, nums, x, y);
  1897. for (i = 0; i < state->order; i++) {
  1898. if (n > 0)
  1899. printf("%c", n2c(n, state->order));
  1900. else if (HINT(state, x, y, i))
  1901. printf("%c", n2c(i+1, state->order));
  1902. else
  1903. printf(".");
  1904. }
  1905. printf(" ");
  1906. }
  1907. printf("\n");
  1908. }
  1909. printf("\n");
  1910. }
  1911. #endif
  1912. static void pdiff(int diff)
  1913. {
  1914. if (diff == DIFF_IMPOSSIBLE)
  1915. printf("Game is impossible.\n");
  1916. else if (diff == DIFF_UNFINISHED)
  1917. printf("Game has incomplete.\n");
  1918. else if (diff == DIFF_AMBIGUOUS)
  1919. printf("Game has multiple solutions.\n");
  1920. else
  1921. printf("Game has difficulty %s.\n", unequal_diffnames[diff]);
  1922. }
  1923. static int solve(game_params *p, char *desc, int debug)
  1924. {
  1925. game_state *state = new_game(NULL, p, desc);
  1926. struct solver_ctx *ctx = new_ctx(state);
  1927. struct latin_solver solver;
  1928. int diff;
  1929. solver_show_working = debug;
  1930. game_debug(state);
  1931. if (latin_solver_alloc(&solver, state->nums, state->order))
  1932. diff = latin_solver_main(&solver, DIFF_RECURSIVE,
  1933. DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
  1934. DIFF_EXTREME, DIFF_RECURSIVE,
  1935. unequal_solvers, unequal_valid, ctx,
  1936. clone_ctx, free_ctx);
  1937. else
  1938. diff = DIFF_IMPOSSIBLE;
  1939. free_ctx(ctx);
  1940. latin_solver_free(&solver);
  1941. if (debug) pdiff(diff);
  1942. game_debug(state);
  1943. free_game(state);
  1944. return diff;
  1945. }
  1946. static void check(game_params *p)
  1947. {
  1948. const char *msg = validate_params(p, true);
  1949. if (msg) {
  1950. fprintf(stderr, "%s: %s", quis, msg);
  1951. exit(1);
  1952. }
  1953. }
  1954. static int gen(game_params *p, random_state *rs, int debug)
  1955. {
  1956. char *desc, *aux;
  1957. int diff;
  1958. check(p);
  1959. solver_show_working = debug;
  1960. desc = new_game_desc(p, rs, &aux, false);
  1961. diff = solve(p, desc, debug);
  1962. sfree(aux);
  1963. sfree(desc);
  1964. return diff;
  1965. }
  1966. static void soak(game_params *p, random_state *rs)
  1967. {
  1968. time_t tt_start, tt_now, tt_last;
  1969. char *aux, *desc;
  1970. game_state *st;
  1971. int n = 0, neasy = 0, realdiff = p->diff;
  1972. check(p);
  1973. solver_show_working = 0;
  1974. maxtries = 1;
  1975. tt_start = tt_now = time(NULL);
  1976. printf("Soak-generating an %s %dx%d grid, difficulty %s.\n",
  1977. p->mode == MODE_ADJACENT ? "adjacent" : "unequal",
  1978. p->order, p->order, unequal_diffnames[p->diff]);
  1979. while (1) {
  1980. p->diff = realdiff;
  1981. desc = new_game_desc(p, rs, &aux, false);
  1982. st = new_game(NULL, p, desc);
  1983. solver_state(st, DIFF_RECURSIVE);
  1984. free_game(st);
  1985. sfree(aux);
  1986. sfree(desc);
  1987. n++;
  1988. if (realdiff != p->diff) neasy++;
  1989. tt_last = time(NULL);
  1990. if (tt_last > tt_now) {
  1991. tt_now = tt_last;
  1992. printf("%d total, %3.1f/s; %d/%2.1f%% easy, %3.1f/s good.\n",
  1993. n, (double)n / ((double)tt_now - tt_start),
  1994. neasy, (double)neasy*100.0/(double)n,
  1995. (double)(n - neasy) / ((double)tt_now - tt_start));
  1996. }
  1997. }
  1998. }
  1999. static void usage_exit(const char *msg)
  2000. {
  2001. if (msg)
  2002. fprintf(stderr, "%s: %s\n", quis, msg);
  2003. fprintf(stderr, "Usage: %s [--seed SEED] --soak <params> | [game_id [game_id ...]]\n", quis);
  2004. exit(1);
  2005. }
  2006. int main(int argc, const char *argv[])
  2007. {
  2008. random_state *rs;
  2009. time_t seed = time(NULL);
  2010. int do_soak = 0, diff;
  2011. game_params *p;
  2012. maxtries = 50;
  2013. quis = argv[0];
  2014. while (--argc > 0) {
  2015. const char *p = *++argv;
  2016. if (!strcmp(p, "--soak"))
  2017. do_soak = 1;
  2018. else if (!strcmp(p, "--seed")) {
  2019. if (argc == 0)
  2020. usage_exit("--seed needs an argument");
  2021. seed = (time_t)atoi(*++argv);
  2022. argc--;
  2023. } else if (*p == '-')
  2024. usage_exit("unrecognised option");
  2025. else
  2026. break;
  2027. }
  2028. rs = random_new((void*)&seed, sizeof(time_t));
  2029. if (do_soak == 1) {
  2030. if (argc != 1) usage_exit("only one argument for --soak");
  2031. p = default_params();
  2032. decode_params(p, *argv);
  2033. soak(p, rs);
  2034. } else if (argc > 0) {
  2035. int i;
  2036. for (i = 0; i < argc; i++) {
  2037. const char *id = *argv++;
  2038. char *desc = strchr(id, ':');
  2039. const char *err;
  2040. p = default_params();
  2041. if (desc) {
  2042. *desc++ = '\0';
  2043. decode_params(p, id);
  2044. err = validate_desc(p, desc);
  2045. if (err) {
  2046. fprintf(stderr, "%s: %s\n", quis, err);
  2047. exit(1);
  2048. }
  2049. solve(p, desc, 1);
  2050. } else {
  2051. decode_params(p, id);
  2052. diff = gen(p, rs, 1);
  2053. }
  2054. }
  2055. } else {
  2056. while(1) {
  2057. p = default_params();
  2058. p->order = random_upto(rs, 7) + 3;
  2059. p->diff = random_upto(rs, 4);
  2060. diff = gen(p, rs, 0);
  2061. pdiff(diff);
  2062. }
  2063. }
  2064. return 0;
  2065. }
  2066. #endif
  2067. /* vim: set shiftwidth=4 tabstop=8: */