unruly.c 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183
  1. /*
  2. * unruly.c: Implementation for Binary Puzzles.
  3. * (C) 2012 Lennard Sprong
  4. * Created for Simon Tatham's Portable Puzzle Collection
  5. * See LICENCE for licence details
  6. *
  7. * Objective of the game: Fill the grid with zeros and ones, with the
  8. * following rules:
  9. * - There can't be a run of three or more equal numbers.
  10. * - Each row and column contains an equal amount of zeros and ones.
  11. *
  12. * This puzzle type is known under several names, including
  13. * Tohu-Wa-Vohu, One and Two and Binairo.
  14. *
  15. * Some variants include an extra constraint, stating that no two rows or two
  16. * columns may contain the same exact sequence of zeros and ones.
  17. * This rule is rarely used, so it is not enabled in the default presets
  18. * (but it can be selected via the Custom configurer).
  19. *
  20. * More information:
  21. * http://www.janko.at/Raetsel/Tohu-Wa-Vohu/index.htm
  22. */
  23. /*
  24. * Possible future improvements:
  25. *
  26. * More solver cleverness
  27. *
  28. * - a counting-based deduction in which you find groups of squares
  29. * which must each contain at least one of a given colour, plus
  30. * other squares which are already known to be that colour, and see
  31. * if you have any squares left over when you've worked out where
  32. * they all have to be. This is a generalisation of the current
  33. * check_near_complete: where that only covers rows with three
  34. * unfilled squares, this would handle more, such as
  35. * 0 . . 1 0 1 . . 0 .
  36. * in which each of the two-square gaps must contain a 0, and there
  37. * are three 0s placed, and that means the rightmost square can't
  38. * be a 0.
  39. *
  40. * - an 'Unreasonable' difficulty level, supporting recursion and
  41. * backtracking.
  42. */
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <assert.h>
  47. #include <ctype.h>
  48. #ifdef NO_TGMATH_H
  49. # include <math.h>
  50. #else
  51. # include <tgmath.h>
  52. #endif
  53. #include "puzzles.h"
  54. #ifdef STANDALONE_SOLVER
  55. static bool solver_verbose = false;
  56. #endif
  57. enum {
  58. COL_BACKGROUND,
  59. COL_GRID,
  60. COL_EMPTY,
  61. /*
  62. * When editing this enum, maintain the invariants
  63. * COL_n_HIGHLIGHT = COL_n + 1
  64. * COL_n_LOWLIGHT = COL_n + 2
  65. */
  66. COL_0,
  67. COL_0_HIGHLIGHT,
  68. COL_0_LOWLIGHT,
  69. COL_1,
  70. COL_1_HIGHLIGHT,
  71. COL_1_LOWLIGHT,
  72. COL_CURSOR,
  73. COL_ERROR,
  74. NCOLOURS
  75. };
  76. struct game_params {
  77. int w2, h2; /* full grid width and height respectively */
  78. bool unique; /* should row and column patterns be unique? */
  79. int diff;
  80. };
  81. #define DIFFLIST(A) \
  82. A(TRIVIAL,Trivial, t) \
  83. A(EASY,Easy, e) \
  84. A(NORMAL,Normal, n) \
  85. #define ENUM(upper,title,lower) DIFF_ ## upper,
  86. #define TITLE(upper,title,lower) #title,
  87. #define ENCODE(upper,title,lower) #lower
  88. #define CONFIG(upper,title,lower) ":" #title
  89. enum { DIFFLIST(ENUM) DIFFCOUNT };
  90. static char const *const unruly_diffnames[] = { DIFFLIST(TITLE) };
  91. static char const unruly_diffchars[] = DIFFLIST(ENCODE);
  92. #define DIFFCONFIG DIFFLIST(CONFIG)
  93. static const struct game_params unruly_presets[] = {
  94. { 8, 8, false, DIFF_TRIVIAL},
  95. { 8, 8, false, DIFF_EASY},
  96. { 8, 8, false, DIFF_NORMAL},
  97. {10, 10, false, DIFF_EASY},
  98. {10, 10, false, DIFF_NORMAL},
  99. {14, 14, false, DIFF_EASY},
  100. {14, 14, false, DIFF_NORMAL}
  101. };
  102. #define DEFAULT_PRESET 0
  103. enum {
  104. EMPTY,
  105. N_ONE,
  106. N_ZERO,
  107. BOGUS
  108. };
  109. #define FE_HOR_ROW_LEFT 0x0001
  110. #define FE_HOR_ROW_MID 0x0003
  111. #define FE_HOR_ROW_RIGHT 0x0002
  112. #define FE_VER_ROW_TOP 0x0004
  113. #define FE_VER_ROW_MID 0x000C
  114. #define FE_VER_ROW_BOTTOM 0x0008
  115. #define FE_COUNT 0x0010
  116. #define FE_ROW_MATCH 0x0020
  117. #define FE_COL_MATCH 0x0040
  118. #define FF_ONE 0x0080
  119. #define FF_ZERO 0x0100
  120. #define FF_CURSOR 0x0200
  121. #define FF_FLASH1 0x0400
  122. #define FF_FLASH2 0x0800
  123. #define FF_IMMUTABLE 0x1000
  124. typedef struct unruly_common {
  125. int refcount;
  126. bool *immutable;
  127. } unruly_common;
  128. struct game_state {
  129. int w2, h2;
  130. bool unique;
  131. char *grid;
  132. unruly_common *common;
  133. bool completed, cheated;
  134. };
  135. static game_params *default_params(void)
  136. {
  137. game_params *ret = snew(game_params);
  138. *ret = unruly_presets[DEFAULT_PRESET]; /* structure copy */
  139. return ret;
  140. }
  141. static bool game_fetch_preset(int i, char **name, game_params **params)
  142. {
  143. game_params *ret;
  144. char buf[80];
  145. if (i < 0 || i >= lenof(unruly_presets))
  146. return false;
  147. ret = snew(game_params);
  148. *ret = unruly_presets[i]; /* structure copy */
  149. sprintf(buf, "%dx%d %s", ret->w2, ret->h2, unruly_diffnames[ret->diff]);
  150. *name = dupstr(buf);
  151. *params = ret;
  152. return true;
  153. }
  154. static void free_params(game_params *params)
  155. {
  156. sfree(params);
  157. }
  158. static game_params *dup_params(const game_params *params)
  159. {
  160. game_params *ret = snew(game_params);
  161. *ret = *params; /* structure copy */
  162. return ret;
  163. }
  164. static void decode_params(game_params *params, char const *string)
  165. {
  166. char const *p = string;
  167. params->unique = false;
  168. params->w2 = atoi(p);
  169. while (*p && isdigit((unsigned char)*p)) p++;
  170. if (*p == 'x') {
  171. p++;
  172. params->h2 = atoi(p);
  173. while (*p && isdigit((unsigned char)*p)) p++;
  174. } else {
  175. params->h2 = params->w2;
  176. }
  177. if (*p == 'u') {
  178. p++;
  179. params->unique = true;
  180. }
  181. if (*p == 'd') {
  182. int i;
  183. p++;
  184. params->diff = DIFFCOUNT + 1; /* ...which is invalid */
  185. if (*p) {
  186. for (i = 0; i < DIFFCOUNT; i++) {
  187. if (*p == unruly_diffchars[i])
  188. params->diff = i;
  189. }
  190. p++;
  191. }
  192. }
  193. }
  194. static char *encode_params(const game_params *params, bool full)
  195. {
  196. char buf[80];
  197. sprintf(buf, "%dx%d", params->w2, params->h2);
  198. if (params->unique)
  199. strcat(buf, "u");
  200. if (full)
  201. sprintf(buf + strlen(buf), "d%c", unruly_diffchars[params->diff]);
  202. return dupstr(buf);
  203. }
  204. static config_item *game_configure(const game_params *params)
  205. {
  206. config_item *ret;
  207. char buf[80];
  208. ret = snewn(5, config_item);
  209. ret[0].name = "Width";
  210. ret[0].type = C_STRING;
  211. sprintf(buf, "%d", params->w2);
  212. ret[0].u.string.sval = dupstr(buf);
  213. ret[1].name = "Height";
  214. ret[1].type = C_STRING;
  215. sprintf(buf, "%d", params->h2);
  216. ret[1].u.string.sval = dupstr(buf);
  217. ret[2].name = "Unique rows and columns";
  218. ret[2].type = C_BOOLEAN;
  219. ret[2].u.boolean.bval = params->unique;
  220. ret[3].name = "Difficulty";
  221. ret[3].type = C_CHOICES;
  222. ret[3].u.choices.choicenames = DIFFCONFIG;
  223. ret[3].u.choices.selected = params->diff;
  224. ret[4].name = NULL;
  225. ret[4].type = C_END;
  226. return ret;
  227. }
  228. static game_params *custom_params(const config_item *cfg)
  229. {
  230. game_params *ret = snew(game_params);
  231. ret->w2 = atoi(cfg[0].u.string.sval);
  232. ret->h2 = atoi(cfg[1].u.string.sval);
  233. ret->unique = cfg[2].u.boolean.bval;
  234. ret->diff = cfg[3].u.choices.selected;
  235. return ret;
  236. }
  237. static const char *validate_params(const game_params *params, bool full)
  238. {
  239. if ((params->w2 & 1) || (params->h2 & 1))
  240. return "Width and height must both be even";
  241. if (params->w2 < 6 || params->h2 < 6)
  242. return "Width and height must be at least 6";
  243. if (params->w2 > INT_MAX / params->h2)
  244. return "Width times height must not be unreasonably large";
  245. if (params->unique) {
  246. static const long A177790[] = {
  247. /*
  248. * The nth element of this array gives the number of
  249. * distinct possible Unruly rows of length 2n (that is,
  250. * containing exactly n 1s and n 0s and not containing
  251. * three consecutive elements the same) for as long as
  252. * those numbers fit in a 32-bit signed int.
  253. *
  254. * So in unique-rows mode, if the puzzle width is 2n, then
  255. * the height must be at most (this array)[n], and vice
  256. * versa.
  257. *
  258. * This is sequence A177790 in the Online Encyclopedia of
  259. * Integer Sequences: http://oeis.org/A177790
  260. */
  261. 1L, 2L, 6L, 14L, 34L, 84L, 208L, 518L, 1296L, 3254L,
  262. 8196L, 20700L, 52404L, 132942L, 337878L, 860142L,
  263. 2192902L, 5598144L, 14308378L, 36610970L, 93770358L,
  264. 240390602L, 616787116L, 1583765724L
  265. };
  266. if (params->w2 < 2*lenof(A177790) &&
  267. params->h2 > A177790[params->w2/2]) {
  268. return "Puzzle is too tall for unique-rows mode";
  269. }
  270. if (params->h2 < 2*lenof(A177790) &&
  271. params->w2 > A177790[params->h2/2]) {
  272. return "Puzzle is too long for unique-rows mode";
  273. }
  274. }
  275. if (params->diff >= DIFFCOUNT)
  276. return "Unknown difficulty rating";
  277. return NULL;
  278. }
  279. static const char *validate_desc(const game_params *params, const char *desc)
  280. {
  281. int w2 = params->w2, h2 = params->h2;
  282. int s = w2 * h2;
  283. const char *p = desc;
  284. int pos = 0;
  285. while (*p) {
  286. if (*p >= 'a' && *p < 'z')
  287. pos += 1 + (*p - 'a');
  288. else if (*p >= 'A' && *p < 'Z')
  289. pos += 1 + (*p - 'A');
  290. else if (*p == 'Z' || *p == 'z')
  291. pos += 25;
  292. else
  293. return "Description contains invalid characters";
  294. ++p;
  295. }
  296. if (pos < s+1)
  297. return "Description too short";
  298. if (pos > s+1)
  299. return "Description too long";
  300. return NULL;
  301. }
  302. static game_state *blank_state(int w2, int h2, bool unique, bool new_common)
  303. {
  304. game_state *state = snew(game_state);
  305. int s = w2 * h2;
  306. state->w2 = w2;
  307. state->h2 = h2;
  308. state->unique = unique;
  309. state->grid = snewn(s, char);
  310. memset(state->grid, EMPTY, s);
  311. if (new_common) {
  312. state->common = snew(unruly_common);
  313. state->common->refcount = 1;
  314. state->common->immutable = snewn(s, bool);
  315. memset(state->common->immutable, 0, s*sizeof(bool));
  316. }
  317. state->completed = state->cheated = false;
  318. return state;
  319. }
  320. static game_state *new_game(midend *me, const game_params *params,
  321. const char *desc)
  322. {
  323. int w2 = params->w2, h2 = params->h2;
  324. int s = w2 * h2;
  325. game_state *state = blank_state(w2, h2, params->unique, true);
  326. const char *p = desc;
  327. int pos = 0;
  328. while (*p) {
  329. if (*p >= 'a' && *p < 'z') {
  330. pos += (*p - 'a');
  331. if (pos < s) {
  332. state->grid[pos] = N_ZERO;
  333. state->common->immutable[pos] = true;
  334. }
  335. pos++;
  336. } else if (*p >= 'A' && *p < 'Z') {
  337. pos += (*p - 'A');
  338. if (pos < s) {
  339. state->grid[pos] = N_ONE;
  340. state->common->immutable[pos] = true;
  341. }
  342. pos++;
  343. } else if (*p == 'Z' || *p == 'z') {
  344. pos += 25;
  345. } else
  346. assert(!"Description contains invalid characters");
  347. ++p;
  348. }
  349. assert(pos == s+1);
  350. return state;
  351. }
  352. static game_state *dup_game(const game_state *state)
  353. {
  354. int w2 = state->w2, h2 = state->h2;
  355. int s = w2 * h2;
  356. game_state *ret = blank_state(w2, h2, state->unique, false);
  357. memcpy(ret->grid, state->grid, s);
  358. ret->common = state->common;
  359. ret->common->refcount++;
  360. ret->completed = state->completed;
  361. ret->cheated = state->cheated;
  362. return ret;
  363. }
  364. static void free_game(game_state *state)
  365. {
  366. sfree(state->grid);
  367. if (--state->common->refcount == 0) {
  368. sfree(state->common->immutable);
  369. sfree(state->common);
  370. }
  371. sfree(state);
  372. }
  373. static bool game_can_format_as_text_now(const game_params *params)
  374. {
  375. return true;
  376. }
  377. static char *game_text_format(const game_state *state)
  378. {
  379. int w2 = state->w2, h2 = state->h2;
  380. int lr = w2*2 + 1;
  381. char *ret = snewn(lr * h2 + 1, char);
  382. char *p = ret;
  383. int x, y;
  384. for (y = 0; y < h2; y++) {
  385. for (x = 0; x < w2; x++) {
  386. /* Place number */
  387. char c = state->grid[y * w2 + x];
  388. *p++ = (c == N_ONE ? '1' : c == N_ZERO ? '0' : '.');
  389. *p++ = ' ';
  390. }
  391. /* End line */
  392. *p++ = '\n';
  393. }
  394. /* End with NUL */
  395. *p++ = '\0';
  396. return ret;
  397. }
  398. /* ****** *
  399. * Solver *
  400. * ****** */
  401. struct unruly_scratch {
  402. int *ones_rows;
  403. int *ones_cols;
  404. int *zeros_rows;
  405. int *zeros_cols;
  406. };
  407. static void unruly_solver_update_remaining(const game_state *state,
  408. struct unruly_scratch *scratch)
  409. {
  410. int w2 = state->w2, h2 = state->h2;
  411. int x, y;
  412. /* Reset all scratch data */
  413. memset(scratch->ones_rows, 0, h2 * sizeof(int));
  414. memset(scratch->ones_cols, 0, w2 * sizeof(int));
  415. memset(scratch->zeros_rows, 0, h2 * sizeof(int));
  416. memset(scratch->zeros_cols, 0, w2 * sizeof(int));
  417. for (x = 0; x < w2; x++)
  418. for (y = 0; y < h2; y++) {
  419. if (state->grid[y * w2 + x] == N_ONE) {
  420. scratch->ones_rows[y]++;
  421. scratch->ones_cols[x]++;
  422. } else if (state->grid[y * w2 + x] == N_ZERO) {
  423. scratch->zeros_rows[y]++;
  424. scratch->zeros_cols[x]++;
  425. }
  426. }
  427. }
  428. static struct unruly_scratch *unruly_new_scratch(const game_state *state)
  429. {
  430. int w2 = state->w2, h2 = state->h2;
  431. struct unruly_scratch *ret = snew(struct unruly_scratch);
  432. ret->ones_rows = snewn(h2, int);
  433. ret->ones_cols = snewn(w2, int);
  434. ret->zeros_rows = snewn(h2, int);
  435. ret->zeros_cols = snewn(w2, int);
  436. unruly_solver_update_remaining(state, ret);
  437. return ret;
  438. }
  439. static void unruly_free_scratch(struct unruly_scratch *scratch)
  440. {
  441. sfree(scratch->ones_rows);
  442. sfree(scratch->ones_cols);
  443. sfree(scratch->zeros_rows);
  444. sfree(scratch->zeros_cols);
  445. sfree(scratch);
  446. }
  447. static int unruly_solver_check_threes(game_state *state, int *rowcount,
  448. int *colcount, bool horizontal,
  449. char check, char block)
  450. {
  451. int w2 = state->w2, h2 = state->h2;
  452. int dx = horizontal ? 1 : 0, dy = 1 - dx;
  453. int sx = dx, sy = dy;
  454. int ex = w2 - dx, ey = h2 - dy;
  455. int x, y;
  456. int ret = 0;
  457. /* Check for any three squares which almost form three in a row */
  458. for (y = sy; y < ey; y++) {
  459. for (x = sx; x < ex; x++) {
  460. int i1 = (y-dy) * w2 + (x-dx);
  461. int i2 = y * w2 + x;
  462. int i3 = (y+dy) * w2 + (x+dx);
  463. if (state->grid[i1] == check && state->grid[i2] == check
  464. && state->grid[i3] == EMPTY) {
  465. ret++;
  466. #ifdef STANDALONE_SOLVER
  467. if (solver_verbose) {
  468. printf("Solver: %i,%i and %i,%i confirm %c at %i,%i\n",
  469. i1 % w2, i1 / w2, i2 % w2, i2 / w2,
  470. (block == N_ONE ? '1' : '0'), i3 % w2,
  471. i3 / w2);
  472. }
  473. #endif
  474. state->grid[i3] = block;
  475. rowcount[i3 / w2]++;
  476. colcount[i3 % w2]++;
  477. }
  478. if (state->grid[i1] == check && state->grid[i2] == EMPTY
  479. && state->grid[i3] == check) {
  480. ret++;
  481. #ifdef STANDALONE_SOLVER
  482. if (solver_verbose) {
  483. printf("Solver: %i,%i and %i,%i confirm %c at %i,%i\n",
  484. i1 % w2, i1 / w2, i3 % w2, i3 / w2,
  485. (block == N_ONE ? '1' : '0'), i2 % w2,
  486. i2 / w2);
  487. }
  488. #endif
  489. state->grid[i2] = block;
  490. rowcount[i2 / w2]++;
  491. colcount[i2 % w2]++;
  492. }
  493. if (state->grid[i1] == EMPTY && state->grid[i2] == check
  494. && state->grid[i3] == check) {
  495. ret++;
  496. #ifdef STANDALONE_SOLVER
  497. if (solver_verbose) {
  498. printf("Solver: %i,%i and %i,%i confirm %c at %i,%i\n",
  499. i2 % w2, i2 / w2, i3 % w2, i3 / w2,
  500. (block == N_ONE ? '1' : '0'), i1 % w2,
  501. i1 / w2);
  502. }
  503. #endif
  504. state->grid[i1] = block;
  505. rowcount[i1 / w2]++;
  506. colcount[i1 % w2]++;
  507. }
  508. }
  509. }
  510. return ret;
  511. }
  512. static int unruly_solver_check_all_threes(game_state *state,
  513. struct unruly_scratch *scratch)
  514. {
  515. int ret = 0;
  516. ret +=
  517. unruly_solver_check_threes(state, scratch->zeros_rows,
  518. scratch->zeros_cols, true, N_ONE, N_ZERO);
  519. ret +=
  520. unruly_solver_check_threes(state, scratch->ones_rows,
  521. scratch->ones_cols, true, N_ZERO, N_ONE);
  522. ret +=
  523. unruly_solver_check_threes(state, scratch->zeros_rows,
  524. scratch->zeros_cols, false, N_ONE,
  525. N_ZERO);
  526. ret +=
  527. unruly_solver_check_threes(state, scratch->ones_rows,
  528. scratch->ones_cols, false, N_ZERO, N_ONE);
  529. return ret;
  530. }
  531. static int unruly_solver_check_uniques(game_state *state, int *rowcount,
  532. bool horizontal, char check, char block,
  533. struct unruly_scratch *scratch)
  534. {
  535. int w2 = state->w2, h2 = state->h2;
  536. int rmult = (horizontal ? w2 : 1);
  537. int cmult = (horizontal ? 1 : w2);
  538. int nr = (horizontal ? h2 : w2);
  539. int nc = (horizontal ? w2 : h2);
  540. int max = nc / 2;
  541. int r, r2, c;
  542. int ret = 0;
  543. /*
  544. * Find each row that has max entries of type 'check', and see if
  545. * all those entries match those in any row with max-1 entries. If
  546. * so, set the last non-matching entry of the latter row to ensure
  547. * that it's different.
  548. */
  549. for (r = 0; r < nr; r++) {
  550. if (rowcount[r] != max)
  551. continue;
  552. for (r2 = 0; r2 < nr; r2++) {
  553. int nmatch = 0, nonmatch = -1;
  554. if (rowcount[r2] != max-1)
  555. continue;
  556. for (c = 0; c < nc; c++) {
  557. if (state->grid[r*rmult + c*cmult] == check) {
  558. if (state->grid[r2*rmult + c*cmult] == check)
  559. nmatch++;
  560. else
  561. nonmatch = c;
  562. }
  563. }
  564. if (nmatch == max-1) {
  565. int i1 = r2 * rmult + nonmatch * cmult;
  566. assert(nonmatch != -1);
  567. if (state->grid[i1] == block)
  568. continue;
  569. assert(state->grid[i1] == EMPTY);
  570. #ifdef STANDALONE_SOLVER
  571. if (solver_verbose) {
  572. printf("Solver: matching %s %i, %i gives %c at %i,%i\n",
  573. horizontal ? "rows" : "cols",
  574. r, r2, (block == N_ONE ? '1' : '0'), i1 % w2,
  575. i1 / w2);
  576. }
  577. #endif
  578. state->grid[i1] = block;
  579. if (block == N_ONE) {
  580. scratch->ones_rows[i1 / w2]++;
  581. scratch->ones_cols[i1 % w2]++;
  582. } else {
  583. scratch->zeros_rows[i1 / w2]++;
  584. scratch->zeros_cols[i1 % w2]++;
  585. }
  586. ret++;
  587. }
  588. }
  589. }
  590. return ret;
  591. }
  592. static int unruly_solver_check_all_uniques(game_state *state,
  593. struct unruly_scratch *scratch)
  594. {
  595. int ret = 0;
  596. ret += unruly_solver_check_uniques(state, scratch->ones_rows,
  597. true, N_ONE, N_ZERO, scratch);
  598. ret += unruly_solver_check_uniques(state, scratch->zeros_rows,
  599. true, N_ZERO, N_ONE, scratch);
  600. ret += unruly_solver_check_uniques(state, scratch->ones_cols,
  601. false, N_ONE, N_ZERO, scratch);
  602. ret += unruly_solver_check_uniques(state, scratch->zeros_cols,
  603. false, N_ZERO, N_ONE, scratch);
  604. return ret;
  605. }
  606. static int unruly_solver_fill_row(game_state *state, int i, bool horizontal,
  607. int *rowcount, int *colcount, char fill)
  608. {
  609. int ret = 0;
  610. int w2 = state->w2, h2 = state->h2;
  611. int j;
  612. #ifdef STANDALONE_SOLVER
  613. if (solver_verbose) {
  614. printf("Solver: Filling %s %i with %c:",
  615. (horizontal ? "Row" : "Col"), i,
  616. (fill == N_ZERO ? '0' : '1'));
  617. }
  618. #endif
  619. /* Place a number in every empty square in a row/column */
  620. for (j = 0; j < (horizontal ? w2 : h2); j++) {
  621. int p = (horizontal ? i * w2 + j : j * w2 + i);
  622. if (state->grid[p] == EMPTY) {
  623. #ifdef STANDALONE_SOLVER
  624. if (solver_verbose) {
  625. printf(" (%i,%i)", (horizontal ? j : i),
  626. (horizontal ? i : j));
  627. }
  628. #endif
  629. ret++;
  630. state->grid[p] = fill;
  631. rowcount[(horizontal ? i : j)]++;
  632. colcount[(horizontal ? j : i)]++;
  633. }
  634. }
  635. #ifdef STANDALONE_SOLVER
  636. if (solver_verbose) {
  637. printf("\n");
  638. }
  639. #endif
  640. return ret;
  641. }
  642. static int unruly_solver_check_single_gap(game_state *state,
  643. int *complete, bool horizontal,
  644. int *rowcount, int *colcount,
  645. char fill)
  646. {
  647. int w2 = state->w2, h2 = state->h2;
  648. int count = (horizontal ? h2 : w2); /* number of rows to check */
  649. int target = (horizontal ? w2 : h2) / 2; /* target number of 0s/1s */
  650. int *other = (horizontal ? rowcount : colcount);
  651. int ret = 0;
  652. int i;
  653. /* Check for completed rows/cols for one number, then fill in the rest */
  654. for (i = 0; i < count; i++) {
  655. if (complete[i] == target && other[i] == target - 1) {
  656. #ifdef STANDALONE_SOLVER
  657. if (solver_verbose) {
  658. printf("Solver: Row %i has only one square left which must be "
  659. "%c\n", i, (fill == N_ZERO ? '0' : '1'));
  660. }
  661. #endif
  662. ret += unruly_solver_fill_row(state, i, horizontal, rowcount,
  663. colcount, fill);
  664. }
  665. }
  666. return ret;
  667. }
  668. static int unruly_solver_check_all_single_gap(game_state *state,
  669. struct unruly_scratch *scratch)
  670. {
  671. int ret = 0;
  672. ret +=
  673. unruly_solver_check_single_gap(state, scratch->ones_rows, true,
  674. scratch->zeros_rows,
  675. scratch->zeros_cols, N_ZERO);
  676. ret +=
  677. unruly_solver_check_single_gap(state, scratch->ones_cols, false,
  678. scratch->zeros_rows,
  679. scratch->zeros_cols, N_ZERO);
  680. ret +=
  681. unruly_solver_check_single_gap(state, scratch->zeros_rows, true,
  682. scratch->ones_rows,
  683. scratch->ones_cols, N_ONE);
  684. ret +=
  685. unruly_solver_check_single_gap(state, scratch->zeros_cols, false,
  686. scratch->ones_rows,
  687. scratch->ones_cols, N_ONE);
  688. return ret;
  689. }
  690. static int unruly_solver_check_complete_nums(game_state *state,
  691. int *complete, bool horizontal,
  692. int *rowcount, int *colcount,
  693. char fill)
  694. {
  695. int w2 = state->w2, h2 = state->h2;
  696. int count = (horizontal ? h2 : w2); /* number of rows to check */
  697. int target = (horizontal ? w2 : h2) / 2; /* target number of 0s/1s */
  698. int *other = (horizontal ? rowcount : colcount);
  699. int ret = 0;
  700. int i;
  701. /* Check for completed rows/cols for one number, then fill in the rest */
  702. for (i = 0; i < count; i++) {
  703. if (complete[i] == target && other[i] < target) {
  704. #ifdef STANDALONE_SOLVER
  705. if (solver_verbose) {
  706. printf("Solver: Row %i satisfied for %c\n", i,
  707. (fill != N_ZERO ? '0' : '1'));
  708. }
  709. #endif
  710. ret += unruly_solver_fill_row(state, i, horizontal, rowcount,
  711. colcount, fill);
  712. }
  713. }
  714. return ret;
  715. }
  716. static int unruly_solver_check_all_complete_nums(game_state *state,
  717. struct unruly_scratch *scratch)
  718. {
  719. int ret = 0;
  720. ret +=
  721. unruly_solver_check_complete_nums(state, scratch->ones_rows, true,
  722. scratch->zeros_rows,
  723. scratch->zeros_cols, N_ZERO);
  724. ret +=
  725. unruly_solver_check_complete_nums(state, scratch->ones_cols, false,
  726. scratch->zeros_rows,
  727. scratch->zeros_cols, N_ZERO);
  728. ret +=
  729. unruly_solver_check_complete_nums(state, scratch->zeros_rows, true,
  730. scratch->ones_rows,
  731. scratch->ones_cols, N_ONE);
  732. ret +=
  733. unruly_solver_check_complete_nums(state, scratch->zeros_cols, false,
  734. scratch->ones_rows,
  735. scratch->ones_cols, N_ONE);
  736. return ret;
  737. }
  738. static int unruly_solver_check_near_complete(game_state *state,
  739. int *complete, bool horizontal,
  740. int *rowcount, int *colcount,
  741. char fill)
  742. {
  743. int w2 = state->w2, h2 = state->h2;
  744. int w = w2/2, h = h2/2;
  745. int dx = horizontal ? 1 : 0, dy = 1 - dx;
  746. int sx = dx, sy = dy;
  747. int ex = w2 - dx, ey = h2 - dy;
  748. int x, y;
  749. int ret = 0;
  750. /*
  751. * This function checks for a row with one Y remaining, then looks
  752. * for positions that could cause the remaining squares in the row
  753. * to make 3 X's in a row. Example:
  754. *
  755. * Consider the following row:
  756. * 1 1 0 . . .
  757. * If the last 1 was placed in the last square, the remaining
  758. * squares would be 0:
  759. * 1 1 0 0 0 1
  760. * This violates the 3 in a row rule. We now know that the last 1
  761. * shouldn't be in the last cell.
  762. * 1 1 0 . . 0
  763. */
  764. /* Check for any two blank and one filled square */
  765. for (y = sy; y < ey; y++) {
  766. /* One type must have 1 remaining, the other at least 2 */
  767. if (horizontal && (complete[y] < w - 1 || rowcount[y] > w - 2))
  768. continue;
  769. for (x = sx; x < ex; x++) {
  770. int i, i1, i2, i3;
  771. if (!horizontal
  772. && (complete[x] < h - 1 || colcount[x] > h - 2))
  773. continue;
  774. i = (horizontal ? y : x);
  775. i1 = (y-dy) * w2 + (x-dx);
  776. i2 = y * w2 + x;
  777. i3 = (y+dy) * w2 + (x+dx);
  778. if (state->grid[i1] == fill && state->grid[i2] == EMPTY
  779. && state->grid[i3] == EMPTY) {
  780. /*
  781. * Temporarily fill the empty spaces with something else.
  782. * This avoids raising the counts for the row and column
  783. */
  784. state->grid[i2] = BOGUS;
  785. state->grid[i3] = BOGUS;
  786. #ifdef STANDALONE_SOLVER
  787. if (solver_verbose) {
  788. printf("Solver: Row %i nearly satisfied for %c\n", i,
  789. (fill != N_ZERO ? '0' : '1'));
  790. }
  791. #endif
  792. ret +=
  793. unruly_solver_fill_row(state, i, horizontal, rowcount,
  794. colcount, fill);
  795. state->grid[i2] = EMPTY;
  796. state->grid[i3] = EMPTY;
  797. }
  798. else if (state->grid[i1] == EMPTY && state->grid[i2] == fill
  799. && state->grid[i3] == EMPTY) {
  800. state->grid[i1] = BOGUS;
  801. state->grid[i3] = BOGUS;
  802. #ifdef STANDALONE_SOLVER
  803. if (solver_verbose) {
  804. printf("Solver: Row %i nearly satisfied for %c\n", i,
  805. (fill != N_ZERO ? '0' : '1'));
  806. }
  807. #endif
  808. ret +=
  809. unruly_solver_fill_row(state, i, horizontal, rowcount,
  810. colcount, fill);
  811. state->grid[i1] = EMPTY;
  812. state->grid[i3] = EMPTY;
  813. }
  814. else if (state->grid[i1] == EMPTY && state->grid[i2] == EMPTY
  815. && state->grid[i3] == fill) {
  816. state->grid[i1] = BOGUS;
  817. state->grid[i2] = BOGUS;
  818. #ifdef STANDALONE_SOLVER
  819. if (solver_verbose) {
  820. printf("Solver: Row %i nearly satisfied for %c\n", i,
  821. (fill != N_ZERO ? '0' : '1'));
  822. }
  823. #endif
  824. ret +=
  825. unruly_solver_fill_row(state, i, horizontal, rowcount,
  826. colcount, fill);
  827. state->grid[i1] = EMPTY;
  828. state->grid[i2] = EMPTY;
  829. }
  830. else if (state->grid[i1] == EMPTY && state->grid[i2] == EMPTY
  831. && state->grid[i3] == EMPTY) {
  832. state->grid[i1] = BOGUS;
  833. state->grid[i2] = BOGUS;
  834. state->grid[i3] = BOGUS;
  835. #ifdef STANDALONE_SOLVER
  836. if (solver_verbose) {
  837. printf("Solver: Row %i nearly satisfied for %c\n", i,
  838. (fill != N_ZERO ? '0' : '1'));
  839. }
  840. #endif
  841. ret +=
  842. unruly_solver_fill_row(state, i, horizontal, rowcount,
  843. colcount, fill);
  844. state->grid[i1] = EMPTY;
  845. state->grid[i2] = EMPTY;
  846. state->grid[i3] = EMPTY;
  847. }
  848. }
  849. }
  850. return ret;
  851. }
  852. static int unruly_solver_check_all_near_complete(game_state *state,
  853. struct unruly_scratch *scratch)
  854. {
  855. int ret = 0;
  856. ret +=
  857. unruly_solver_check_near_complete(state, scratch->ones_rows, true,
  858. scratch->zeros_rows,
  859. scratch->zeros_cols, N_ZERO);
  860. ret +=
  861. unruly_solver_check_near_complete(state, scratch->ones_cols, false,
  862. scratch->zeros_rows,
  863. scratch->zeros_cols, N_ZERO);
  864. ret +=
  865. unruly_solver_check_near_complete(state, scratch->zeros_rows, true,
  866. scratch->ones_rows,
  867. scratch->ones_cols, N_ONE);
  868. ret +=
  869. unruly_solver_check_near_complete(state, scratch->zeros_cols, false,
  870. scratch->ones_rows,
  871. scratch->ones_cols, N_ONE);
  872. return ret;
  873. }
  874. static int unruly_validate_rows(const game_state *state, bool horizontal,
  875. char check, int *errors)
  876. {
  877. int w2 = state->w2, h2 = state->h2;
  878. int dx = horizontal ? 1 : 0, dy = 1 - dx;
  879. int sx = dx, sy = dy;
  880. int ex = w2 - dx, ey = h2 - dy;
  881. int x, y;
  882. int ret = 0;
  883. int err1 = (horizontal ? FE_HOR_ROW_LEFT : FE_VER_ROW_TOP);
  884. int err2 = (horizontal ? FE_HOR_ROW_MID : FE_VER_ROW_MID);
  885. int err3 = (horizontal ? FE_HOR_ROW_RIGHT : FE_VER_ROW_BOTTOM);
  886. /* Check for any three in a row, and mark errors accordingly (if
  887. * required) */
  888. for (y = sy; y < ey; y++) {
  889. for (x = sx; x < ex; x++) {
  890. int i1 = (y-dy) * w2 + (x-dx);
  891. int i2 = y * w2 + x;
  892. int i3 = (y+dy) * w2 + (x+dx);
  893. if (state->grid[i1] == check && state->grid[i2] == check
  894. && state->grid[i3] == check) {
  895. ret++;
  896. if (errors) {
  897. errors[i1] |= err1;
  898. errors[i2] |= err2;
  899. errors[i3] |= err3;
  900. }
  901. }
  902. }
  903. }
  904. return ret;
  905. }
  906. static int unruly_validate_unique(const game_state *state, bool horizontal,
  907. int *errors)
  908. {
  909. int w2 = state->w2, h2 = state->h2;
  910. int rmult = (horizontal ? w2 : 1);
  911. int cmult = (horizontal ? 1 : w2);
  912. int nr = (horizontal ? h2 : w2);
  913. int nc = (horizontal ? w2 : h2);
  914. int err = (horizontal ? FE_ROW_MATCH : FE_COL_MATCH);
  915. int r, r2, c;
  916. int ret = 0;
  917. /* Check for any two full rows matching exactly, and mark errors
  918. * accordingly (if required) */
  919. for (r = 0; r < nr; r++) {
  920. int nfull = 0;
  921. for (c = 0; c < nc; c++)
  922. if (state->grid[r*rmult + c*cmult] != EMPTY)
  923. nfull++;
  924. if (nfull != nc)
  925. continue;
  926. for (r2 = r+1; r2 < nr; r2++) {
  927. bool match = true;
  928. for (c = 0; c < nc; c++)
  929. if (state->grid[r*rmult + c*cmult] !=
  930. state->grid[r2*rmult + c*cmult])
  931. match = false;
  932. if (match) {
  933. if (errors) {
  934. for (c = 0; c < nc; c++) {
  935. errors[r*rmult + c*cmult] |= err;
  936. errors[r2*rmult + c*cmult] |= err;
  937. }
  938. }
  939. ret++;
  940. }
  941. }
  942. }
  943. return ret;
  944. }
  945. static int unruly_validate_all_rows(const game_state *state, int *errors)
  946. {
  947. int errcount = 0;
  948. errcount += unruly_validate_rows(state, true, N_ONE, errors);
  949. errcount += unruly_validate_rows(state, false, N_ONE, errors);
  950. errcount += unruly_validate_rows(state, true, N_ZERO, errors);
  951. errcount += unruly_validate_rows(state, false, N_ZERO, errors);
  952. if (state->unique) {
  953. errcount += unruly_validate_unique(state, true, errors);
  954. errcount += unruly_validate_unique(state, false, errors);
  955. }
  956. if (errcount)
  957. return -1;
  958. return 0;
  959. }
  960. static int unruly_validate_counts(const game_state *state,
  961. struct unruly_scratch *scratch, bool *errors)
  962. {
  963. int w2 = state->w2, h2 = state->h2;
  964. int w = w2/2, h = h2/2;
  965. bool below = false;
  966. bool above = false;
  967. int i;
  968. /* See if all rows/columns are satisfied. If one is exceeded,
  969. * mark it as an error (if required)
  970. */
  971. bool hasscratch = true;
  972. if (!scratch) {
  973. scratch = unruly_new_scratch(state);
  974. hasscratch = false;
  975. }
  976. for (i = 0; i < w2; i++) {
  977. if (scratch->ones_cols[i] < h)
  978. below = true;
  979. if (scratch->zeros_cols[i] < h)
  980. below = true;
  981. if (scratch->ones_cols[i] > h) {
  982. above = true;
  983. if (errors)
  984. errors[2*h2 + i] = true;
  985. } else if (errors)
  986. errors[2*h2 + i] = false;
  987. if (scratch->zeros_cols[i] > h) {
  988. above = true;
  989. if (errors)
  990. errors[2*h2 + w2 + i] = true;
  991. } else if (errors)
  992. errors[2*h2 + w2 + i] = false;
  993. }
  994. for (i = 0; i < h2; i++) {
  995. if (scratch->ones_rows[i] < w)
  996. below = true;
  997. if (scratch->zeros_rows[i] < w)
  998. below = true;
  999. if (scratch->ones_rows[i] > w) {
  1000. above = true;
  1001. if (errors)
  1002. errors[i] = true;
  1003. } else if (errors)
  1004. errors[i] = false;
  1005. if (scratch->zeros_rows[i] > w) {
  1006. above = true;
  1007. if (errors)
  1008. errors[h2 + i] = true;
  1009. } else if (errors)
  1010. errors[h2 + i] = false;
  1011. }
  1012. if (!hasscratch)
  1013. unruly_free_scratch(scratch);
  1014. return (above ? -1 : below ? 1 : 0);
  1015. }
  1016. static int unruly_solve_game(game_state *state,
  1017. struct unruly_scratch *scratch, int diff)
  1018. {
  1019. int done, maxdiff = -1;
  1020. while (true) {
  1021. done = 0;
  1022. /* Check for impending 3's */
  1023. done += unruly_solver_check_all_threes(state, scratch);
  1024. /* Keep using the simpler techniques while they produce results */
  1025. if (done) {
  1026. if (maxdiff < DIFF_TRIVIAL)
  1027. maxdiff = DIFF_TRIVIAL;
  1028. continue;
  1029. }
  1030. /* Check for rows with only one unfilled square */
  1031. done += unruly_solver_check_all_single_gap(state, scratch);
  1032. if (done) {
  1033. if (maxdiff < DIFF_TRIVIAL)
  1034. maxdiff = DIFF_TRIVIAL;
  1035. continue;
  1036. }
  1037. /* Easy techniques */
  1038. if (diff < DIFF_EASY)
  1039. break;
  1040. /* Check for completed rows */
  1041. done += unruly_solver_check_all_complete_nums(state, scratch);
  1042. if (done) {
  1043. if (maxdiff < DIFF_EASY)
  1044. maxdiff = DIFF_EASY;
  1045. continue;
  1046. }
  1047. /* Check for impending failures of row/column uniqueness, if
  1048. * it's enabled in this game mode */
  1049. if (state->unique) {
  1050. done += unruly_solver_check_all_uniques(state, scratch);
  1051. if (done) {
  1052. if (maxdiff < DIFF_EASY)
  1053. maxdiff = DIFF_EASY;
  1054. continue;
  1055. }
  1056. }
  1057. /* Normal techniques */
  1058. if (diff < DIFF_NORMAL)
  1059. break;
  1060. /* Check for nearly completed rows */
  1061. done += unruly_solver_check_all_near_complete(state, scratch);
  1062. if (done) {
  1063. if (maxdiff < DIFF_NORMAL)
  1064. maxdiff = DIFF_NORMAL;
  1065. continue;
  1066. }
  1067. break;
  1068. }
  1069. return maxdiff;
  1070. }
  1071. static char *solve_game(const game_state *state, const game_state *currstate,
  1072. const char *aux, const char **error)
  1073. {
  1074. game_state *solved = dup_game(state);
  1075. struct unruly_scratch *scratch = unruly_new_scratch(solved);
  1076. char *ret = NULL;
  1077. int result;
  1078. unruly_solve_game(solved, scratch, DIFFCOUNT);
  1079. result = unruly_validate_counts(solved, scratch, NULL);
  1080. if (unruly_validate_all_rows(solved, NULL) == -1)
  1081. result = -1;
  1082. if (result == 0) {
  1083. int w2 = solved->w2, h2 = solved->h2;
  1084. int s = w2 * h2;
  1085. char *p;
  1086. int i;
  1087. ret = snewn(s + 2, char);
  1088. p = ret;
  1089. *p++ = 'S';
  1090. for (i = 0; i < s; i++)
  1091. *p++ = (solved->grid[i] == N_ONE ? '1' : '0');
  1092. *p++ = '\0';
  1093. } else if (result == 1)
  1094. *error = "No solution found.";
  1095. else if (result == -1)
  1096. *error = "Puzzle is invalid.";
  1097. free_game(solved);
  1098. unruly_free_scratch(scratch);
  1099. return ret;
  1100. }
  1101. /* ********* *
  1102. * Generator *
  1103. * ********* */
  1104. static bool unruly_fill_game(game_state *state, struct unruly_scratch *scratch,
  1105. random_state *rs)
  1106. {
  1107. int w2 = state->w2, h2 = state->h2;
  1108. int s = w2 * h2;
  1109. int i, j;
  1110. int *spaces;
  1111. #ifdef STANDALONE_SOLVER
  1112. if (solver_verbose) {
  1113. printf("Generator: Attempt to fill grid\n");
  1114. }
  1115. #endif
  1116. /* Generate random array of spaces */
  1117. spaces = snewn(s, int);
  1118. for (i = 0; i < s; i++)
  1119. spaces[i] = i;
  1120. shuffle(spaces, s, sizeof(*spaces), rs);
  1121. /*
  1122. * Construct a valid filled grid by repeatedly picking an unfilled
  1123. * space and fill it, then calling the solver to fill in any
  1124. * spaces forced by the change.
  1125. */
  1126. for (j = 0; j < s; j++) {
  1127. i = spaces[j];
  1128. if (state->grid[i] != EMPTY)
  1129. continue;
  1130. if (random_upto(rs, 2)) {
  1131. state->grid[i] = N_ONE;
  1132. scratch->ones_rows[i / w2]++;
  1133. scratch->ones_cols[i % w2]++;
  1134. } else {
  1135. state->grid[i] = N_ZERO;
  1136. scratch->zeros_rows[i / w2]++;
  1137. scratch->zeros_cols[i % w2]++;
  1138. }
  1139. unruly_solve_game(state, scratch, DIFFCOUNT);
  1140. }
  1141. sfree(spaces);
  1142. if (unruly_validate_all_rows(state, NULL) != 0
  1143. || unruly_validate_counts(state, scratch, NULL) != 0)
  1144. return false;
  1145. return true;
  1146. }
  1147. static char *new_game_desc(const game_params *params, random_state *rs,
  1148. char **aux, bool interactive)
  1149. {
  1150. #ifdef STANDALONE_SOLVER
  1151. char *debug;
  1152. bool temp_verbose = false;
  1153. #endif
  1154. int w2 = params->w2, h2 = params->h2;
  1155. int s = w2 * h2;
  1156. int *spaces;
  1157. int i, j, run;
  1158. char *ret, *p;
  1159. game_state *state;
  1160. struct unruly_scratch *scratch;
  1161. int attempts = 0;
  1162. while (1) {
  1163. while (true) {
  1164. attempts++;
  1165. state = blank_state(w2, h2, params->unique, true);
  1166. scratch = unruly_new_scratch(state);
  1167. if (unruly_fill_game(state, scratch, rs))
  1168. break;
  1169. free_game(state);
  1170. unruly_free_scratch(scratch);
  1171. }
  1172. #ifdef STANDALONE_SOLVER
  1173. if (solver_verbose) {
  1174. printf("Puzzle generated in %i attempts\n", attempts);
  1175. debug = game_text_format(state);
  1176. fputs(debug, stdout);
  1177. sfree(debug);
  1178. temp_verbose = solver_verbose;
  1179. solver_verbose = false;
  1180. }
  1181. #else
  1182. (void)attempts;
  1183. #endif
  1184. unruly_free_scratch(scratch);
  1185. /* Generate random array of spaces */
  1186. spaces = snewn(s, int);
  1187. for (i = 0; i < s; i++)
  1188. spaces[i] = i;
  1189. shuffle(spaces, s, sizeof(*spaces), rs);
  1190. /*
  1191. * Winnow the clues by starting from our filled grid, repeatedly
  1192. * picking a filled space and emptying it, as long as the solver
  1193. * reports that the puzzle can still be solved after doing so.
  1194. */
  1195. for (j = 0; j < s; j++) {
  1196. char c;
  1197. game_state *solver;
  1198. i = spaces[j];
  1199. c = state->grid[i];
  1200. state->grid[i] = EMPTY;
  1201. solver = dup_game(state);
  1202. scratch = unruly_new_scratch(state);
  1203. unruly_solve_game(solver, scratch, params->diff);
  1204. if (unruly_validate_counts(solver, scratch, NULL) != 0)
  1205. state->grid[i] = c;
  1206. free_game(solver);
  1207. unruly_free_scratch(scratch);
  1208. }
  1209. sfree(spaces);
  1210. #ifdef STANDALONE_SOLVER
  1211. if (temp_verbose) {
  1212. solver_verbose = true;
  1213. printf("Final puzzle:\n");
  1214. debug = game_text_format(state);
  1215. fputs(debug, stdout);
  1216. sfree(debug);
  1217. }
  1218. #endif
  1219. /*
  1220. * See if the game has accidentally come out too easy.
  1221. */
  1222. if (params->diff > 0) {
  1223. bool ok;
  1224. game_state *solver;
  1225. solver = dup_game(state);
  1226. scratch = unruly_new_scratch(state);
  1227. unruly_solve_game(solver, scratch, params->diff - 1);
  1228. ok = unruly_validate_counts(solver, scratch, NULL) > 0;
  1229. free_game(solver);
  1230. unruly_free_scratch(scratch);
  1231. if (ok)
  1232. break;
  1233. } else {
  1234. /*
  1235. * Puzzles of the easiest difficulty can't be too easy.
  1236. */
  1237. break;
  1238. }
  1239. }
  1240. /* Encode description */
  1241. ret = snewn(s + 1, char);
  1242. p = ret;
  1243. run = 0;
  1244. for (i = 0; i < s+1; i++) {
  1245. if (i == s || state->grid[i] == N_ZERO) {
  1246. while (run > 24) {
  1247. *p++ = 'z';
  1248. run -= 25;
  1249. }
  1250. *p++ = 'a' + run;
  1251. run = 0;
  1252. } else if (state->grid[i] == N_ONE) {
  1253. while (run > 24) {
  1254. *p++ = 'Z';
  1255. run -= 25;
  1256. }
  1257. *p++ = 'A' + run;
  1258. run = 0;
  1259. } else {
  1260. run++;
  1261. }
  1262. }
  1263. *p = '\0';
  1264. free_game(state);
  1265. return ret;
  1266. }
  1267. /* ************** *
  1268. * User Interface *
  1269. * ************** */
  1270. struct game_ui {
  1271. int cx, cy;
  1272. bool cursor;
  1273. };
  1274. static game_ui *new_ui(const game_state *state)
  1275. {
  1276. game_ui *ret = snew(game_ui);
  1277. ret->cx = ret->cy = 0;
  1278. ret->cursor = getenv_bool("PUZZLES_SHOW_CURSOR", false);
  1279. return ret;
  1280. }
  1281. static void free_ui(game_ui *ui)
  1282. {
  1283. sfree(ui);
  1284. }
  1285. static void game_changed_state(game_ui *ui, const game_state *oldstate,
  1286. const game_state *newstate)
  1287. {
  1288. }
  1289. static const char *current_key_label(const game_ui *ui,
  1290. const game_state *state, int button)
  1291. {
  1292. int hx = ui->cx, hy = ui->cy;
  1293. int w2 = state->w2;
  1294. char i = state->grid[hy * w2 + hx];
  1295. if (ui->cursor && IS_CURSOR_SELECT(button)) {
  1296. if (state->common->immutable[hy * w2 + hx]) return "";
  1297. switch (i) {
  1298. case EMPTY:
  1299. return button == CURSOR_SELECT ? "Black" : "White";
  1300. case N_ONE:
  1301. return button == CURSOR_SELECT ? "White" : "Empty";
  1302. case N_ZERO:
  1303. return button == CURSOR_SELECT ? "Empty" : "Black";
  1304. }
  1305. }
  1306. return "";
  1307. }
  1308. struct game_drawstate {
  1309. int tilesize;
  1310. int w2, h2;
  1311. bool started;
  1312. int *gridfs;
  1313. bool *rowfs;
  1314. int *grid;
  1315. };
  1316. static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
  1317. {
  1318. struct game_drawstate *ds = snew(struct game_drawstate);
  1319. int w2 = state->w2, h2 = state->h2;
  1320. int s = w2 * h2;
  1321. int i;
  1322. ds->tilesize = 0;
  1323. ds->w2 = w2;
  1324. ds->h2 = h2;
  1325. ds->started = false;
  1326. ds->gridfs = snewn(s, int);
  1327. ds->rowfs = snewn(2 * (w2 + h2), bool);
  1328. ds->grid = snewn(s, int);
  1329. for (i = 0; i < s; i++)
  1330. ds->grid[i] = -1;
  1331. return ds;
  1332. }
  1333. static void game_free_drawstate(drawing *dr, game_drawstate *ds)
  1334. {
  1335. sfree(ds->gridfs);
  1336. sfree(ds->rowfs);
  1337. sfree(ds->grid);
  1338. sfree(ds);
  1339. }
  1340. #define COORD(x) ( (x) * ds->tilesize + ds->tilesize/2 )
  1341. #define FROMCOORD(x) ( ((x)-(ds->tilesize/2)) / ds->tilesize )
  1342. static char *interpret_move(const game_state *state, game_ui *ui,
  1343. const game_drawstate *ds,
  1344. int ox, int oy, int button)
  1345. {
  1346. int hx = ui->cx;
  1347. int hy = ui->cy;
  1348. int gx = FROMCOORD(ox);
  1349. int gy = FROMCOORD(oy);
  1350. int w2 = state->w2, h2 = state->h2;
  1351. button &= ~MOD_MASK;
  1352. /* Mouse click */
  1353. if (button == LEFT_BUTTON || button == RIGHT_BUTTON ||
  1354. button == MIDDLE_BUTTON) {
  1355. if (ox >= (ds->tilesize / 2) && gx < w2
  1356. && oy >= (ds->tilesize / 2) && gy < h2) {
  1357. hx = gx;
  1358. hy = gy;
  1359. ui->cursor = false;
  1360. } else
  1361. return NULL;
  1362. }
  1363. /* Keyboard move */
  1364. if (IS_CURSOR_MOVE(button)) {
  1365. move_cursor(button, &ui->cx, &ui->cy, w2, h2, false);
  1366. ui->cursor = true;
  1367. return MOVE_UI_UPDATE;
  1368. }
  1369. /* Place one */
  1370. if ((ui->cursor && (button == CURSOR_SELECT || button == CURSOR_SELECT2
  1371. || button == '\b' || button == '0' || button == '1'
  1372. || button == '2')) ||
  1373. button == LEFT_BUTTON || button == RIGHT_BUTTON ||
  1374. button == MIDDLE_BUTTON) {
  1375. char buf[80];
  1376. char c, i;
  1377. if (state->common->immutable[hy * w2 + hx])
  1378. return NULL;
  1379. c = '-';
  1380. i = state->grid[hy * w2 + hx];
  1381. if (button == '0' || button == '2')
  1382. c = '0';
  1383. else if (button == '1')
  1384. c = '1';
  1385. else if (button == MIDDLE_BUTTON)
  1386. c = '-';
  1387. /* Cycle through options */
  1388. else if (button == CURSOR_SELECT2 || button == RIGHT_BUTTON)
  1389. c = (i == EMPTY ? '0' : i == N_ZERO ? '1' : '-');
  1390. else if (button == CURSOR_SELECT || button == LEFT_BUTTON)
  1391. c = (i == EMPTY ? '1' : i == N_ONE ? '0' : '-');
  1392. if (state->grid[hy * w2 + hx] ==
  1393. (c == '0' ? N_ZERO : c == '1' ? N_ONE : EMPTY))
  1394. return NULL; /* don't put no-ops on the undo chain */
  1395. sprintf(buf, "P%c,%d,%d", c, hx, hy);
  1396. return dupstr(buf);
  1397. }
  1398. return NULL;
  1399. }
  1400. static game_state *execute_move(const game_state *state, const char *move)
  1401. {
  1402. int w2 = state->w2, h2 = state->h2;
  1403. int s = w2 * h2;
  1404. int x, y, i;
  1405. char c;
  1406. game_state *ret;
  1407. if (move[0] == 'S') {
  1408. const char *p;
  1409. ret = dup_game(state);
  1410. p = move + 1;
  1411. for (i = 0; i < s; i++) {
  1412. if (!*p || !(*p == '1' || *p == '0')) {
  1413. free_game(ret);
  1414. return NULL;
  1415. }
  1416. ret->grid[i] = (*p == '1' ? N_ONE : N_ZERO);
  1417. p++;
  1418. }
  1419. ret->completed = ret->cheated = true;
  1420. return ret;
  1421. } else if (move[0] == 'P'
  1422. && sscanf(move + 1, "%c,%d,%d", &c, &x, &y) == 3 && x >= 0
  1423. && x < w2 && y >= 0 && y < h2 && (c == '-' || c == '0'
  1424. || c == '1')) {
  1425. ret = dup_game(state);
  1426. i = y * w2 + x;
  1427. if (state->common->immutable[i]) {
  1428. free_game(ret);
  1429. return NULL;
  1430. }
  1431. ret->grid[i] = (c == '1' ? N_ONE : c == '0' ? N_ZERO : EMPTY);
  1432. if (!ret->completed && unruly_validate_counts(ret, NULL, NULL) == 0
  1433. && (unruly_validate_all_rows(ret, NULL) == 0))
  1434. ret->completed = true;
  1435. return ret;
  1436. }
  1437. return NULL;
  1438. }
  1439. /* ----------------------------------------------------------------------
  1440. * Drawing routines.
  1441. */
  1442. static void game_compute_size(const game_params *params, int tilesize,
  1443. const game_ui *ui, int *x, int *y)
  1444. {
  1445. *x = tilesize * (params->w2 + 1);
  1446. *y = tilesize * (params->h2 + 1);
  1447. }
  1448. static void game_set_size(drawing *dr, game_drawstate *ds,
  1449. const game_params *params, int tilesize)
  1450. {
  1451. ds->tilesize = tilesize;
  1452. }
  1453. static float *game_colours(frontend *fe, int *ncolours)
  1454. {
  1455. float *ret = snewn(3 * NCOLOURS, float);
  1456. int i;
  1457. frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
  1458. for (i = 0; i < 3; i++) {
  1459. ret[COL_1 * 3 + i] = 0.2F;
  1460. ret[COL_1_HIGHLIGHT * 3 + i] = 0.4F;
  1461. ret[COL_1_LOWLIGHT * 3 + i] = 0.0F;
  1462. ret[COL_0 * 3 + i] = 0.95F;
  1463. ret[COL_0_HIGHLIGHT * 3 + i] = 1.0F;
  1464. ret[COL_0_LOWLIGHT * 3 + i] = 0.9F;
  1465. ret[COL_EMPTY * 3 + i] = 0.5F;
  1466. ret[COL_GRID * 3 + i] = 0.3F;
  1467. }
  1468. game_mkhighlight_specific(fe, ret, COL_0, COL_0_HIGHLIGHT, COL_0_LOWLIGHT);
  1469. game_mkhighlight_specific(fe, ret, COL_1, COL_1_HIGHLIGHT, COL_1_LOWLIGHT);
  1470. ret[COL_ERROR * 3 + 0] = 1.0F;
  1471. ret[COL_ERROR * 3 + 1] = 0.0F;
  1472. ret[COL_ERROR * 3 + 2] = 0.0F;
  1473. ret[COL_CURSOR * 3 + 0] = 0.0F;
  1474. ret[COL_CURSOR * 3 + 1] = 0.7F;
  1475. ret[COL_CURSOR * 3 + 2] = 0.0F;
  1476. *ncolours = NCOLOURS;
  1477. return ret;
  1478. }
  1479. static void unruly_draw_err_rectangle(drawing *dr, int x, int y, int w, int h,
  1480. int tilesize)
  1481. {
  1482. double thick = tilesize / 10;
  1483. double margin = tilesize / 20;
  1484. draw_rect(dr, x+margin, y+margin, w-2*margin, thick, COL_ERROR);
  1485. draw_rect(dr, x+margin, y+margin, thick, h-2*margin, COL_ERROR);
  1486. draw_rect(dr, x+margin, y+h-margin-thick, w-2*margin, thick, COL_ERROR);
  1487. draw_rect(dr, x+w-margin-thick, y+margin, thick, h-2*margin, COL_ERROR);
  1488. }
  1489. static void unruly_draw_tile(drawing *dr, int x, int y, int tilesize, int tile)
  1490. {
  1491. clip(dr, x, y, tilesize, tilesize);
  1492. /* Draw the grid edge first, so the tile can overwrite it */
  1493. draw_rect(dr, x, y, tilesize, tilesize, COL_GRID);
  1494. /* Background of the tile */
  1495. {
  1496. int val = (tile & FF_ZERO ? 0 : tile & FF_ONE ? 2 : 1);
  1497. val = (val == 0 ? COL_0 : val == 2 ? COL_1 : COL_EMPTY);
  1498. if ((tile & (FF_FLASH1 | FF_FLASH2)) &&
  1499. (val == COL_0 || val == COL_1)) {
  1500. val += (tile & FF_FLASH1 ? 1 : 2);
  1501. }
  1502. draw_rect(dr, x, y, tilesize-1, tilesize-1, val);
  1503. if ((val == COL_0 || val == COL_1) && (tile & FF_IMMUTABLE)) {
  1504. draw_rect(dr, x + tilesize/6, y + tilesize/6,
  1505. tilesize - 2*(tilesize/6) - 2, 1, val + 2);
  1506. draw_rect(dr, x + tilesize/6, y + tilesize/6,
  1507. 1, tilesize - 2*(tilesize/6) - 2, val + 2);
  1508. draw_rect(dr, x + tilesize/6 + 1, y + tilesize - tilesize/6 - 2,
  1509. tilesize - 2*(tilesize/6) - 2, 1, val + 1);
  1510. draw_rect(dr, x + tilesize - tilesize/6 - 2, y + tilesize/6 + 1,
  1511. 1, tilesize - 2*(tilesize/6) - 2, val + 1);
  1512. }
  1513. }
  1514. /* 3-in-a-row errors */
  1515. if (tile & (FE_HOR_ROW_LEFT | FE_HOR_ROW_RIGHT)) {
  1516. int left = x, right = x + tilesize - 1;
  1517. if ((tile & FE_HOR_ROW_LEFT))
  1518. right += tilesize/2;
  1519. if ((tile & FE_HOR_ROW_RIGHT))
  1520. left -= tilesize/2;
  1521. unruly_draw_err_rectangle(dr, left, y, right-left, tilesize-1, tilesize);
  1522. }
  1523. if (tile & (FE_VER_ROW_TOP | FE_VER_ROW_BOTTOM)) {
  1524. int top = y, bottom = y + tilesize - 1;
  1525. if ((tile & FE_VER_ROW_TOP))
  1526. bottom += tilesize/2;
  1527. if ((tile & FE_VER_ROW_BOTTOM))
  1528. top -= tilesize/2;
  1529. unruly_draw_err_rectangle(dr, x, top, tilesize-1, bottom-top, tilesize);
  1530. }
  1531. /* Count errors */
  1532. if (tile & FE_COUNT) {
  1533. draw_text(dr, x + tilesize/2, y + tilesize/2, FONT_VARIABLE,
  1534. tilesize/2, ALIGN_HCENTRE | ALIGN_VCENTRE, COL_ERROR, "!");
  1535. }
  1536. /* Row-match errors */
  1537. if (tile & FE_ROW_MATCH) {
  1538. draw_rect(dr, x, y+tilesize/2-tilesize/12,
  1539. tilesize, 2*(tilesize/12), COL_ERROR);
  1540. }
  1541. if (tile & FE_COL_MATCH) {
  1542. draw_rect(dr, x+tilesize/2-tilesize/12, y,
  1543. 2*(tilesize/12), tilesize, COL_ERROR);
  1544. }
  1545. /* Cursor rectangle */
  1546. if (tile & FF_CURSOR) {
  1547. draw_rect(dr, x, y, tilesize/12, tilesize-1, COL_CURSOR);
  1548. draw_rect(dr, x, y, tilesize-1, tilesize/12, COL_CURSOR);
  1549. draw_rect(dr, x+tilesize-1-tilesize/12, y, tilesize/12, tilesize-1,
  1550. COL_CURSOR);
  1551. draw_rect(dr, x, y+tilesize-1-tilesize/12, tilesize-1, tilesize/12,
  1552. COL_CURSOR);
  1553. }
  1554. unclip(dr);
  1555. draw_update(dr, x, y, tilesize, tilesize);
  1556. }
  1557. #define TILE_SIZE (ds->tilesize)
  1558. #define DEFAULT_TILE_SIZE 32
  1559. #define FLASH_FRAME 0.12F
  1560. #define FLASH_TIME (FLASH_FRAME * 3)
  1561. static void game_redraw(drawing *dr, game_drawstate *ds,
  1562. const game_state *oldstate, const game_state *state,
  1563. int dir, const game_ui *ui,
  1564. float animtime, float flashtime)
  1565. {
  1566. int w2 = state->w2, h2 = state->h2;
  1567. int s = w2 * h2;
  1568. int flash;
  1569. int x, y, i;
  1570. if (!ds->started) {
  1571. /* Outer edge of grid */
  1572. draw_rect(dr, COORD(0)-TILE_SIZE/10, COORD(0)-TILE_SIZE/10,
  1573. TILE_SIZE*w2 + 2*(TILE_SIZE/10) - 1,
  1574. TILE_SIZE*h2 + 2*(TILE_SIZE/10) - 1, COL_GRID);
  1575. draw_update(dr, 0, 0, TILE_SIZE * (w2+1), TILE_SIZE * (h2+1));
  1576. ds->started = true;
  1577. }
  1578. flash = 0;
  1579. if (flashtime > 0)
  1580. flash = (int)(flashtime / FLASH_FRAME) == 1 ? FF_FLASH2 : FF_FLASH1;
  1581. for (i = 0; i < s; i++)
  1582. ds->gridfs[i] = 0;
  1583. unruly_validate_all_rows(state, ds->gridfs);
  1584. for (i = 0; i < 2 * (h2 + w2); i++)
  1585. ds->rowfs[i] = false;
  1586. unruly_validate_counts(state, NULL, ds->rowfs);
  1587. for (y = 0; y < h2; y++) {
  1588. for (x = 0; x < w2; x++) {
  1589. int tile;
  1590. i = y * w2 + x;
  1591. tile = ds->gridfs[i];
  1592. if (state->grid[i] == N_ONE) {
  1593. tile |= FF_ONE;
  1594. if (ds->rowfs[y] || ds->rowfs[2*h2 + x])
  1595. tile |= FE_COUNT;
  1596. } else if (state->grid[i] == N_ZERO) {
  1597. tile |= FF_ZERO;
  1598. if (ds->rowfs[h2 + y] || ds->rowfs[2*h2 + w2 + x])
  1599. tile |= FE_COUNT;
  1600. }
  1601. tile |= flash;
  1602. if (state->common->immutable[i])
  1603. tile |= FF_IMMUTABLE;
  1604. if (ui->cursor && ui->cx == x && ui->cy == y)
  1605. tile |= FF_CURSOR;
  1606. if (ds->grid[i] != tile) {
  1607. ds->grid[i] = tile;
  1608. unruly_draw_tile(dr, COORD(x), COORD(y), TILE_SIZE, tile);
  1609. }
  1610. }
  1611. }
  1612. }
  1613. static float game_anim_length(const game_state *oldstate,
  1614. const game_state *newstate, int dir, game_ui *ui)
  1615. {
  1616. return 0.0F;
  1617. }
  1618. static float game_flash_length(const game_state *oldstate,
  1619. const game_state *newstate, int dir, game_ui *ui)
  1620. {
  1621. if (!oldstate->completed && newstate->completed &&
  1622. !oldstate->cheated && !newstate->cheated)
  1623. return FLASH_TIME;
  1624. return 0.0F;
  1625. }
  1626. static void game_get_cursor_location(const game_ui *ui,
  1627. const game_drawstate *ds,
  1628. const game_state *state,
  1629. const game_params *params,
  1630. int *x, int *y, int *w, int *h)
  1631. {
  1632. if(ui->cursor) {
  1633. *x = COORD(ui->cx);
  1634. *y = COORD(ui->cy);
  1635. *w = *h = TILE_SIZE;
  1636. }
  1637. }
  1638. static int game_status(const game_state *state)
  1639. {
  1640. return state->completed ? +1 : 0;
  1641. }
  1642. static void game_print_size(const game_params *params, const game_ui *ui,
  1643. float *x, float *y)
  1644. {
  1645. int pw, ph;
  1646. /* Using 7mm squares */
  1647. game_compute_size(params, 700, ui, &pw, &ph);
  1648. *x = pw / 100.0F;
  1649. *y = ph / 100.0F;
  1650. }
  1651. static void game_print(drawing *dr, const game_state *state, const game_ui *ui,
  1652. int tilesize)
  1653. {
  1654. int w2 = state->w2, h2 = state->h2;
  1655. int x, y;
  1656. int ink = print_mono_colour(dr, 0);
  1657. for (y = 0; y < h2; y++)
  1658. for (x = 0; x < w2; x++) {
  1659. int tx = x * tilesize + (tilesize / 2);
  1660. int ty = y * tilesize + (tilesize / 2);
  1661. /* Draw the border */
  1662. int coords[8];
  1663. coords[0] = tx;
  1664. coords[1] = ty - 1;
  1665. coords[2] = tx + tilesize;
  1666. coords[3] = ty - 1;
  1667. coords[4] = tx + tilesize;
  1668. coords[5] = ty + tilesize - 1;
  1669. coords[6] = tx;
  1670. coords[7] = ty + tilesize - 1;
  1671. draw_polygon(dr, coords, 4, -1, ink);
  1672. if (state->grid[y * w2 + x] == N_ONE)
  1673. draw_rect(dr, tx, ty, tilesize, tilesize, ink);
  1674. else if (state->grid[y * w2 + x] == N_ZERO)
  1675. draw_circle(dr, tx + tilesize/2, ty + tilesize/2,
  1676. tilesize/12, ink, ink);
  1677. }
  1678. }
  1679. #ifdef COMBINED
  1680. #define thegame unruly
  1681. #endif
  1682. const struct game thegame = {
  1683. "Unruly", "games.unruly", "unruly",
  1684. default_params,
  1685. game_fetch_preset, NULL,
  1686. decode_params,
  1687. encode_params,
  1688. free_params,
  1689. dup_params,
  1690. true, game_configure, custom_params,
  1691. validate_params,
  1692. new_game_desc,
  1693. validate_desc,
  1694. new_game,
  1695. dup_game,
  1696. free_game,
  1697. true, solve_game,
  1698. true, game_can_format_as_text_now, game_text_format,
  1699. NULL, NULL, /* get_prefs, set_prefs */
  1700. new_ui,
  1701. free_ui,
  1702. NULL, /* encode_ui */
  1703. NULL, /* decode_ui */
  1704. NULL, /* game_request_keys */
  1705. game_changed_state,
  1706. current_key_label,
  1707. interpret_move,
  1708. execute_move,
  1709. DEFAULT_TILE_SIZE, game_compute_size, game_set_size,
  1710. game_colours,
  1711. game_new_drawstate,
  1712. game_free_drawstate,
  1713. game_redraw,
  1714. game_anim_length,
  1715. game_flash_length,
  1716. game_get_cursor_location,
  1717. game_status,
  1718. true, false, game_print_size, game_print,
  1719. false, /* wants_statusbar */
  1720. false, NULL, /* timing_state */
  1721. 0, /* flags */
  1722. };
  1723. /* ***************** *
  1724. * Standalone solver *
  1725. * ***************** */
  1726. #ifdef STANDALONE_SOLVER
  1727. #include <time.h>
  1728. #include <stdarg.h>
  1729. /* Most of the standalone solver code was copied from unequal.c and singles.c */
  1730. static const char *quis;
  1731. static void usage_exit(const char *msg)
  1732. {
  1733. if (msg)
  1734. fprintf(stderr, "%s: %s\n", quis, msg);
  1735. fprintf(stderr,
  1736. "Usage: %s [-v] [--seed SEED] <params> | [game_id [game_id ...]]\n",
  1737. quis);
  1738. exit(1);
  1739. }
  1740. int main(int argc, char *argv[])
  1741. {
  1742. random_state *rs;
  1743. time_t seed = time(NULL);
  1744. game_params *params = NULL;
  1745. char *id = NULL, *desc = NULL;
  1746. const char *err;
  1747. quis = argv[0];
  1748. while (--argc > 0) {
  1749. char *p = *++argv;
  1750. if (!strcmp(p, "--seed")) {
  1751. if (argc == 0)
  1752. usage_exit("--seed needs an argument");
  1753. seed = (time_t) atoi(*++argv);
  1754. argc--;
  1755. } else if (!strcmp(p, "-v"))
  1756. solver_verbose = true;
  1757. else if (*p == '-')
  1758. usage_exit("unrecognised option");
  1759. else
  1760. id = p;
  1761. }
  1762. if (id) {
  1763. desc = strchr(id, ':');
  1764. if (desc)
  1765. *desc++ = '\0';
  1766. params = default_params();
  1767. decode_params(params, id);
  1768. err = validate_params(params, true);
  1769. if (err) {
  1770. fprintf(stderr, "Parameters are invalid\n");
  1771. fprintf(stderr, "%s: %s", argv[0], err);
  1772. exit(1);
  1773. }
  1774. }
  1775. if (!desc) {
  1776. char *desc_gen, *aux;
  1777. rs = random_new((void *) &seed, sizeof(time_t));
  1778. if (!params)
  1779. params = default_params();
  1780. printf("Generating puzzle with parameters %s\n",
  1781. encode_params(params, true));
  1782. desc_gen = new_game_desc(params, rs, &aux, false);
  1783. if (!solver_verbose) {
  1784. char *fmt = game_text_format(new_game(NULL, params, desc_gen));
  1785. fputs(fmt, stdout);
  1786. sfree(fmt);
  1787. }
  1788. printf("Game ID: %s\n", desc_gen);
  1789. } else {
  1790. game_state *input;
  1791. struct unruly_scratch *scratch;
  1792. int maxdiff, errcode;
  1793. err = validate_desc(params, desc);
  1794. if (err) {
  1795. fprintf(stderr, "Description is invalid\n");
  1796. fprintf(stderr, "%s", err);
  1797. exit(1);
  1798. }
  1799. input = new_game(NULL, params, desc);
  1800. scratch = unruly_new_scratch(input);
  1801. maxdiff = unruly_solve_game(input, scratch, DIFFCOUNT);
  1802. errcode = unruly_validate_counts(input, scratch, NULL);
  1803. if (unruly_validate_all_rows(input, NULL) == -1)
  1804. errcode = -1;
  1805. if (errcode != -1) {
  1806. char *fmt = game_text_format(input);
  1807. fputs(fmt, stdout);
  1808. sfree(fmt);
  1809. if (maxdiff < 0)
  1810. printf("Difficulty: already solved!\n");
  1811. else
  1812. printf("Difficulty: %s\n", unruly_diffnames[maxdiff]);
  1813. }
  1814. if (errcode == 1)
  1815. printf("No solution found.\n");
  1816. else if (errcode == -1)
  1817. printf("Puzzle is invalid.\n");
  1818. free_game(input);
  1819. unruly_free_scratch(scratch);
  1820. }
  1821. return 0;
  1822. }
  1823. #endif