map.c 93 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455
  1. /*
  2. * map.c: Game involving four-colouring a map.
  3. */
  4. /*
  5. * TODO:
  6. *
  7. * - clue marking
  8. * - better four-colouring algorithm?
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <assert.h>
  14. #include <ctype.h>
  15. #include <limits.h>
  16. #ifdef NO_TGMATH_H
  17. # include <math.h>
  18. #else
  19. # include <tgmath.h>
  20. #endif
  21. #include "puzzles.h"
  22. /*
  23. * In standalone solver mode, `verbose' is a variable which can be
  24. * set by command-line option; in debugging mode it's simply always
  25. * true.
  26. */
  27. #if defined STANDALONE_SOLVER
  28. #define SOLVER_DIAGNOSTICS
  29. static bool verbose = false;
  30. #elif defined SOLVER_DIAGNOSTICS
  31. #define verbose true
  32. #endif
  33. /*
  34. * I don't seriously anticipate wanting to change the number of
  35. * colours used in this game, but it doesn't cost much to use a
  36. * #define just in case :-)
  37. */
  38. #define FOUR 4
  39. #define THREE (FOUR-1)
  40. #define FIVE (FOUR+1)
  41. #define SIX (FOUR+2)
  42. /*
  43. * Difficulty levels. I do some macro ickery here to ensure that my
  44. * enum and the various forms of my name list always match up.
  45. */
  46. #define DIFFLIST(A) \
  47. A(EASY,Easy,e) \
  48. A(NORMAL,Normal,n) \
  49. A(HARD,Hard,h) \
  50. A(RECURSE,Unreasonable,u)
  51. #define ENUM(upper,title,lower) DIFF_ ## upper,
  52. #define TITLE(upper,title,lower) #title,
  53. #define ENCODE(upper,title,lower) #lower
  54. #define CONFIG(upper,title,lower) ":" #title
  55. enum { DIFFLIST(ENUM) DIFFCOUNT };
  56. static char const *const map_diffnames[] = { DIFFLIST(TITLE) };
  57. static char const map_diffchars[] = DIFFLIST(ENCODE);
  58. #define DIFFCONFIG DIFFLIST(CONFIG)
  59. enum { TE, BE, LE, RE }; /* top/bottom/left/right edges */
  60. enum {
  61. COL_BACKGROUND,
  62. COL_GRID,
  63. COL_0, COL_1, COL_2, COL_3,
  64. COL_ERROR, COL_ERRTEXT,
  65. NCOLOURS
  66. };
  67. struct game_params {
  68. int w, h, n, diff;
  69. };
  70. struct map {
  71. int refcount;
  72. int *map;
  73. int *graph;
  74. int n;
  75. int ngraph;
  76. bool *immutable;
  77. int *edgex, *edgey; /* position of a point on each edge */
  78. int *regionx, *regiony; /* position of a point in each region */
  79. };
  80. struct game_state {
  81. game_params p;
  82. struct map *map;
  83. int *colouring, *pencil;
  84. bool completed, cheated;
  85. };
  86. static game_params *default_params(void)
  87. {
  88. game_params *ret = snew(game_params);
  89. #ifdef PORTRAIT_SCREEN
  90. ret->w = 16;
  91. ret->h = 18;
  92. #else
  93. ret->w = 20;
  94. ret->h = 15;
  95. #endif
  96. ret->n = 30;
  97. ret->diff = DIFF_NORMAL;
  98. return ret;
  99. }
  100. static const struct game_params map_presets[] = {
  101. #ifdef PORTRAIT_SCREEN
  102. {16, 18, 30, DIFF_EASY},
  103. {16, 18, 30, DIFF_NORMAL},
  104. {16, 18, 30, DIFF_HARD},
  105. {16, 18, 30, DIFF_RECURSE},
  106. {25, 30, 75, DIFF_NORMAL},
  107. {25, 30, 75, DIFF_HARD},
  108. #else
  109. {20, 15, 30, DIFF_EASY},
  110. {20, 15, 30, DIFF_NORMAL},
  111. {20, 15, 30, DIFF_HARD},
  112. {20, 15, 30, DIFF_RECURSE},
  113. {30, 25, 75, DIFF_NORMAL},
  114. {30, 25, 75, DIFF_HARD},
  115. #endif
  116. };
  117. static bool game_fetch_preset(int i, char **name, game_params **params)
  118. {
  119. game_params *ret;
  120. char str[80];
  121. if (i < 0 || i >= lenof(map_presets))
  122. return false;
  123. ret = snew(game_params);
  124. *ret = map_presets[i];
  125. sprintf(str, "%dx%d, %d regions, %s", ret->w, ret->h, ret->n,
  126. map_diffnames[ret->diff]);
  127. *name = dupstr(str);
  128. *params = ret;
  129. return true;
  130. }
  131. static void free_params(game_params *params)
  132. {
  133. sfree(params);
  134. }
  135. static game_params *dup_params(const game_params *params)
  136. {
  137. game_params *ret = snew(game_params);
  138. *ret = *params; /* structure copy */
  139. return ret;
  140. }
  141. static void decode_params(game_params *params, char const *string)
  142. {
  143. char const *p = string;
  144. params->w = atoi(p);
  145. while (*p && isdigit((unsigned char)*p)) p++;
  146. if (*p == 'x') {
  147. p++;
  148. params->h = atoi(p);
  149. while (*p && isdigit((unsigned char)*p)) p++;
  150. } else {
  151. params->h = params->w;
  152. }
  153. if (*p == 'n') {
  154. p++;
  155. params->n = atoi(p);
  156. while (*p && (*p == '.' || isdigit((unsigned char)*p))) p++;
  157. } else {
  158. if (params->h > 0 && params->w > 0 &&
  159. params->w <= INT_MAX / params->h)
  160. params->n = params->w * params->h / 8;
  161. }
  162. if (*p == 'd') {
  163. int i;
  164. p++;
  165. for (i = 0; i < DIFFCOUNT; i++)
  166. if (*p == map_diffchars[i])
  167. params->diff = i;
  168. if (*p) p++;
  169. }
  170. }
  171. static char *encode_params(const game_params *params, bool full)
  172. {
  173. char ret[400];
  174. sprintf(ret, "%dx%dn%d", params->w, params->h, params->n);
  175. if (full)
  176. sprintf(ret + strlen(ret), "d%c", map_diffchars[params->diff]);
  177. return dupstr(ret);
  178. }
  179. static config_item *game_configure(const game_params *params)
  180. {
  181. config_item *ret;
  182. char buf[80];
  183. ret = snewn(5, config_item);
  184. ret[0].name = "Width";
  185. ret[0].type = C_STRING;
  186. sprintf(buf, "%d", params->w);
  187. ret[0].u.string.sval = dupstr(buf);
  188. ret[1].name = "Height";
  189. ret[1].type = C_STRING;
  190. sprintf(buf, "%d", params->h);
  191. ret[1].u.string.sval = dupstr(buf);
  192. ret[2].name = "Regions";
  193. ret[2].type = C_STRING;
  194. sprintf(buf, "%d", params->n);
  195. ret[2].u.string.sval = dupstr(buf);
  196. ret[3].name = "Difficulty";
  197. ret[3].type = C_CHOICES;
  198. ret[3].u.choices.choicenames = DIFFCONFIG;
  199. ret[3].u.choices.selected = params->diff;
  200. ret[4].name = NULL;
  201. ret[4].type = C_END;
  202. return ret;
  203. }
  204. static game_params *custom_params(const config_item *cfg)
  205. {
  206. game_params *ret = snew(game_params);
  207. ret->w = atoi(cfg[0].u.string.sval);
  208. ret->h = atoi(cfg[1].u.string.sval);
  209. ret->n = atoi(cfg[2].u.string.sval);
  210. ret->diff = cfg[3].u.choices.selected;
  211. return ret;
  212. }
  213. static const char *validate_params(const game_params *params, bool full)
  214. {
  215. if (params->w < 2 || params->h < 2)
  216. return "Width and height must be at least two";
  217. if (params->w > INT_MAX / 2 / params->h)
  218. return "Width times height must not be unreasonably large";
  219. if (params->n < 5)
  220. return "Must have at least five regions";
  221. if (params->n > params->w * params->h)
  222. return "Too many regions to fit in grid";
  223. return NULL;
  224. }
  225. /* ----------------------------------------------------------------------
  226. * Cumulative frequency table functions.
  227. */
  228. /*
  229. * Initialise a cumulative frequency table. (Hardly worth writing
  230. * this function; all it does is to initialise everything in the
  231. * array to zero.)
  232. */
  233. static void cf_init(int *table, int n)
  234. {
  235. int i;
  236. for (i = 0; i < n; i++)
  237. table[i] = 0;
  238. }
  239. /*
  240. * Increment the count of symbol `sym' by `count'.
  241. */
  242. static void cf_add(int *table, int n, int sym, int count)
  243. {
  244. int bit;
  245. bit = 1;
  246. while (sym != 0) {
  247. if (sym & bit) {
  248. table[sym] += count;
  249. sym &= ~bit;
  250. }
  251. bit <<= 1;
  252. }
  253. table[0] += count;
  254. }
  255. /*
  256. * Cumulative frequency lookup: return the total count of symbols
  257. * with value less than `sym'.
  258. */
  259. static int cf_clookup(int *table, int n, int sym)
  260. {
  261. int bit, index, limit, count;
  262. if (sym == 0)
  263. return 0;
  264. assert(0 < sym && sym <= n);
  265. count = table[0]; /* start with the whole table size */
  266. bit = 1;
  267. while (bit < n)
  268. bit <<= 1;
  269. limit = n;
  270. while (bit > 0) {
  271. /*
  272. * Find the least number with its lowest set bit in this
  273. * position which is greater than or equal to sym.
  274. */
  275. index = ((sym + bit - 1) &~ (bit * 2 - 1)) + bit;
  276. if (index < limit) {
  277. count -= table[index];
  278. limit = index;
  279. }
  280. bit >>= 1;
  281. }
  282. return count;
  283. }
  284. /*
  285. * Single frequency lookup: return the count of symbol `sym'.
  286. */
  287. static int cf_slookup(int *table, int n, int sym)
  288. {
  289. int count, bit;
  290. assert(0 <= sym && sym < n);
  291. count = table[sym];
  292. for (bit = 1; sym+bit < n && !(sym & bit); bit <<= 1)
  293. count -= table[sym+bit];
  294. return count;
  295. }
  296. /*
  297. * Return the largest symbol index such that the cumulative
  298. * frequency up to that symbol is less than _or equal to_ count.
  299. */
  300. static int cf_whichsym(int *table, int n, int count) {
  301. int bit, sym, top;
  302. assert(count >= 0 && count < table[0]);
  303. bit = 1;
  304. while (bit < n)
  305. bit <<= 1;
  306. sym = 0;
  307. top = table[0];
  308. while (bit > 0) {
  309. if (sym+bit < n) {
  310. if (count >= top - table[sym+bit])
  311. sym += bit;
  312. else
  313. top -= table[sym+bit];
  314. }
  315. bit >>= 1;
  316. }
  317. return sym;
  318. }
  319. /* ----------------------------------------------------------------------
  320. * Map generation.
  321. *
  322. * FIXME: this isn't entirely optimal at present, because it
  323. * inherently prioritises growing the largest region since there
  324. * are more squares adjacent to it. This acts as a destabilising
  325. * influence leading to a few large regions and mostly small ones.
  326. * It might be better to do it some other way.
  327. */
  328. #define WEIGHT_INCREASED 2 /* for increased perimeter */
  329. #define WEIGHT_DECREASED 4 /* for decreased perimeter */
  330. #define WEIGHT_UNCHANGED 3 /* for unchanged perimeter */
  331. /*
  332. * Look at a square and decide which colours can be extended into
  333. * it.
  334. *
  335. * If called with index < 0, it adds together one of
  336. * WEIGHT_INCREASED, WEIGHT_DECREASED or WEIGHT_UNCHANGED for each
  337. * colour that has a valid extension (according to the effect that
  338. * it would have on the perimeter of the region being extended) and
  339. * returns the overall total.
  340. *
  341. * If called with index >= 0, it returns one of the possible
  342. * colours depending on the value of index, in such a way that the
  343. * number of possible inputs which would give rise to a given
  344. * return value correspond to the weight of that value.
  345. */
  346. static int extend_options(int w, int h, int n, int *map,
  347. int x, int y, int index)
  348. {
  349. int c, i, dx, dy;
  350. int col[8];
  351. int total = 0;
  352. if (map[y*w+x] >= 0) {
  353. assert(index < 0);
  354. return 0; /* can't do this square at all */
  355. }
  356. /*
  357. * Fetch the eight neighbours of this square, in order around
  358. * the square.
  359. */
  360. for (dy = -1; dy <= +1; dy++)
  361. for (dx = -1; dx <= +1; dx++) {
  362. int index = (dy < 0 ? 6-dx : dy > 0 ? 2+dx : 2*(1+dx));
  363. if (x+dx >= 0 && x+dx < w && y+dy >= 0 && y+dy < h)
  364. col[index] = map[(y+dy)*w+(x+dx)];
  365. else
  366. col[index] = -1;
  367. }
  368. /*
  369. * Iterate over each colour that might be feasible.
  370. *
  371. * FIXME: this routine currently has O(n) running time. We
  372. * could turn it into O(FOUR) by only bothering to iterate over
  373. * the colours mentioned in the four neighbouring squares.
  374. */
  375. for (c = 0; c < n; c++) {
  376. int count, neighbours, runs;
  377. /*
  378. * One of the even indices of col (representing the
  379. * orthogonal neighbours of this square) must be equal to
  380. * c, or else this square is not adjacent to region c and
  381. * obviously cannot become an extension of it at this time.
  382. */
  383. neighbours = 0;
  384. for (i = 0; i < 8; i += 2)
  385. if (col[i] == c)
  386. neighbours++;
  387. if (!neighbours)
  388. continue;
  389. /*
  390. * Now we know this square is adjacent to region c. The
  391. * next question is, would extending it cause the region to
  392. * become non-simply-connected? If so, we mustn't do it.
  393. *
  394. * We determine this by looking around col to see if we can
  395. * find more than one separate run of colour c.
  396. */
  397. runs = 0;
  398. for (i = 0; i < 8; i++)
  399. if (col[i] == c && col[(i+1) & 7] != c)
  400. runs++;
  401. if (runs > 1)
  402. continue;
  403. assert(runs == 1);
  404. /*
  405. * This square is a possibility. Determine its effect on
  406. * the region's perimeter (computed from the number of
  407. * orthogonal neighbours - 1 means a perimeter increase, 3
  408. * a decrease, 2 no change; 4 is impossible because the
  409. * region would already not be simply connected) and we're
  410. * done.
  411. */
  412. assert(neighbours > 0 && neighbours < 4);
  413. count = (neighbours == 1 ? WEIGHT_INCREASED :
  414. neighbours == 2 ? WEIGHT_UNCHANGED : WEIGHT_DECREASED);
  415. total += count;
  416. if (index >= 0 && index < count)
  417. return c;
  418. else
  419. index -= count;
  420. }
  421. assert(index < 0);
  422. return total;
  423. }
  424. static void genmap(int w, int h, int n, int *map, random_state *rs)
  425. {
  426. int wh = w*h;
  427. int x, y, i, k;
  428. int *tmp;
  429. assert(n <= wh);
  430. tmp = snewn(wh, int);
  431. /*
  432. * Clear the map, and set up `tmp' as a list of grid indices.
  433. */
  434. for (i = 0; i < wh; i++) {
  435. map[i] = -1;
  436. tmp[i] = i;
  437. }
  438. /*
  439. * Place the region seeds by selecting n members from `tmp'.
  440. */
  441. k = wh;
  442. for (i = 0; i < n; i++) {
  443. int j = random_upto(rs, k);
  444. map[tmp[j]] = i;
  445. tmp[j] = tmp[--k];
  446. }
  447. /*
  448. * Re-initialise `tmp' as a cumulative frequency table. This
  449. * will store the number of possible region colours we can
  450. * extend into each square.
  451. */
  452. cf_init(tmp, wh);
  453. /*
  454. * Go through the grid and set up the initial cumulative
  455. * frequencies.
  456. */
  457. for (y = 0; y < h; y++)
  458. for (x = 0; x < w; x++)
  459. cf_add(tmp, wh, y*w+x,
  460. extend_options(w, h, n, map, x, y, -1));
  461. /*
  462. * Now repeatedly choose a square we can extend a region into,
  463. * and do so.
  464. */
  465. while (tmp[0] > 0) {
  466. int k = random_upto(rs, tmp[0]);
  467. int sq;
  468. int colour;
  469. int xx, yy;
  470. sq = cf_whichsym(tmp, wh, k);
  471. k -= cf_clookup(tmp, wh, sq);
  472. x = sq % w;
  473. y = sq / w;
  474. colour = extend_options(w, h, n, map, x, y, k);
  475. map[sq] = colour;
  476. /*
  477. * Re-scan the nine cells around the one we've just
  478. * modified.
  479. */
  480. for (yy = max(y-1, 0); yy < min(y+2, h); yy++)
  481. for (xx = max(x-1, 0); xx < min(x+2, w); xx++) {
  482. cf_add(tmp, wh, yy*w+xx,
  483. -cf_slookup(tmp, wh, yy*w+xx) +
  484. extend_options(w, h, n, map, xx, yy, -1));
  485. }
  486. }
  487. /*
  488. * Finally, go through and normalise the region labels into
  489. * order, meaning that indistinguishable maps are actually
  490. * identical.
  491. */
  492. for (i = 0; i < n; i++)
  493. tmp[i] = -1;
  494. k = 0;
  495. for (i = 0; i < wh; i++) {
  496. assert(map[i] >= 0);
  497. if (tmp[map[i]] < 0)
  498. tmp[map[i]] = k++;
  499. map[i] = tmp[map[i]];
  500. }
  501. sfree(tmp);
  502. }
  503. /* ----------------------------------------------------------------------
  504. * Functions to handle graphs.
  505. */
  506. /*
  507. * Having got a map in a square grid, convert it into a graph
  508. * representation.
  509. */
  510. static int gengraph(int w, int h, int n, int *map, int *graph)
  511. {
  512. int i, j, x, y;
  513. /*
  514. * Start by setting the graph up as an adjacency matrix. We'll
  515. * turn it into a list later.
  516. */
  517. for (i = 0; i < n*n; i++)
  518. graph[i] = 0;
  519. /*
  520. * Iterate over the map looking for all adjacencies.
  521. */
  522. for (y = 0; y < h; y++)
  523. for (x = 0; x < w; x++) {
  524. int v, vx, vy;
  525. v = map[y*w+x];
  526. if (x+1 < w && (vx = map[y*w+(x+1)]) != v)
  527. graph[v*n+vx] = graph[vx*n+v] = 1;
  528. if (y+1 < h && (vy = map[(y+1)*w+x]) != v)
  529. graph[v*n+vy] = graph[vy*n+v] = 1;
  530. }
  531. /*
  532. * Turn the matrix into a list.
  533. */
  534. for (i = j = 0; i < n*n; i++)
  535. if (graph[i])
  536. graph[j++] = i;
  537. return j;
  538. }
  539. static int graph_edge_index(int *graph, int n, int ngraph, int i, int j)
  540. {
  541. int v = i*n+j;
  542. int top, bot, mid;
  543. bot = -1;
  544. top = ngraph;
  545. while (top - bot > 1) {
  546. mid = (top + bot) / 2;
  547. if (graph[mid] == v)
  548. return mid;
  549. else if (graph[mid] < v)
  550. bot = mid;
  551. else
  552. top = mid;
  553. }
  554. return -1;
  555. }
  556. #define graph_adjacent(graph, n, ngraph, i, j) \
  557. (graph_edge_index((graph), (n), (ngraph), (i), (j)) >= 0)
  558. static int graph_vertex_start(int *graph, int n, int ngraph, int i)
  559. {
  560. int v = i*n;
  561. int top, bot, mid;
  562. bot = -1;
  563. top = ngraph;
  564. while (top - bot > 1) {
  565. mid = (top + bot) / 2;
  566. if (graph[mid] < v)
  567. bot = mid;
  568. else
  569. top = mid;
  570. }
  571. return top;
  572. }
  573. /* ----------------------------------------------------------------------
  574. * Generate a four-colouring of a graph.
  575. *
  576. * FIXME: it would be nice if we could convert this recursion into
  577. * pseudo-recursion using some sort of explicit stack array, for
  578. * the sake of the Palm port and its limited stack.
  579. */
  580. static bool fourcolour_recurse(int *graph, int n, int ngraph,
  581. int *colouring, int *scratch, random_state *rs)
  582. {
  583. int nfree, nvert, start, i, j, k, c, ci;
  584. int cs[FOUR];
  585. /*
  586. * Find the smallest number of free colours in any uncoloured
  587. * vertex, and count the number of such vertices.
  588. */
  589. nfree = FIVE; /* start off bigger than FOUR! */
  590. nvert = 0;
  591. for (i = 0; i < n; i++)
  592. if (colouring[i] < 0 && scratch[i*FIVE+FOUR] <= nfree) {
  593. if (nfree > scratch[i*FIVE+FOUR]) {
  594. nfree = scratch[i*FIVE+FOUR];
  595. nvert = 0;
  596. }
  597. nvert++;
  598. }
  599. /*
  600. * If there aren't any uncoloured vertices at all, we're done.
  601. */
  602. if (nvert == 0)
  603. return true; /* we've got a colouring! */
  604. /*
  605. * Pick a random vertex in that set.
  606. */
  607. j = random_upto(rs, nvert);
  608. for (i = 0; i < n; i++)
  609. if (colouring[i] < 0 && scratch[i*FIVE+FOUR] == nfree)
  610. if (j-- == 0)
  611. break;
  612. assert(i < n);
  613. start = graph_vertex_start(graph, n, ngraph, i);
  614. /*
  615. * Loop over the possible colours for i, and recurse for each
  616. * one.
  617. */
  618. ci = 0;
  619. for (c = 0; c < FOUR; c++)
  620. if (scratch[i*FIVE+c] == 0)
  621. cs[ci++] = c;
  622. shuffle(cs, ci, sizeof(*cs), rs);
  623. while (ci-- > 0) {
  624. c = cs[ci];
  625. /*
  626. * Fill in this colour.
  627. */
  628. colouring[i] = c;
  629. /*
  630. * Update the scratch space to reflect a new neighbour
  631. * of this colour for each neighbour of vertex i.
  632. */
  633. for (j = start; j < ngraph && graph[j] < n*(i+1); j++) {
  634. k = graph[j] - i*n;
  635. if (scratch[k*FIVE+c] == 0)
  636. scratch[k*FIVE+FOUR]--;
  637. scratch[k*FIVE+c]++;
  638. }
  639. /*
  640. * Recurse.
  641. */
  642. if (fourcolour_recurse(graph, n, ngraph, colouring, scratch, rs))
  643. return true; /* got one! */
  644. /*
  645. * If that didn't work, clean up and try again with a
  646. * different colour.
  647. */
  648. for (j = start; j < ngraph && graph[j] < n*(i+1); j++) {
  649. k = graph[j] - i*n;
  650. scratch[k*FIVE+c]--;
  651. if (scratch[k*FIVE+c] == 0)
  652. scratch[k*FIVE+FOUR]++;
  653. }
  654. colouring[i] = -1;
  655. }
  656. /*
  657. * If we reach here, we were unable to find a colouring at all.
  658. * (This doesn't necessarily mean the Four Colour Theorem is
  659. * violated; it might just mean we've gone down a dead end and
  660. * need to back up and look somewhere else. It's only an FCT
  661. * violation if we get all the way back up to the top level and
  662. * still fail.)
  663. */
  664. return false;
  665. }
  666. static void fourcolour(int *graph, int n, int ngraph, int *colouring,
  667. random_state *rs)
  668. {
  669. int *scratch;
  670. int i;
  671. bool retd;
  672. /*
  673. * For each vertex and each colour, we store the number of
  674. * neighbours that have that colour. Also, we store the number
  675. * of free colours for the vertex.
  676. */
  677. scratch = snewn(n * FIVE, int);
  678. for (i = 0; i < n * FIVE; i++)
  679. scratch[i] = (i % FIVE == FOUR ? FOUR : 0);
  680. /*
  681. * Clear the colouring to start with.
  682. */
  683. for (i = 0; i < n; i++)
  684. colouring[i] = -1;
  685. retd = fourcolour_recurse(graph, n, ngraph, colouring, scratch, rs);
  686. assert(retd); /* by the Four Colour Theorem :-) */
  687. sfree(scratch);
  688. }
  689. /* ----------------------------------------------------------------------
  690. * Non-recursive solver.
  691. */
  692. struct solver_scratch {
  693. unsigned char *possible; /* bitmap of colours for each region */
  694. int *graph;
  695. int n;
  696. int ngraph;
  697. int *bfsqueue;
  698. int *bfscolour;
  699. #ifdef SOLVER_DIAGNOSTICS
  700. int *bfsprev;
  701. #endif
  702. int depth;
  703. };
  704. static struct solver_scratch *new_scratch(int *graph, int n, int ngraph)
  705. {
  706. struct solver_scratch *sc;
  707. sc = snew(struct solver_scratch);
  708. sc->graph = graph;
  709. sc->n = n;
  710. sc->ngraph = ngraph;
  711. sc->possible = snewn(n, unsigned char);
  712. sc->depth = 0;
  713. sc->bfsqueue = snewn(n, int);
  714. sc->bfscolour = snewn(n, int);
  715. #ifdef SOLVER_DIAGNOSTICS
  716. sc->bfsprev = snewn(n, int);
  717. #endif
  718. return sc;
  719. }
  720. static void free_scratch(struct solver_scratch *sc)
  721. {
  722. sfree(sc->possible);
  723. sfree(sc->bfsqueue);
  724. sfree(sc->bfscolour);
  725. #ifdef SOLVER_DIAGNOSTICS
  726. sfree(sc->bfsprev);
  727. #endif
  728. sfree(sc);
  729. }
  730. /*
  731. * Count the bits in a word. Only needs to cope with FOUR bits.
  732. */
  733. static int bitcount(int word)
  734. {
  735. assert(FOUR <= 4); /* or this needs changing */
  736. word = ((word & 0xA) >> 1) + (word & 0x5);
  737. word = ((word & 0xC) >> 2) + (word & 0x3);
  738. return word;
  739. }
  740. #ifdef SOLVER_DIAGNOSTICS
  741. static const char colnames[FOUR] = { 'R', 'Y', 'G', 'B' };
  742. #endif
  743. static bool place_colour(struct solver_scratch *sc,
  744. int *colouring, int index, int colour
  745. #ifdef SOLVER_DIAGNOSTICS
  746. , const char *verb
  747. #endif
  748. )
  749. {
  750. int *graph = sc->graph, n = sc->n, ngraph = sc->ngraph;
  751. int j, k;
  752. if (!(sc->possible[index] & (1 << colour))) {
  753. #ifdef SOLVER_DIAGNOSTICS
  754. if (verbose)
  755. printf("%*scannot place %c in region %d\n", 2*sc->depth, "",
  756. colnames[colour], index);
  757. #endif
  758. return false; /* can't do it */
  759. }
  760. sc->possible[index] = 1 << colour;
  761. colouring[index] = colour;
  762. #ifdef SOLVER_DIAGNOSTICS
  763. if (verbose)
  764. printf("%*s%s %c in region %d\n", 2*sc->depth, "",
  765. verb, colnames[colour], index);
  766. #endif
  767. /*
  768. * Rule out this colour from all the region's neighbours.
  769. */
  770. for (j = graph_vertex_start(graph, n, ngraph, index);
  771. j < ngraph && graph[j] < n*(index+1); j++) {
  772. k = graph[j] - index*n;
  773. #ifdef SOLVER_DIAGNOSTICS
  774. if (verbose && (sc->possible[k] & (1 << colour)))
  775. printf("%*s ruling out %c in region %d\n", 2*sc->depth, "",
  776. colnames[colour], k);
  777. #endif
  778. sc->possible[k] &= ~(1 << colour);
  779. }
  780. return true;
  781. }
  782. #ifdef SOLVER_DIAGNOSTICS
  783. static char *colourset(char *buf, int set)
  784. {
  785. int i;
  786. char *p = buf;
  787. const char *sep = "";
  788. for (i = 0; i < FOUR; i++)
  789. if (set & (1 << i)) {
  790. p += sprintf(p, "%s%c", sep, colnames[i]);
  791. sep = ",";
  792. }
  793. return buf;
  794. }
  795. #endif
  796. /*
  797. * Returns 0 for impossible, 1 for success, 2 for failure to
  798. * converge (i.e. puzzle is either ambiguous or just too
  799. * difficult).
  800. */
  801. static int map_solver(struct solver_scratch *sc,
  802. int *graph, int n, int ngraph, int *colouring,
  803. int difficulty)
  804. {
  805. int i;
  806. if (sc->depth == 0) {
  807. /*
  808. * Initialise scratch space.
  809. */
  810. for (i = 0; i < n; i++)
  811. sc->possible[i] = (1 << FOUR) - 1;
  812. /*
  813. * Place clues.
  814. */
  815. for (i = 0; i < n; i++)
  816. if (colouring[i] >= 0) {
  817. if (!place_colour(sc, colouring, i, colouring[i]
  818. #ifdef SOLVER_DIAGNOSTICS
  819. , "initial clue:"
  820. #endif
  821. )) {
  822. #ifdef SOLVER_DIAGNOSTICS
  823. if (verbose)
  824. printf("%*sinitial clue set is inconsistent\n",
  825. 2*sc->depth, "");
  826. #endif
  827. return 0; /* the clues aren't even consistent! */
  828. }
  829. }
  830. }
  831. /*
  832. * Now repeatedly loop until we find nothing further to do.
  833. */
  834. while (1) {
  835. bool done_something = false;
  836. if (difficulty < DIFF_EASY)
  837. break; /* can't do anything at all! */
  838. /*
  839. * Simplest possible deduction: find a region with only one
  840. * possible colour.
  841. */
  842. for (i = 0; i < n; i++) if (colouring[i] < 0) {
  843. int p = sc->possible[i];
  844. if (p == 0) {
  845. #ifdef SOLVER_DIAGNOSTICS
  846. if (verbose)
  847. printf("%*sregion %d has no possible colours left\n",
  848. 2*sc->depth, "", i);
  849. #endif
  850. return 0; /* puzzle is inconsistent */
  851. }
  852. if ((p & (p-1)) == 0) { /* p is a power of two */
  853. int c;
  854. bool ret;
  855. for (c = 0; c < FOUR; c++)
  856. if (p == (1 << c))
  857. break;
  858. assert(c < FOUR);
  859. ret = place_colour(sc, colouring, i, c
  860. #ifdef SOLVER_DIAGNOSTICS
  861. , "placing"
  862. #endif
  863. );
  864. /*
  865. * place_colour() can only fail if colour c was not
  866. * even a _possibility_ for region i, and we're
  867. * pretty sure it was because we checked before
  868. * calling place_colour(). So we can safely assert
  869. * here rather than having to return a nice
  870. * friendly error code.
  871. */
  872. assert(ret);
  873. done_something = true;
  874. }
  875. }
  876. if (done_something)
  877. continue;
  878. if (difficulty < DIFF_NORMAL)
  879. break; /* can't do anything harder */
  880. /*
  881. * Failing that, go up one level. Look for pairs of regions
  882. * which (a) both have the same pair of possible colours,
  883. * (b) are adjacent to one another, (c) are adjacent to the
  884. * same region, and (d) that region still thinks it has one
  885. * or both of those possible colours.
  886. *
  887. * Simplest way to do this is by going through the graph
  888. * edge by edge, so that we start with property (b) and
  889. * then look for (a) and finally (c) and (d).
  890. */
  891. for (i = 0; i < ngraph; i++) {
  892. int j1 = graph[i] / n, j2 = graph[i] % n;
  893. int j, k, v, v2;
  894. #ifdef SOLVER_DIAGNOSTICS
  895. bool started = false;
  896. #endif
  897. if (j1 > j2)
  898. continue; /* done it already, other way round */
  899. if (colouring[j1] >= 0 || colouring[j2] >= 0)
  900. continue; /* they're not undecided */
  901. if (sc->possible[j1] != sc->possible[j2])
  902. continue; /* they don't have the same possibles */
  903. v = sc->possible[j1];
  904. /*
  905. * See if v contains exactly two set bits.
  906. */
  907. v2 = v & -v; /* find lowest set bit */
  908. v2 = v & ~v2; /* clear it */
  909. if (v2 == 0 || (v2 & (v2-1)) != 0) /* not power of 2 */
  910. continue;
  911. /*
  912. * We've found regions j1 and j2 satisfying properties
  913. * (a) and (b): they have two possible colours between
  914. * them, and since they're adjacent to one another they
  915. * must use _both_ those colours between them.
  916. * Therefore, if they are both adjacent to any other
  917. * region then that region cannot be either colour.
  918. *
  919. * Go through the neighbours of j1 and see if any are
  920. * shared with j2.
  921. */
  922. for (j = graph_vertex_start(graph, n, ngraph, j1);
  923. j < ngraph && graph[j] < n*(j1+1); j++) {
  924. k = graph[j] - j1*n;
  925. if (graph_adjacent(graph, n, ngraph, k, j2) &&
  926. (sc->possible[k] & v)) {
  927. #ifdef SOLVER_DIAGNOSTICS
  928. if (verbose) {
  929. char buf[80];
  930. if (!started)
  931. printf("%*sadjacent regions %d,%d share colours"
  932. " %s\n", 2*sc->depth, "", j1, j2,
  933. colourset(buf, v));
  934. started = true;
  935. printf("%*s ruling out %s in region %d\n",2*sc->depth,
  936. "", colourset(buf, sc->possible[k] & v), k);
  937. }
  938. #endif
  939. sc->possible[k] &= ~v;
  940. done_something = true;
  941. }
  942. }
  943. }
  944. if (done_something)
  945. continue;
  946. if (difficulty < DIFF_HARD)
  947. break; /* can't do anything harder */
  948. /*
  949. * Right; now we get creative. Now we're going to look for
  950. * `forcing chains'. A forcing chain is a path through the
  951. * graph with the following properties:
  952. *
  953. * (a) Each vertex on the path has precisely two possible
  954. * colours.
  955. *
  956. * (b) Each pair of vertices which are adjacent on the
  957. * path share at least one possible colour in common.
  958. *
  959. * (c) Each vertex in the middle of the path shares _both_
  960. * of its colours with at least one of its neighbours
  961. * (not the same one with both neighbours).
  962. *
  963. * These together imply that at least one of the possible
  964. * colour choices at one end of the path forces _all_ the
  965. * rest of the colours along the path. In order to make
  966. * real use of this, we need further properties:
  967. *
  968. * (c) Ruling out some colour C from the vertex at one end
  969. * of the path forces the vertex at the other end to
  970. * take colour C.
  971. *
  972. * (d) The two end vertices are mutually adjacent to some
  973. * third vertex.
  974. *
  975. * (e) That third vertex currently has C as a possibility.
  976. *
  977. * If we can find all of that lot, we can deduce that at
  978. * least one of the two ends of the forcing chain has
  979. * colour C, and that therefore the mutually adjacent third
  980. * vertex does not.
  981. *
  982. * To find forcing chains, we're going to start a bfs at
  983. * each suitable vertex of the graph, once for each of its
  984. * two possible colours.
  985. */
  986. for (i = 0; i < n; i++) {
  987. int c;
  988. if (colouring[i] >= 0 || bitcount(sc->possible[i]) != 2)
  989. continue;
  990. for (c = 0; c < FOUR; c++)
  991. if (sc->possible[i] & (1 << c)) {
  992. int j, k, gi, origc, currc, head, tail;
  993. /*
  994. * Try a bfs from this vertex, ruling out
  995. * colour c.
  996. *
  997. * Within this loop, we work in colour bitmaps
  998. * rather than actual colours, because
  999. * converting back and forth is a needless
  1000. * computational expense.
  1001. */
  1002. origc = 1 << c;
  1003. for (j = 0; j < n; j++) {
  1004. sc->bfscolour[j] = -1;
  1005. #ifdef SOLVER_DIAGNOSTICS
  1006. sc->bfsprev[j] = -1;
  1007. #endif
  1008. }
  1009. head = tail = 0;
  1010. sc->bfsqueue[tail++] = i;
  1011. sc->bfscolour[i] = sc->possible[i] &~ origc;
  1012. while (head < tail) {
  1013. j = sc->bfsqueue[head++];
  1014. currc = sc->bfscolour[j];
  1015. /*
  1016. * Try neighbours of j.
  1017. */
  1018. for (gi = graph_vertex_start(graph, n, ngraph, j);
  1019. gi < ngraph && graph[gi] < n*(j+1); gi++) {
  1020. k = graph[gi] - j*n;
  1021. /*
  1022. * To continue with the bfs in vertex
  1023. * k, we need k to be
  1024. * (a) not already visited
  1025. * (b) have two possible colours
  1026. * (c) those colours include currc.
  1027. */
  1028. if (sc->bfscolour[k] < 0 &&
  1029. colouring[k] < 0 &&
  1030. bitcount(sc->possible[k]) == 2 &&
  1031. (sc->possible[k] & currc)) {
  1032. sc->bfsqueue[tail++] = k;
  1033. sc->bfscolour[k] =
  1034. sc->possible[k] &~ currc;
  1035. #ifdef SOLVER_DIAGNOSTICS
  1036. sc->bfsprev[k] = j;
  1037. #endif
  1038. }
  1039. /*
  1040. * One other possibility is that k
  1041. * might be the region in which we can
  1042. * make a real deduction: if it's
  1043. * adjacent to i, contains currc as a
  1044. * possibility, and currc is equal to
  1045. * the original colour we ruled out.
  1046. */
  1047. if (currc == origc &&
  1048. graph_adjacent(graph, n, ngraph, k, i) &&
  1049. (sc->possible[k] & currc)) {
  1050. #ifdef SOLVER_DIAGNOSTICS
  1051. if (verbose) {
  1052. char buf[80];
  1053. const char *sep = "";
  1054. int r;
  1055. printf("%*sforcing chain, colour %s, ",
  1056. 2*sc->depth, "",
  1057. colourset(buf, origc));
  1058. for (r = j; r != -1; r = sc->bfsprev[r]) {
  1059. printf("%s%d", sep, r);
  1060. sep = "-";
  1061. }
  1062. printf("\n%*s ruling out %s in region"
  1063. " %d\n", 2*sc->depth, "",
  1064. colourset(buf, origc), k);
  1065. }
  1066. #endif
  1067. sc->possible[k] &= ~origc;
  1068. done_something = true;
  1069. }
  1070. }
  1071. }
  1072. assert(tail <= n);
  1073. }
  1074. }
  1075. if (!done_something)
  1076. break;
  1077. }
  1078. /*
  1079. * See if we've got a complete solution, and return if so.
  1080. */
  1081. for (i = 0; i < n; i++)
  1082. if (colouring[i] < 0)
  1083. break;
  1084. if (i == n) {
  1085. #ifdef SOLVER_DIAGNOSTICS
  1086. if (verbose)
  1087. printf("%*sone solution found\n", 2*sc->depth, "");
  1088. #endif
  1089. return 1; /* success! */
  1090. }
  1091. /*
  1092. * If recursion is not permissible, we now give up.
  1093. */
  1094. if (difficulty < DIFF_RECURSE) {
  1095. #ifdef SOLVER_DIAGNOSTICS
  1096. if (verbose)
  1097. printf("%*sunable to proceed further without recursion\n",
  1098. 2*sc->depth, "");
  1099. #endif
  1100. return 2; /* unable to complete */
  1101. }
  1102. /*
  1103. * Now we've got to do something recursive. So first hunt for a
  1104. * currently-most-constrained region.
  1105. */
  1106. {
  1107. int best, bestc;
  1108. struct solver_scratch *rsc;
  1109. int *subcolouring, *origcolouring;
  1110. int ret, subret;
  1111. bool we_already_got_one;
  1112. best = -1;
  1113. bestc = FIVE;
  1114. for (i = 0; i < n; i++) if (colouring[i] < 0) {
  1115. int p = sc->possible[i];
  1116. enum { compile_time_assertion = 1 / (FOUR <= 4) };
  1117. int c;
  1118. /* Count the set bits. */
  1119. c = (p & 5) + ((p >> 1) & 5);
  1120. c = (c & 3) + ((c >> 2) & 3);
  1121. assert(c > 1); /* or colouring[i] would be >= 0 */
  1122. if (c < bestc) {
  1123. best = i;
  1124. bestc = c;
  1125. }
  1126. }
  1127. assert(best >= 0); /* or we'd be solved already */
  1128. #ifdef SOLVER_DIAGNOSTICS
  1129. if (verbose)
  1130. printf("%*srecursing on region %d\n", 2*sc->depth, "", best);
  1131. #endif
  1132. /*
  1133. * Now iterate over the possible colours for this region.
  1134. */
  1135. rsc = new_scratch(graph, n, ngraph);
  1136. rsc->depth = sc->depth + 1;
  1137. origcolouring = snewn(n, int);
  1138. memcpy(origcolouring, colouring, n * sizeof(int));
  1139. subcolouring = snewn(n, int);
  1140. we_already_got_one = false;
  1141. ret = 0;
  1142. for (i = 0; i < FOUR; i++) {
  1143. if (!(sc->possible[best] & (1 << i)))
  1144. continue;
  1145. memcpy(rsc->possible, sc->possible, n);
  1146. memcpy(subcolouring, origcolouring, n * sizeof(int));
  1147. place_colour(rsc, subcolouring, best, i
  1148. #ifdef SOLVER_DIAGNOSTICS
  1149. , "trying"
  1150. #endif
  1151. );
  1152. subret = map_solver(rsc, graph, n, ngraph,
  1153. subcolouring, difficulty);
  1154. #ifdef SOLVER_DIAGNOSTICS
  1155. if (verbose) {
  1156. printf("%*sretracting %c in region %d; found %s\n",
  1157. 2*sc->depth, "", colnames[i], best,
  1158. subret == 0 ? "no solutions" :
  1159. subret == 1 ? "one solution" : "multiple solutions");
  1160. }
  1161. #endif
  1162. /*
  1163. * If this possibility turned up more than one valid
  1164. * solution, or if it turned up one and we already had
  1165. * one, we're definitely ambiguous.
  1166. */
  1167. if (subret == 2 || (subret == 1 && we_already_got_one)) {
  1168. ret = 2;
  1169. break;
  1170. }
  1171. /*
  1172. * If this possibility turned up one valid solution and
  1173. * it's the first we've seen, copy it into the output.
  1174. */
  1175. if (subret == 1) {
  1176. memcpy(colouring, subcolouring, n * sizeof(int));
  1177. we_already_got_one = true;
  1178. ret = 1;
  1179. }
  1180. /*
  1181. * Otherwise, this guess led to a contradiction, so we
  1182. * do nothing.
  1183. */
  1184. }
  1185. sfree(origcolouring);
  1186. sfree(subcolouring);
  1187. free_scratch(rsc);
  1188. #ifdef SOLVER_DIAGNOSTICS
  1189. if (verbose && sc->depth == 0) {
  1190. printf("%*s%s found\n",
  1191. 2*sc->depth, "",
  1192. ret == 0 ? "no solutions" :
  1193. ret == 1 ? "one solution" : "multiple solutions");
  1194. }
  1195. #endif
  1196. return ret;
  1197. }
  1198. }
  1199. /* ----------------------------------------------------------------------
  1200. * Game generation main function.
  1201. */
  1202. static char *new_game_desc(const game_params *params, random_state *rs,
  1203. char **aux, bool interactive)
  1204. {
  1205. struct solver_scratch *sc = NULL;
  1206. int *map, *graph, ngraph, *colouring, *colouring2, *regions;
  1207. int i, j, w, h, n, solveret, cfreq[FOUR];
  1208. int wh;
  1209. int mindiff, tries;
  1210. #ifdef GENERATION_DIAGNOSTICS
  1211. int x, y;
  1212. #endif
  1213. char *ret, buf[80];
  1214. int retlen, retsize;
  1215. w = params->w;
  1216. h = params->h;
  1217. n = params->n;
  1218. wh = w*h;
  1219. *aux = NULL;
  1220. map = snewn(wh, int);
  1221. graph = snewn(n*n, int);
  1222. colouring = snewn(n, int);
  1223. colouring2 = snewn(n, int);
  1224. regions = snewn(n, int);
  1225. /*
  1226. * This is the minimum difficulty below which we'll completely
  1227. * reject a map design. Normally we set this to one below the
  1228. * requested difficulty, ensuring that we have the right
  1229. * result. However, for particularly dense maps or maps with
  1230. * particularly few regions it might not be possible to get the
  1231. * desired difficulty, so we will eventually drop this down to
  1232. * -1 to indicate that any old map will do.
  1233. */
  1234. mindiff = params->diff;
  1235. tries = 50;
  1236. while (1) {
  1237. /*
  1238. * Create the map.
  1239. */
  1240. genmap(w, h, n, map, rs);
  1241. #ifdef GENERATION_DIAGNOSTICS
  1242. for (y = 0; y < h; y++) {
  1243. for (x = 0; x < w; x++) {
  1244. int v = map[y*w+x];
  1245. if (v >= 62)
  1246. putchar('!');
  1247. else if (v >= 36)
  1248. putchar('a' + v-36);
  1249. else if (v >= 10)
  1250. putchar('A' + v-10);
  1251. else
  1252. putchar('0' + v);
  1253. }
  1254. putchar('\n');
  1255. }
  1256. #endif
  1257. /*
  1258. * Convert the map into a graph.
  1259. */
  1260. ngraph = gengraph(w, h, n, map, graph);
  1261. #ifdef GENERATION_DIAGNOSTICS
  1262. for (i = 0; i < ngraph; i++)
  1263. printf("%d-%d\n", graph[i]/n, graph[i]%n);
  1264. #endif
  1265. /*
  1266. * Colour the map.
  1267. */
  1268. fourcolour(graph, n, ngraph, colouring, rs);
  1269. #ifdef GENERATION_DIAGNOSTICS
  1270. for (i = 0; i < n; i++)
  1271. printf("%d: %d\n", i, colouring[i]);
  1272. for (y = 0; y < h; y++) {
  1273. for (x = 0; x < w; x++) {
  1274. int v = colouring[map[y*w+x]];
  1275. if (v >= 36)
  1276. putchar('a' + v-36);
  1277. else if (v >= 10)
  1278. putchar('A' + v-10);
  1279. else
  1280. putchar('0' + v);
  1281. }
  1282. putchar('\n');
  1283. }
  1284. #endif
  1285. /*
  1286. * Encode the solution as an aux string.
  1287. */
  1288. if (*aux) /* in case we've come round again */
  1289. sfree(*aux);
  1290. retlen = retsize = 0;
  1291. ret = NULL;
  1292. for (i = 0; i < n; i++) {
  1293. int len;
  1294. if (colouring[i] < 0)
  1295. continue;
  1296. len = sprintf(buf, "%s%d:%d", i ? ";" : "S;", colouring[i], i);
  1297. if (retlen + len >= retsize) {
  1298. retsize = retlen + len + 256;
  1299. ret = sresize(ret, retsize, char);
  1300. }
  1301. strcpy(ret + retlen, buf);
  1302. retlen += len;
  1303. }
  1304. *aux = ret;
  1305. /*
  1306. * Remove the region colours one by one, keeping
  1307. * solubility. Also ensure that there always remains at
  1308. * least one region of every colour, so that the user can
  1309. * drag from somewhere.
  1310. */
  1311. for (i = 0; i < FOUR; i++)
  1312. cfreq[i] = 0;
  1313. for (i = 0; i < n; i++) {
  1314. regions[i] = i;
  1315. cfreq[colouring[i]]++;
  1316. }
  1317. for (i = 0; i < FOUR; i++)
  1318. if (cfreq[i] == 0)
  1319. continue;
  1320. shuffle(regions, n, sizeof(*regions), rs);
  1321. if (sc) free_scratch(sc);
  1322. sc = new_scratch(graph, n, ngraph);
  1323. for (i = 0; i < n; i++) {
  1324. j = regions[i];
  1325. if (cfreq[colouring[j]] == 1)
  1326. continue; /* can't remove last region of colour */
  1327. memcpy(colouring2, colouring, n*sizeof(int));
  1328. colouring2[j] = -1;
  1329. solveret = map_solver(sc, graph, n, ngraph, colouring2,
  1330. params->diff);
  1331. assert(solveret >= 0); /* mustn't be impossible! */
  1332. if (solveret == 1) {
  1333. cfreq[colouring[j]]--;
  1334. colouring[j] = -1;
  1335. }
  1336. }
  1337. #ifdef GENERATION_DIAGNOSTICS
  1338. for (i = 0; i < n; i++)
  1339. if (colouring[i] >= 0) {
  1340. if (i >= 62)
  1341. putchar('!');
  1342. else if (i >= 36)
  1343. putchar('a' + i-36);
  1344. else if (i >= 10)
  1345. putchar('A' + i-10);
  1346. else
  1347. putchar('0' + i);
  1348. printf(": %d\n", colouring[i]);
  1349. }
  1350. #endif
  1351. /*
  1352. * Finally, check that the puzzle is _at least_ as hard as
  1353. * required, and indeed that it isn't already solved.
  1354. * (Calling map_solver with negative difficulty ensures the
  1355. * latter - if a solver which _does nothing_ can solve it,
  1356. * it's too easy!)
  1357. */
  1358. memcpy(colouring2, colouring, n*sizeof(int));
  1359. if (map_solver(sc, graph, n, ngraph, colouring2,
  1360. mindiff - 1) == 1) {
  1361. /*
  1362. * Drop minimum difficulty if necessary.
  1363. */
  1364. if (mindiff > 0 && (n < 9 || n > 2*wh/3)) {
  1365. if (tries-- <= 0)
  1366. mindiff = 0; /* give up and go for Easy */
  1367. }
  1368. continue;
  1369. }
  1370. break;
  1371. }
  1372. /*
  1373. * Encode as a game ID. We do this by:
  1374. *
  1375. * - first going along the horizontal edges row by row, and
  1376. * then the vertical edges column by column
  1377. * - encoding the lengths of runs of edges and runs of
  1378. * non-edges
  1379. * - the decoder will reconstitute the region boundaries from
  1380. * this and automatically number them the same way we did
  1381. * - then we encode the initial region colours in a Slant-like
  1382. * fashion (digits 0-3 interspersed with letters giving
  1383. * lengths of runs of empty spaces).
  1384. */
  1385. retlen = retsize = 0;
  1386. ret = NULL;
  1387. {
  1388. int run;
  1389. bool pv;
  1390. /*
  1391. * Start with a notional non-edge, so that there'll be an
  1392. * explicit `a' to distinguish the case where we start with
  1393. * an edge.
  1394. */
  1395. run = 1;
  1396. pv = false;
  1397. for (i = 0; i < w*(h-1) + (w-1)*h; i++) {
  1398. int x, y, dx, dy;
  1399. bool v;
  1400. if (i < w*(h-1)) {
  1401. /* Horizontal edge. */
  1402. y = i / w;
  1403. x = i % w;
  1404. dx = 0;
  1405. dy = 1;
  1406. } else {
  1407. /* Vertical edge. */
  1408. x = (i - w*(h-1)) / h;
  1409. y = (i - w*(h-1)) % h;
  1410. dx = 1;
  1411. dy = 0;
  1412. }
  1413. if (retlen + 10 >= retsize) {
  1414. retsize = retlen + 256;
  1415. ret = sresize(ret, retsize, char);
  1416. }
  1417. v = (map[y*w+x] != map[(y+dy)*w+(x+dx)]);
  1418. if (pv != v) {
  1419. ret[retlen++] = 'a'-1 + run;
  1420. run = 1;
  1421. pv = v;
  1422. } else {
  1423. /*
  1424. * 'z' is a special case in this encoding. Rather
  1425. * than meaning a run of 26 and a state switch, it
  1426. * means a run of 25 and _no_ state switch, because
  1427. * otherwise there'd be no way to encode runs of
  1428. * more than 26.
  1429. */
  1430. if (run == 25) {
  1431. ret[retlen++] = 'z';
  1432. run = 0;
  1433. }
  1434. run++;
  1435. }
  1436. }
  1437. if (retlen + 10 >= retsize) {
  1438. retsize = retlen + 256;
  1439. ret = sresize(ret, retsize, char);
  1440. }
  1441. ret[retlen++] = 'a'-1 + run;
  1442. ret[retlen++] = ',';
  1443. run = 0;
  1444. for (i = 0; i < n; i++) {
  1445. if (retlen + 10 >= retsize) {
  1446. retsize = retlen + 256;
  1447. ret = sresize(ret, retsize, char);
  1448. }
  1449. if (colouring[i] < 0) {
  1450. /*
  1451. * In _this_ encoding, 'z' is a run of 26, since
  1452. * there's no implicit state switch after each run.
  1453. * Confusingly different, but more compact.
  1454. */
  1455. if (run == 26) {
  1456. ret[retlen++] = 'z';
  1457. run = 0;
  1458. }
  1459. run++;
  1460. } else {
  1461. if (run > 0)
  1462. ret[retlen++] = 'a'-1 + run;
  1463. ret[retlen++] = '0' + colouring[i];
  1464. run = 0;
  1465. }
  1466. }
  1467. if (run > 0)
  1468. ret[retlen++] = 'a'-1 + run;
  1469. ret[retlen] = '\0';
  1470. assert(retlen < retsize);
  1471. }
  1472. free_scratch(sc);
  1473. sfree(regions);
  1474. sfree(colouring2);
  1475. sfree(colouring);
  1476. sfree(graph);
  1477. sfree(map);
  1478. return ret;
  1479. }
  1480. static const char *parse_edge_list(const game_params *params,
  1481. const char **desc, int *map)
  1482. {
  1483. int w = params->w, h = params->h, wh = w*h, n = params->n;
  1484. int i, k, pos;
  1485. bool state;
  1486. const char *p = *desc;
  1487. const char *err = NULL;
  1488. DSF *dsf = dsf_new(wh);
  1489. pos = -1;
  1490. state = false;
  1491. /*
  1492. * Parse the game description to get the list of edges, and
  1493. * build up a disjoint set forest as we go (by identifying
  1494. * pairs of squares whenever the edge list shows a non-edge).
  1495. */
  1496. while (*p && *p != ',') {
  1497. if (*p < 'a' || *p > 'z') {
  1498. err = "Unexpected character in edge list";
  1499. goto out;
  1500. }
  1501. if (*p == 'z')
  1502. k = 25;
  1503. else
  1504. k = *p - 'a' + 1;
  1505. while (k-- > 0) {
  1506. int x, y, dx, dy;
  1507. if (pos < 0) {
  1508. pos++;
  1509. continue;
  1510. } else if (pos < w*(h-1)) {
  1511. /* Horizontal edge. */
  1512. y = pos / w;
  1513. x = pos % w;
  1514. dx = 0;
  1515. dy = 1;
  1516. } else if (pos < 2*wh-w-h) {
  1517. /* Vertical edge. */
  1518. x = (pos - w*(h-1)) / h;
  1519. y = (pos - w*(h-1)) % h;
  1520. dx = 1;
  1521. dy = 0;
  1522. } else {
  1523. err = "Too much data in edge list";
  1524. goto out;
  1525. }
  1526. if (!state)
  1527. dsf_merge(dsf, y*w+x, (y+dy)*w+(x+dx));
  1528. pos++;
  1529. }
  1530. if (*p != 'z')
  1531. state = !state;
  1532. p++;
  1533. }
  1534. assert(pos <= 2*wh-w-h);
  1535. if (pos < 2*wh-w-h) {
  1536. err = "Too little data in edge list";
  1537. goto out;
  1538. }
  1539. /*
  1540. * Now go through again and allocate region numbers.
  1541. */
  1542. pos = 0;
  1543. for (i = 0; i < wh; i++)
  1544. map[i] = -1;
  1545. for (i = 0; i < wh; i++) {
  1546. k = dsf_canonify(dsf, i);
  1547. if (map[k] < 0)
  1548. map[k] = pos++;
  1549. map[i] = map[k];
  1550. }
  1551. if (pos != n) {
  1552. err = "Edge list defines the wrong number of regions";
  1553. goto out;
  1554. }
  1555. *desc = p;
  1556. err = NULL; /* no error */
  1557. out:
  1558. dsf_free(dsf);
  1559. return err;
  1560. }
  1561. static const char *validate_desc(const game_params *params, const char *desc)
  1562. {
  1563. int w = params->w, h = params->h, wh = w*h, n = params->n;
  1564. int area;
  1565. int *map;
  1566. const char *ret;
  1567. map = snewn(wh, int);
  1568. ret = parse_edge_list(params, &desc, map);
  1569. sfree(map);
  1570. if (ret)
  1571. return ret;
  1572. if (*desc != ',')
  1573. return "Expected comma before clue list";
  1574. desc++; /* eat comma */
  1575. area = 0;
  1576. while (*desc) {
  1577. if (*desc >= '0' && *desc < '0'+FOUR)
  1578. area++;
  1579. else if (*desc >= 'a' && *desc <= 'z')
  1580. area += *desc - 'a' + 1;
  1581. else
  1582. return "Unexpected character in clue list";
  1583. desc++;
  1584. }
  1585. if (area < n)
  1586. return "Too little data in clue list";
  1587. else if (area > n)
  1588. return "Too much data in clue list";
  1589. return NULL;
  1590. }
  1591. static game_state *new_game(midend *me, const game_params *params,
  1592. const char *desc)
  1593. {
  1594. int w = params->w, h = params->h, wh = w*h, n = params->n;
  1595. int i, pos;
  1596. const char *p;
  1597. game_state *state = snew(game_state);
  1598. state->p = *params;
  1599. state->colouring = snewn(n, int);
  1600. for (i = 0; i < n; i++)
  1601. state->colouring[i] = -1;
  1602. state->pencil = snewn(n, int);
  1603. for (i = 0; i < n; i++)
  1604. state->pencil[i] = 0;
  1605. state->completed = false;
  1606. state->cheated = false;
  1607. state->map = snew(struct map);
  1608. state->map->refcount = 1;
  1609. state->map->map = snewn(wh*4, int);
  1610. state->map->graph = snewn(n*n, int);
  1611. state->map->n = n;
  1612. state->map->immutable = snewn(n, bool);
  1613. for (i = 0; i < n; i++)
  1614. state->map->immutable[i] = false;
  1615. p = desc;
  1616. {
  1617. const char *ret;
  1618. ret = parse_edge_list(params, &p, state->map->map);
  1619. assert(!ret);
  1620. }
  1621. /*
  1622. * Set up the other three quadrants in `map'.
  1623. */
  1624. for (i = wh; i < 4*wh; i++)
  1625. state->map->map[i] = state->map->map[i % wh];
  1626. assert(*p == ',');
  1627. p++;
  1628. /*
  1629. * Now process the clue list.
  1630. */
  1631. pos = 0;
  1632. while (*p) {
  1633. if (*p >= '0' && *p < '0'+FOUR) {
  1634. state->colouring[pos] = *p - '0';
  1635. state->map->immutable[pos] = true;
  1636. pos++;
  1637. } else {
  1638. assert(*p >= 'a' && *p <= 'z');
  1639. pos += *p - 'a' + 1;
  1640. }
  1641. p++;
  1642. }
  1643. assert(pos == n);
  1644. state->map->ngraph = gengraph(w, h, n, state->map->map, state->map->graph);
  1645. /*
  1646. * Attempt to smooth out some of the more jagged region
  1647. * outlines by the judicious use of diagonally divided squares.
  1648. */
  1649. {
  1650. random_state *rs = random_new(desc, strlen(desc));
  1651. int *squares = snewn(wh, int);
  1652. bool done_something;
  1653. for (i = 0; i < wh; i++)
  1654. squares[i] = i;
  1655. shuffle(squares, wh, sizeof(*squares), rs);
  1656. do {
  1657. done_something = false;
  1658. for (i = 0; i < wh; i++) {
  1659. int y = squares[i] / w, x = squares[i] % w;
  1660. int c = state->map->map[y*w+x];
  1661. int tc, bc, lc, rc;
  1662. if (x == 0 || x == w-1 || y == 0 || y == h-1)
  1663. continue;
  1664. if (state->map->map[TE * wh + y*w+x] !=
  1665. state->map->map[BE * wh + y*w+x])
  1666. continue;
  1667. tc = state->map->map[BE * wh + (y-1)*w+x];
  1668. bc = state->map->map[TE * wh + (y+1)*w+x];
  1669. lc = state->map->map[RE * wh + y*w+(x-1)];
  1670. rc = state->map->map[LE * wh + y*w+(x+1)];
  1671. /*
  1672. * If this square is adjacent on two sides to one
  1673. * region and on the other two sides to the other
  1674. * region, and is itself one of the two regions, we can
  1675. * adjust it so that it's a diagonal.
  1676. */
  1677. if (tc != bc && (tc == c || bc == c)) {
  1678. if ((lc == tc && rc == bc) ||
  1679. (lc == bc && rc == tc)) {
  1680. state->map->map[TE * wh + y*w+x] = tc;
  1681. state->map->map[BE * wh + y*w+x] = bc;
  1682. state->map->map[LE * wh + y*w+x] = lc;
  1683. state->map->map[RE * wh + y*w+x] = rc;
  1684. done_something = true;
  1685. }
  1686. }
  1687. }
  1688. } while (done_something);
  1689. sfree(squares);
  1690. random_free(rs);
  1691. }
  1692. /*
  1693. * Analyse the map to find a canonical line segment
  1694. * corresponding to each edge, and a canonical point
  1695. * corresponding to each region. The former are where we'll
  1696. * eventually put error markers; the latter are where we'll put
  1697. * per-region flags such as numbers (when in diagnostic mode).
  1698. */
  1699. {
  1700. int *bestx, *besty, *an, pass;
  1701. float *ax, *ay, *best;
  1702. ax = snewn(state->map->ngraph + n, float);
  1703. ay = snewn(state->map->ngraph + n, float);
  1704. an = snewn(state->map->ngraph + n, int);
  1705. bestx = snewn(state->map->ngraph + n, int);
  1706. besty = snewn(state->map->ngraph + n, int);
  1707. best = snewn(state->map->ngraph + n, float);
  1708. for (i = 0; i < state->map->ngraph + n; i++) {
  1709. bestx[i] = besty[i] = -1;
  1710. best[i] = (float)(2*(w+h)+1);
  1711. ax[i] = ay[i] = 0.0F;
  1712. an[i] = 0;
  1713. }
  1714. /*
  1715. * We make two passes over the map, finding all the line
  1716. * segments separating regions and all the suitable points
  1717. * within regions. In the first pass, we compute the
  1718. * _average_ x and y coordinate of all the points in a
  1719. * given class; in the second pass, for each such average
  1720. * point, we find the candidate closest to it and call that
  1721. * canonical.
  1722. *
  1723. * Line segments are considered to have coordinates in
  1724. * their centre. Thus, at least one coordinate for any line
  1725. * segment is always something-and-a-half; so we store our
  1726. * coordinates as twice their normal value.
  1727. */
  1728. for (pass = 0; pass < 2; pass++) {
  1729. int x, y;
  1730. for (y = 0; y < h; y++)
  1731. for (x = 0; x < w; x++) {
  1732. int ex[4], ey[4], ea[4], eb[4], en = 0;
  1733. /*
  1734. * Look for an edge to the right of this
  1735. * square, an edge below it, and an edge in the
  1736. * middle of it. Also look to see if the point
  1737. * at the bottom right of this square is on an
  1738. * edge (and isn't a place where more than two
  1739. * regions meet).
  1740. */
  1741. if (x+1 < w) {
  1742. /* right edge */
  1743. ea[en] = state->map->map[RE * wh + y*w+x];
  1744. eb[en] = state->map->map[LE * wh + y*w+(x+1)];
  1745. ex[en] = (x+1)*2;
  1746. ey[en] = y*2+1;
  1747. en++;
  1748. }
  1749. if (y+1 < h) {
  1750. /* bottom edge */
  1751. ea[en] = state->map->map[BE * wh + y*w+x];
  1752. eb[en] = state->map->map[TE * wh + (y+1)*w+x];
  1753. ex[en] = x*2+1;
  1754. ey[en] = (y+1)*2;
  1755. en++;
  1756. }
  1757. /* diagonal edge */
  1758. ea[en] = state->map->map[TE * wh + y*w+x];
  1759. eb[en] = state->map->map[BE * wh + y*w+x];
  1760. ex[en] = x*2+1;
  1761. ey[en] = y*2+1;
  1762. en++;
  1763. if (x+1 < w && y+1 < h) {
  1764. /* bottom right corner */
  1765. int oct[8], othercol, nchanges;
  1766. oct[0] = state->map->map[RE * wh + y*w+x];
  1767. oct[1] = state->map->map[LE * wh + y*w+(x+1)];
  1768. oct[2] = state->map->map[BE * wh + y*w+(x+1)];
  1769. oct[3] = state->map->map[TE * wh + (y+1)*w+(x+1)];
  1770. oct[4] = state->map->map[LE * wh + (y+1)*w+(x+1)];
  1771. oct[5] = state->map->map[RE * wh + (y+1)*w+x];
  1772. oct[6] = state->map->map[TE * wh + (y+1)*w+x];
  1773. oct[7] = state->map->map[BE * wh + y*w+x];
  1774. othercol = -1;
  1775. nchanges = 0;
  1776. for (i = 0; i < 8; i++) {
  1777. if (oct[i] != oct[0]) {
  1778. if (othercol < 0)
  1779. othercol = oct[i];
  1780. else if (othercol != oct[i])
  1781. break; /* three colours at this point */
  1782. }
  1783. if (oct[i] != oct[(i+1) & 7])
  1784. nchanges++;
  1785. }
  1786. /*
  1787. * Now if there are exactly two regions at
  1788. * this point (not one, and not three or
  1789. * more), and only two changes around the
  1790. * loop, then this is a valid place to put
  1791. * an error marker.
  1792. */
  1793. if (i == 8 && othercol >= 0 && nchanges == 2) {
  1794. ea[en] = oct[0];
  1795. eb[en] = othercol;
  1796. ex[en] = (x+1)*2;
  1797. ey[en] = (y+1)*2;
  1798. en++;
  1799. }
  1800. /*
  1801. * If there's exactly _one_ region at this
  1802. * point, on the other hand, it's a valid
  1803. * place to put a region centre.
  1804. */
  1805. if (othercol < 0) {
  1806. ea[en] = eb[en] = oct[0];
  1807. ex[en] = (x+1)*2;
  1808. ey[en] = (y+1)*2;
  1809. en++;
  1810. }
  1811. }
  1812. /*
  1813. * Now process the points we've found, one by
  1814. * one.
  1815. */
  1816. for (i = 0; i < en; i++) {
  1817. int emin = min(ea[i], eb[i]);
  1818. int emax = max(ea[i], eb[i]);
  1819. int gindex;
  1820. if (emin != emax) {
  1821. /* Graph edge */
  1822. gindex =
  1823. graph_edge_index(state->map->graph, n,
  1824. state->map->ngraph, emin,
  1825. emax);
  1826. } else {
  1827. /* Region number */
  1828. gindex = state->map->ngraph + emin;
  1829. }
  1830. assert(gindex >= 0);
  1831. if (pass == 0) {
  1832. /*
  1833. * In pass 0, accumulate the values
  1834. * we'll use to compute the average
  1835. * positions.
  1836. */
  1837. ax[gindex] += ex[i];
  1838. ay[gindex] += ey[i];
  1839. an[gindex] += 1;
  1840. } else {
  1841. /*
  1842. * In pass 1, work out whether this
  1843. * point is closer to the average than
  1844. * the last one we've seen.
  1845. */
  1846. float dx, dy, d;
  1847. assert(an[gindex] > 0);
  1848. dx = ex[i] - ax[gindex];
  1849. dy = ey[i] - ay[gindex];
  1850. d = (float)sqrt(dx*dx + dy*dy);
  1851. if (d < best[gindex]) {
  1852. best[gindex] = d;
  1853. bestx[gindex] = ex[i];
  1854. besty[gindex] = ey[i];
  1855. }
  1856. }
  1857. }
  1858. }
  1859. if (pass == 0) {
  1860. for (i = 0; i < state->map->ngraph + n; i++)
  1861. if (an[i] > 0) {
  1862. ax[i] /= an[i];
  1863. ay[i] /= an[i];
  1864. }
  1865. }
  1866. }
  1867. state->map->edgex = snewn(state->map->ngraph, int);
  1868. state->map->edgey = snewn(state->map->ngraph, int);
  1869. memcpy(state->map->edgex, bestx, state->map->ngraph * sizeof(int));
  1870. memcpy(state->map->edgey, besty, state->map->ngraph * sizeof(int));
  1871. state->map->regionx = snewn(n, int);
  1872. state->map->regiony = snewn(n, int);
  1873. memcpy(state->map->regionx, bestx + state->map->ngraph, n*sizeof(int));
  1874. memcpy(state->map->regiony, besty + state->map->ngraph, n*sizeof(int));
  1875. for (i = 0; i < state->map->ngraph; i++)
  1876. if (state->map->edgex[i] < 0) {
  1877. /* Find the other representation of this edge. */
  1878. int e = state->map->graph[i];
  1879. int iprime = graph_edge_index(state->map->graph, n,
  1880. state->map->ngraph, e%n, e/n);
  1881. assert(state->map->edgex[iprime] >= 0);
  1882. state->map->edgex[i] = state->map->edgex[iprime];
  1883. state->map->edgey[i] = state->map->edgey[iprime];
  1884. }
  1885. sfree(ax);
  1886. sfree(ay);
  1887. sfree(an);
  1888. sfree(best);
  1889. sfree(bestx);
  1890. sfree(besty);
  1891. }
  1892. return state;
  1893. }
  1894. static game_state *dup_game(const game_state *state)
  1895. {
  1896. game_state *ret = snew(game_state);
  1897. ret->p = state->p;
  1898. ret->colouring = snewn(state->p.n, int);
  1899. memcpy(ret->colouring, state->colouring, state->p.n * sizeof(int));
  1900. ret->pencil = snewn(state->p.n, int);
  1901. memcpy(ret->pencil, state->pencil, state->p.n * sizeof(int));
  1902. ret->map = state->map;
  1903. ret->map->refcount++;
  1904. ret->completed = state->completed;
  1905. ret->cheated = state->cheated;
  1906. return ret;
  1907. }
  1908. static void free_game(game_state *state)
  1909. {
  1910. if (--state->map->refcount <= 0) {
  1911. sfree(state->map->map);
  1912. sfree(state->map->graph);
  1913. sfree(state->map->immutable);
  1914. sfree(state->map->edgex);
  1915. sfree(state->map->edgey);
  1916. sfree(state->map->regionx);
  1917. sfree(state->map->regiony);
  1918. sfree(state->map);
  1919. }
  1920. sfree(state->pencil);
  1921. sfree(state->colouring);
  1922. sfree(state);
  1923. }
  1924. static char *solve_game(const game_state *state, const game_state *currstate,
  1925. const char *aux, const char **error)
  1926. {
  1927. if (!aux) {
  1928. /*
  1929. * Use the solver.
  1930. */
  1931. int *colouring;
  1932. struct solver_scratch *sc;
  1933. int sret;
  1934. int i;
  1935. char *ret, buf[80];
  1936. int retlen, retsize;
  1937. colouring = snewn(state->map->n, int);
  1938. memcpy(colouring, state->colouring, state->map->n * sizeof(int));
  1939. sc = new_scratch(state->map->graph, state->map->n, state->map->ngraph);
  1940. sret = map_solver(sc, state->map->graph, state->map->n,
  1941. state->map->ngraph, colouring, DIFFCOUNT-1);
  1942. free_scratch(sc);
  1943. if (sret != 1) {
  1944. sfree(colouring);
  1945. if (sret == 0)
  1946. *error = "Puzzle is inconsistent";
  1947. else
  1948. *error = "Unable to find a unique solution for this puzzle";
  1949. return NULL;
  1950. }
  1951. retsize = 64;
  1952. ret = snewn(retsize, char);
  1953. strcpy(ret, "S");
  1954. retlen = 1;
  1955. for (i = 0; i < state->map->n; i++) {
  1956. int len;
  1957. assert(colouring[i] >= 0);
  1958. if (colouring[i] == currstate->colouring[i])
  1959. continue;
  1960. assert(!state->map->immutable[i]);
  1961. len = sprintf(buf, ";%d:%d", colouring[i], i);
  1962. if (retlen + len >= retsize) {
  1963. retsize = retlen + len + 256;
  1964. ret = sresize(ret, retsize, char);
  1965. }
  1966. strcpy(ret + retlen, buf);
  1967. retlen += len;
  1968. }
  1969. sfree(colouring);
  1970. return ret;
  1971. }
  1972. return dupstr(aux);
  1973. }
  1974. struct game_ui {
  1975. /*
  1976. * drag_colour:
  1977. *
  1978. * - -2 means no drag currently active.
  1979. * - >=0 means we're dragging a solid colour.
  1980. * - -1 means we're dragging a blank space, and drag_pencil
  1981. * might or might not add some pencil-mark stipples to that.
  1982. */
  1983. int drag_colour;
  1984. int drag_pencil;
  1985. int dragx, dragy;
  1986. bool show_numbers;
  1987. int cur_x, cur_y, cur_lastmove;
  1988. bool cur_visible, cur_moved;
  1989. /*
  1990. * User preference to enable alternative versions of the
  1991. * completion flash. Some users have found the colour-cycling
  1992. * default version to be a bit eye-twisting.
  1993. */
  1994. enum {
  1995. FLASH_CYCLIC, /* cycle the four colours of the map */
  1996. FLASH_EACH_TO_WHITE, /* turn each colour white in turn */
  1997. FLASH_ALL_TO_WHITE /* flash the whole map to white in one go */
  1998. } flash_type;
  1999. };
  2000. static void legacy_prefs_override(struct game_ui *ui_out)
  2001. {
  2002. static bool initialised = false;
  2003. static int flash_type = -1;
  2004. if (!initialised) {
  2005. char *env;
  2006. initialised = true;
  2007. if ((env = getenv("MAP_ALTERNATIVE_FLASH")) != NULL)
  2008. flash_type = FLASH_EACH_TO_WHITE;
  2009. }
  2010. if (flash_type != -1)
  2011. ui_out->flash_type = flash_type;
  2012. }
  2013. static game_ui *new_ui(const game_state *state)
  2014. {
  2015. game_ui *ui = snew(game_ui);
  2016. ui->dragx = ui->dragy = -1;
  2017. ui->drag_colour = -2;
  2018. ui->drag_pencil = 0;
  2019. ui->show_numbers = false;
  2020. ui->cur_x = ui->cur_y = 0;
  2021. ui->cur_visible = getenv_bool("PUZZLES_SHOW_CURSOR", false);
  2022. ui->cur_moved = false;
  2023. ui->cur_lastmove = 0;
  2024. ui->flash_type = FLASH_CYCLIC;
  2025. legacy_prefs_override(ui);
  2026. return ui;
  2027. }
  2028. static config_item *get_prefs(game_ui *ui)
  2029. {
  2030. config_item *ret;
  2031. ret = snewn(3, config_item);
  2032. ret[0].name = "Victory flash effect";
  2033. ret[0].kw = "flash-type";
  2034. ret[0].type = C_CHOICES;
  2035. ret[0].u.choices.choicenames = ":Cyclic:Each to white:All to white";
  2036. ret[0].u.choices.choicekws = ":cyclic:each-white:all-white";
  2037. ret[0].u.choices.selected = ui->flash_type;
  2038. ret[1].name = "Number regions";
  2039. ret[1].kw = "show-numbers";
  2040. ret[1].type = C_BOOLEAN;
  2041. ret[1].u.boolean.bval = ui->show_numbers;
  2042. ret[2].name = NULL;
  2043. ret[2].type = C_END;
  2044. return ret;
  2045. }
  2046. static void set_prefs(game_ui *ui, const config_item *cfg)
  2047. {
  2048. ui->flash_type = cfg[0].u.choices.selected;
  2049. ui->show_numbers = cfg[1].u.boolean.bval;
  2050. }
  2051. static void free_ui(game_ui *ui)
  2052. {
  2053. sfree(ui);
  2054. }
  2055. static void game_changed_state(game_ui *ui, const game_state *oldstate,
  2056. const game_state *newstate)
  2057. {
  2058. }
  2059. struct game_drawstate {
  2060. int tilesize;
  2061. unsigned long *drawn, *todraw;
  2062. bool started;
  2063. int dragx, dragy;
  2064. bool drag_visible;
  2065. blitter *bl;
  2066. };
  2067. /* Flags in `drawn'. */
  2068. #define ERR_BASE 0x00800000L
  2069. #define ERR_MASK 0xFF800000L
  2070. #define PENCIL_T_BASE 0x00080000L
  2071. #define PENCIL_T_MASK 0x00780000L
  2072. #define PENCIL_B_BASE 0x00008000L
  2073. #define PENCIL_B_MASK 0x00078000L
  2074. #define PENCIL_MASK 0x007F8000L
  2075. #define SHOW_NUMBERS 0x00004000L
  2076. #define TILESIZE (ds->tilesize)
  2077. #define BORDER (TILESIZE)
  2078. #define COORD(x) ( (x) * TILESIZE + BORDER )
  2079. #define FROMCOORD(x) ( ((x) - BORDER + TILESIZE) / TILESIZE - 1 )
  2080. /*
  2081. * EPSILON_FOO are epsilons added to absolute cursor position by
  2082. * cursor movement, such that in pathological cases (e.g. a very
  2083. * small diamond-shaped area) it's relatively easy to select the
  2084. * region you wanted.
  2085. */
  2086. #define EPSILON_X(button) (((button) == CURSOR_RIGHT) ? +1 : \
  2087. ((button) == CURSOR_LEFT) ? -1 : 0)
  2088. #define EPSILON_Y(button) (((button) == CURSOR_DOWN) ? +1 : \
  2089. ((button) == CURSOR_UP) ? -1 : 0)
  2090. /*
  2091. * Return the map region containing a point in tile (tx,ty), offset by
  2092. * (x_eps,y_eps) from the centre of the tile.
  2093. */
  2094. static int region_from_logical_coords(const game_state *state, int tx, int ty,
  2095. int x_eps, int y_eps)
  2096. {
  2097. int w = state->p.w, h = state->p.h, wh = w*h /*, n = state->p.n */;
  2098. int quadrant;
  2099. if (tx < 0 || tx >= w || ty < 0 || ty >= h)
  2100. return -1; /* border */
  2101. quadrant = 2 * (x_eps > y_eps) + (-x_eps > y_eps);
  2102. quadrant = (quadrant == 0 ? BE :
  2103. quadrant == 1 ? LE :
  2104. quadrant == 2 ? RE : TE);
  2105. return state->map->map[quadrant * wh + ty*w+tx];
  2106. }
  2107. static int region_from_coords(const game_state *state,
  2108. const game_drawstate *ds, int x, int y)
  2109. {
  2110. int tx = FROMCOORD(x), ty = FROMCOORD(y);
  2111. return region_from_logical_coords(
  2112. state, tx, ty, x - COORD(tx) - TILESIZE/2, y - COORD(ty) - TILESIZE/2);
  2113. }
  2114. static int region_from_ui_cursor(const game_state *state, const game_ui *ui)
  2115. {
  2116. assert(ui->cur_visible);
  2117. return region_from_logical_coords(state, ui->cur_x, ui->cur_y,
  2118. EPSILON_X(ui->cur_lastmove),
  2119. EPSILON_Y(ui->cur_lastmove));
  2120. }
  2121. static const char *current_key_label(const game_ui *ui,
  2122. const game_state *state, int button)
  2123. {
  2124. int r;
  2125. if (IS_CURSOR_SELECT(button) && ui->cur_visible) {
  2126. if (ui->drag_colour == -2) return "Pick";
  2127. r = region_from_ui_cursor(state, ui);
  2128. if (state->map->immutable[r]) return "Cancel";
  2129. if (!ui->cur_moved) return ui->drag_pencil ? "Cancel" : "Clear";
  2130. if (button == CURSOR_SELECT2) {
  2131. if (state->colouring[r] >= 0) return "Cancel";
  2132. if (ui->drag_colour >= 0) return "Stipple";
  2133. }
  2134. if (ui->drag_pencil) return "Stipple";
  2135. return ui->drag_colour >= 0 ? "Fill" : "Clear";
  2136. }
  2137. return "";
  2138. }
  2139. static char *interpret_move(const game_state *state, game_ui *ui,
  2140. const game_drawstate *ds,
  2141. int x, int y, int button)
  2142. {
  2143. char *bufp, buf[256];
  2144. bool alt_button;
  2145. int drop_region;
  2146. /*
  2147. * Enable or disable numeric labels on regions.
  2148. */
  2149. if (button == 'l' || button == 'L') {
  2150. ui->show_numbers = !ui->show_numbers;
  2151. return MOVE_UI_UPDATE;
  2152. }
  2153. if (IS_CURSOR_MOVE(button)) {
  2154. move_cursor(button, &ui->cur_x, &ui->cur_y, state->p.w, state->p.h,
  2155. false);
  2156. ui->cur_visible = true;
  2157. ui->cur_moved = true;
  2158. ui->cur_lastmove = button;
  2159. return MOVE_UI_UPDATE;
  2160. }
  2161. if (IS_CURSOR_SELECT(button)) {
  2162. if (!ui->cur_visible) {
  2163. ui->cur_visible = true;
  2164. return MOVE_UI_UPDATE;
  2165. }
  2166. if (ui->drag_colour == -2) { /* not currently cursor-dragging, start. */
  2167. int r = region_from_ui_cursor(state, ui);
  2168. if (r >= 0) {
  2169. ui->drag_colour = state->colouring[r];
  2170. ui->drag_pencil = (ui->drag_colour >= 0) ? 0 : state->pencil[r];
  2171. } else {
  2172. ui->drag_colour = -1;
  2173. ui->drag_pencil = 0;
  2174. }
  2175. ui->cur_moved = false;
  2176. return MOVE_UI_UPDATE;
  2177. } else { /* currently cursor-dragging; drop the colour in the new region. */
  2178. alt_button = (button == CURSOR_SELECT2);
  2179. /* Double-select removes current colour. */
  2180. if (!ui->cur_moved) ui->drag_colour = -1;
  2181. drop_region = region_from_ui_cursor(state, ui);
  2182. goto drag_dropped;
  2183. }
  2184. }
  2185. if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
  2186. int r = region_from_coords(state, ds, x, y);
  2187. if (r >= 0) {
  2188. ui->drag_colour = state->colouring[r];
  2189. ui->drag_pencil = state->pencil[r];
  2190. if (ui->drag_colour >= 0)
  2191. ui->drag_pencil = 0; /* should be already, but double-check */
  2192. } else {
  2193. ui->drag_colour = -1;
  2194. ui->drag_pencil = 0;
  2195. }
  2196. ui->dragx = x;
  2197. ui->dragy = y;
  2198. ui->cur_visible = false;
  2199. return MOVE_UI_UPDATE;
  2200. }
  2201. if ((button == LEFT_DRAG || button == RIGHT_DRAG) &&
  2202. ui->drag_colour > -2) {
  2203. ui->dragx = x;
  2204. ui->dragy = y;
  2205. return MOVE_UI_UPDATE;
  2206. }
  2207. if ((button == LEFT_RELEASE || button == RIGHT_RELEASE) &&
  2208. ui->drag_colour > -2) {
  2209. alt_button = (button == RIGHT_RELEASE);
  2210. drop_region = region_from_coords(state, ds, x, y);
  2211. goto drag_dropped;
  2212. }
  2213. return NULL;
  2214. drag_dropped:
  2215. {
  2216. int r = drop_region;
  2217. int c = ui->drag_colour;
  2218. int p = ui->drag_pencil;
  2219. int oldp;
  2220. /*
  2221. * Cancel the drag, whatever happens.
  2222. */
  2223. ui->drag_colour = -2;
  2224. if (r < 0)
  2225. return MOVE_UI_UPDATE; /* drag into border; do nothing else */
  2226. if (state->map->immutable[r])
  2227. return MOVE_UI_UPDATE; /* can't change this region */
  2228. if (state->colouring[r] == c && state->pencil[r] == p)
  2229. return MOVE_UI_UPDATE; /* don't _need_ to change this region */
  2230. if (alt_button) {
  2231. if (state->colouring[r] >= 0) {
  2232. /* Can't pencil on a coloured region */
  2233. return MOVE_UI_UPDATE;
  2234. } else if (c >= 0) {
  2235. /* Right-dragging from colour to blank toggles one pencil */
  2236. p = state->pencil[r] ^ (1 << c);
  2237. c = -1;
  2238. }
  2239. /* Otherwise, right-dragging from blank to blank is equivalent
  2240. * to left-dragging. */
  2241. }
  2242. bufp = buf;
  2243. oldp = state->pencil[r];
  2244. if (c != state->colouring[r]) {
  2245. bufp += sprintf(bufp, ";%c:%d", (int)(c < 0 ? 'C' : '0' + c), r);
  2246. if (c >= 0)
  2247. oldp = 0;
  2248. }
  2249. if (p != oldp) {
  2250. int i;
  2251. for (i = 0; i < FOUR; i++)
  2252. if ((oldp ^ p) & (1 << i))
  2253. bufp += sprintf(bufp, ";p%c:%d", (int)('0' + i), r);
  2254. }
  2255. return dupstr(buf+1); /* ignore first semicolon */
  2256. }
  2257. }
  2258. static game_state *execute_move(const game_state *state, const char *move)
  2259. {
  2260. int n = state->p.n;
  2261. game_state *ret = dup_game(state);
  2262. int c, k, adv, i;
  2263. while (*move) {
  2264. bool pencil = false;
  2265. c = *move;
  2266. if (c == 'p') {
  2267. pencil = true;
  2268. c = *++move;
  2269. }
  2270. if ((c == 'C' || (c >= '0' && c < '0'+FOUR)) &&
  2271. sscanf(move+1, ":%d%n", &k, &adv) == 1 &&
  2272. k >= 0 && k < state->p.n) {
  2273. move += 1 + adv;
  2274. if (pencil) {
  2275. if (ret->colouring[k] >= 0) {
  2276. free_game(ret);
  2277. return NULL;
  2278. }
  2279. if (c == 'C')
  2280. ret->pencil[k] = 0;
  2281. else
  2282. ret->pencil[k] ^= 1 << (c - '0');
  2283. } else {
  2284. ret->colouring[k] = (c == 'C' ? -1 : c - '0');
  2285. ret->pencil[k] = 0;
  2286. }
  2287. } else if (*move == 'S') {
  2288. move++;
  2289. ret->cheated = true;
  2290. } else {
  2291. free_game(ret);
  2292. return NULL;
  2293. }
  2294. if (*move && *move != ';') {
  2295. free_game(ret);
  2296. return NULL;
  2297. }
  2298. if (*move)
  2299. move++;
  2300. }
  2301. /*
  2302. * Check for completion.
  2303. */
  2304. if (!ret->completed) {
  2305. bool ok = true;
  2306. for (i = 0; i < n; i++)
  2307. if (ret->colouring[i] < 0) {
  2308. ok = false;
  2309. break;
  2310. }
  2311. if (ok) {
  2312. for (i = 0; i < ret->map->ngraph; i++) {
  2313. int j = ret->map->graph[i] / n;
  2314. int k = ret->map->graph[i] % n;
  2315. if (ret->colouring[j] == ret->colouring[k]) {
  2316. ok = false;
  2317. break;
  2318. }
  2319. }
  2320. }
  2321. if (ok)
  2322. ret->completed = true;
  2323. }
  2324. return ret;
  2325. }
  2326. /* ----------------------------------------------------------------------
  2327. * Drawing routines.
  2328. */
  2329. static void game_compute_size(const game_params *params, int tilesize,
  2330. const game_ui *ui, int *x, int *y)
  2331. {
  2332. /* Ick: fake up `ds->tilesize' for macro expansion purposes */
  2333. struct { int tilesize; } ads, *ds = &ads;
  2334. ads.tilesize = tilesize;
  2335. *x = params->w * TILESIZE + 2 * BORDER + 1;
  2336. *y = params->h * TILESIZE + 2 * BORDER + 1;
  2337. }
  2338. static void game_set_size(drawing *dr, game_drawstate *ds,
  2339. const game_params *params, int tilesize)
  2340. {
  2341. ds->tilesize = tilesize;
  2342. assert(!ds->bl); /* set_size is never called twice */
  2343. ds->bl = blitter_new(dr, TILESIZE+3, TILESIZE+3);
  2344. }
  2345. static const float map_colours[FOUR][3] = {
  2346. #ifdef VIVID_COLOURS
  2347. /* Use more vivid colours (e.g. on the Pocket PC) */
  2348. {0.75F, 0.25F, 0.25F},
  2349. {0.3F, 0.7F, 0.3F},
  2350. {0.3F, 0.3F, 0.7F},
  2351. {0.85F, 0.85F, 0.1F},
  2352. #else
  2353. {0.7F, 0.5F, 0.4F},
  2354. {0.8F, 0.7F, 0.4F},
  2355. {0.5F, 0.6F, 0.4F},
  2356. {0.55F, 0.45F, 0.35F},
  2357. #endif
  2358. };
  2359. static const int map_hatching[FOUR] = {
  2360. HATCH_VERT, HATCH_SLASH, HATCH_HORIZ, HATCH_BACKSLASH
  2361. };
  2362. static float *game_colours(frontend *fe, int *ncolours)
  2363. {
  2364. float *ret = snewn(3 * NCOLOURS, float);
  2365. frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
  2366. ret[COL_GRID * 3 + 0] = 0.0F;
  2367. ret[COL_GRID * 3 + 1] = 0.0F;
  2368. ret[COL_GRID * 3 + 2] = 0.0F;
  2369. memcpy(ret + COL_0 * 3, map_colours[0], 3 * sizeof(float));
  2370. memcpy(ret + COL_1 * 3, map_colours[1], 3 * sizeof(float));
  2371. memcpy(ret + COL_2 * 3, map_colours[2], 3 * sizeof(float));
  2372. memcpy(ret + COL_3 * 3, map_colours[3], 3 * sizeof(float));
  2373. ret[COL_ERROR * 3 + 0] = 1.0F;
  2374. ret[COL_ERROR * 3 + 1] = 0.0F;
  2375. ret[COL_ERROR * 3 + 2] = 0.0F;
  2376. ret[COL_ERRTEXT * 3 + 0] = 1.0F;
  2377. ret[COL_ERRTEXT * 3 + 1] = 1.0F;
  2378. ret[COL_ERRTEXT * 3 + 2] = 1.0F;
  2379. *ncolours = NCOLOURS;
  2380. return ret;
  2381. }
  2382. static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
  2383. {
  2384. struct game_drawstate *ds = snew(struct game_drawstate);
  2385. int i;
  2386. ds->tilesize = 0;
  2387. ds->drawn = snewn(state->p.w * state->p.h, unsigned long);
  2388. for (i = 0; i < state->p.w * state->p.h; i++)
  2389. ds->drawn[i] = 0xFFFFL;
  2390. ds->todraw = snewn(state->p.w * state->p.h, unsigned long);
  2391. ds->started = false;
  2392. ds->bl = NULL;
  2393. ds->drag_visible = false;
  2394. ds->dragx = ds->dragy = -1;
  2395. return ds;
  2396. }
  2397. static void game_free_drawstate(drawing *dr, game_drawstate *ds)
  2398. {
  2399. sfree(ds->drawn);
  2400. sfree(ds->todraw);
  2401. if (ds->bl)
  2402. blitter_free(dr, ds->bl);
  2403. sfree(ds);
  2404. }
  2405. static void draw_error(drawing *dr, game_drawstate *ds, int x, int y)
  2406. {
  2407. int coords[8];
  2408. int yext, xext;
  2409. /*
  2410. * Draw a diamond.
  2411. */
  2412. coords[0] = x - TILESIZE*2/5;
  2413. coords[1] = y;
  2414. coords[2] = x;
  2415. coords[3] = y - TILESIZE*2/5;
  2416. coords[4] = x + TILESIZE*2/5;
  2417. coords[5] = y;
  2418. coords[6] = x;
  2419. coords[7] = y + TILESIZE*2/5;
  2420. draw_polygon(dr, coords, 4, COL_ERROR, COL_GRID);
  2421. /*
  2422. * Draw an exclamation mark in the diamond. This turns out to
  2423. * look unpleasantly off-centre if done via draw_text, so I do
  2424. * it by hand on the basis that exclamation marks aren't that
  2425. * difficult to draw...
  2426. */
  2427. xext = TILESIZE/16;
  2428. yext = TILESIZE*2/5 - (xext*2+2);
  2429. draw_rect(dr, x-xext, y-yext, xext*2+1, yext*2+1 - (xext*3),
  2430. COL_ERRTEXT);
  2431. draw_rect(dr, x-xext, y+yext-xext*2+1, xext*2+1, xext*2, COL_ERRTEXT);
  2432. }
  2433. static void draw_square(drawing *dr, game_drawstate *ds,
  2434. const game_params *params, struct map *map,
  2435. int x, int y, unsigned long v)
  2436. {
  2437. int w = params->w, h = params->h, wh = w*h;
  2438. int tv, bv, xo, yo, i, j, oldj;
  2439. unsigned long errs, pencil, show_numbers;
  2440. errs = v & ERR_MASK;
  2441. v &= ~ERR_MASK;
  2442. pencil = v & PENCIL_MASK;
  2443. v &= ~PENCIL_MASK;
  2444. show_numbers = v & SHOW_NUMBERS;
  2445. v &= ~SHOW_NUMBERS;
  2446. tv = v / FIVE;
  2447. bv = v % FIVE;
  2448. clip(dr, COORD(x), COORD(y), TILESIZE, TILESIZE);
  2449. /*
  2450. * Draw the region colour.
  2451. */
  2452. draw_rect(dr, COORD(x), COORD(y), TILESIZE, TILESIZE,
  2453. (tv == FOUR ? COL_BACKGROUND : COL_0 + tv));
  2454. /*
  2455. * Draw the second region colour, if this is a diagonally
  2456. * divided square.
  2457. */
  2458. if (map->map[TE * wh + y*w+x] != map->map[BE * wh + y*w+x]) {
  2459. int coords[6];
  2460. coords[0] = COORD(x)-1;
  2461. coords[1] = COORD(y+1)+1;
  2462. if (map->map[LE * wh + y*w+x] == map->map[TE * wh + y*w+x])
  2463. coords[2] = COORD(x+1)+1;
  2464. else
  2465. coords[2] = COORD(x)-1;
  2466. coords[3] = COORD(y)-1;
  2467. coords[4] = COORD(x+1)+1;
  2468. coords[5] = COORD(y+1)+1;
  2469. draw_polygon(dr, coords, 3,
  2470. (bv == FOUR ? COL_BACKGROUND : COL_0 + bv), COL_GRID);
  2471. }
  2472. /*
  2473. * Draw `pencil marks'. Currently we arrange these in a square
  2474. * formation, which means we may be in trouble if the value of
  2475. * FOUR changes later...
  2476. */
  2477. assert(FOUR == 4);
  2478. for (yo = 0; yo < 4; yo++)
  2479. for (xo = 0; xo < 4; xo++) {
  2480. int te = map->map[TE * wh + y*w+x];
  2481. int e, ee, c;
  2482. e = (yo < xo && yo < 3-xo ? TE :
  2483. yo > xo && yo > 3-xo ? BE :
  2484. xo < 2 ? LE : RE);
  2485. ee = map->map[e * wh + y*w+x];
  2486. if (xo != (yo * 2 + 1) % 5)
  2487. continue;
  2488. c = yo;
  2489. if (!(pencil & ((ee == te ? PENCIL_T_BASE : PENCIL_B_BASE) << c)))
  2490. continue;
  2491. if (yo == xo &&
  2492. (map->map[TE * wh + y*w+x] != map->map[LE * wh + y*w+x]))
  2493. continue; /* avoid TL-BR diagonal line */
  2494. if (yo == 3-xo &&
  2495. (map->map[TE * wh + y*w+x] != map->map[RE * wh + y*w+x]))
  2496. continue; /* avoid BL-TR diagonal line */
  2497. draw_circle(dr, COORD(x) + (xo+1)*TILESIZE/5,
  2498. COORD(y) + (yo+1)*TILESIZE/5,
  2499. TILESIZE/7, COL_0 + c, COL_0 + c);
  2500. }
  2501. /*
  2502. * Draw the grid lines, if required.
  2503. */
  2504. if (x <= 0 || map->map[RE*wh+y*w+(x-1)] != map->map[LE*wh+y*w+x])
  2505. draw_rect(dr, COORD(x), COORD(y), 1, TILESIZE, COL_GRID);
  2506. if (y <= 0 || map->map[BE*wh+(y-1)*w+x] != map->map[TE*wh+y*w+x])
  2507. draw_rect(dr, COORD(x), COORD(y), TILESIZE, 1, COL_GRID);
  2508. if (x <= 0 || y <= 0 ||
  2509. map->map[RE*wh+(y-1)*w+(x-1)] != map->map[TE*wh+y*w+x] ||
  2510. map->map[BE*wh+(y-1)*w+(x-1)] != map->map[LE*wh+y*w+x])
  2511. draw_rect(dr, COORD(x), COORD(y), 1, 1, COL_GRID);
  2512. /*
  2513. * Draw error markers.
  2514. */
  2515. for (yo = 0; yo < 3; yo++)
  2516. for (xo = 0; xo < 3; xo++)
  2517. if (errs & (ERR_BASE << (yo*3+xo)))
  2518. draw_error(dr, ds,
  2519. (COORD(x)*2+TILESIZE*xo)/2,
  2520. (COORD(y)*2+TILESIZE*yo)/2);
  2521. /*
  2522. * Draw region numbers, if desired.
  2523. */
  2524. if (show_numbers) {
  2525. oldj = -1;
  2526. for (i = 0; i < 2; i++) {
  2527. j = map->map[(i?BE:TE)*wh+y*w+x];
  2528. if (oldj == j)
  2529. continue;
  2530. oldj = j;
  2531. xo = map->regionx[j] - 2*x;
  2532. yo = map->regiony[j] - 2*y;
  2533. if (xo >= 0 && xo <= 2 && yo >= 0 && yo <= 2) {
  2534. char buf[80];
  2535. sprintf(buf, "%d", j);
  2536. draw_text(dr, (COORD(x)*2+TILESIZE*xo)/2,
  2537. (COORD(y)*2+TILESIZE*yo)/2,
  2538. FONT_VARIABLE, 3*TILESIZE/5,
  2539. ALIGN_HCENTRE|ALIGN_VCENTRE,
  2540. COL_GRID, buf);
  2541. }
  2542. }
  2543. }
  2544. unclip(dr);
  2545. draw_update(dr, COORD(x), COORD(y), TILESIZE, TILESIZE);
  2546. }
  2547. static float flash_length(const game_ui *ui)
  2548. {
  2549. return (ui->flash_type == FLASH_EACH_TO_WHITE ? 0.50F : 0.30F);
  2550. }
  2551. static void game_redraw(drawing *dr, game_drawstate *ds,
  2552. const game_state *oldstate, const game_state *state,
  2553. int dir, const game_ui *ui,
  2554. float animtime, float flashtime)
  2555. {
  2556. int w = state->p.w, h = state->p.h, wh = w*h, n = state->p.n;
  2557. int x, y, i;
  2558. int flash;
  2559. if (ds->drag_visible) {
  2560. blitter_load(dr, ds->bl, ds->dragx, ds->dragy);
  2561. draw_update(dr, ds->dragx, ds->dragy, TILESIZE + 3, TILESIZE + 3);
  2562. ds->drag_visible = false;
  2563. }
  2564. if (!ds->started) {
  2565. draw_rect(dr, COORD(0), COORD(0), w*TILESIZE+1, h*TILESIZE+1,
  2566. COL_GRID);
  2567. draw_update(dr, COORD(0), COORD(0), w*TILESIZE+1, h*TILESIZE+1);
  2568. ds->started = true;
  2569. }
  2570. if (flashtime) {
  2571. if (ui->flash_type == FLASH_EACH_TO_WHITE)
  2572. flash = (int)(flashtime * FOUR / flash_length(ui));
  2573. else
  2574. flash = 1 + (int)(flashtime * THREE / flash_length(ui));
  2575. } else
  2576. flash = -1;
  2577. /*
  2578. * Set up the `todraw' array.
  2579. */
  2580. for (y = 0; y < h; y++)
  2581. for (x = 0; x < w; x++) {
  2582. int tv = state->colouring[state->map->map[TE * wh + y*w+x]];
  2583. int bv = state->colouring[state->map->map[BE * wh + y*w+x]];
  2584. unsigned long v;
  2585. if (tv < 0)
  2586. tv = FOUR;
  2587. if (bv < 0)
  2588. bv = FOUR;
  2589. if (flash >= 0) {
  2590. if (ui->flash_type == FLASH_EACH_TO_WHITE) {
  2591. if (tv == flash)
  2592. tv = FOUR;
  2593. if (bv == flash)
  2594. bv = FOUR;
  2595. } else if (ui->flash_type == FLASH_ALL_TO_WHITE) {
  2596. if (flash % 2)
  2597. tv = bv = FOUR;
  2598. } else {
  2599. if (tv != FOUR)
  2600. tv = (tv + flash) % FOUR;
  2601. if (bv != FOUR)
  2602. bv = (bv + flash) % FOUR;
  2603. }
  2604. }
  2605. v = tv * FIVE + bv;
  2606. /*
  2607. * Add pencil marks.
  2608. */
  2609. for (i = 0; i < FOUR; i++) {
  2610. if (state->colouring[state->map->map[TE * wh + y*w+x]] < 0 &&
  2611. (state->pencil[state->map->map[TE * wh + y*w+x]] & (1<<i)))
  2612. v |= PENCIL_T_BASE << i;
  2613. if (state->colouring[state->map->map[BE * wh + y*w+x]] < 0 &&
  2614. (state->pencil[state->map->map[BE * wh + y*w+x]] & (1<<i)))
  2615. v |= PENCIL_B_BASE << i;
  2616. }
  2617. if (ui->show_numbers)
  2618. v |= SHOW_NUMBERS;
  2619. ds->todraw[y*w+x] = v;
  2620. }
  2621. /*
  2622. * Add error markers to the `todraw' array.
  2623. */
  2624. for (i = 0; i < state->map->ngraph; i++) {
  2625. int v1 = state->map->graph[i] / n;
  2626. int v2 = state->map->graph[i] % n;
  2627. int xo, yo;
  2628. if (state->colouring[v1] < 0 || state->colouring[v2] < 0)
  2629. continue;
  2630. if (state->colouring[v1] != state->colouring[v2])
  2631. continue;
  2632. x = state->map->edgex[i];
  2633. y = state->map->edgey[i];
  2634. xo = x % 2; x /= 2;
  2635. yo = y % 2; y /= 2;
  2636. ds->todraw[y*w+x] |= ERR_BASE << (yo*3+xo);
  2637. if (xo == 0) {
  2638. assert(x > 0);
  2639. ds->todraw[y*w+(x-1)] |= ERR_BASE << (yo*3+2);
  2640. }
  2641. if (yo == 0) {
  2642. assert(y > 0);
  2643. ds->todraw[(y-1)*w+x] |= ERR_BASE << (2*3+xo);
  2644. }
  2645. if (xo == 0 && yo == 0) {
  2646. assert(x > 0 && y > 0);
  2647. ds->todraw[(y-1)*w+(x-1)] |= ERR_BASE << (2*3+2);
  2648. }
  2649. }
  2650. /*
  2651. * Now actually draw everything.
  2652. */
  2653. for (y = 0; y < h; y++)
  2654. for (x = 0; x < w; x++) {
  2655. unsigned long v = ds->todraw[y*w+x];
  2656. if (ds->drawn[y*w+x] != v) {
  2657. draw_square(dr, ds, &state->p, state->map, x, y, v);
  2658. ds->drawn[y*w+x] = v;
  2659. }
  2660. }
  2661. /*
  2662. * Draw the dragged colour blob if any.
  2663. */
  2664. if ((ui->drag_colour > -2) || ui->cur_visible) {
  2665. int bg, cursor_x, cursor_y;
  2666. bool iscur = false;
  2667. if (ui->drag_colour >= 0)
  2668. bg = COL_0 + ui->drag_colour;
  2669. else if (ui->drag_colour == -1) {
  2670. bg = COL_BACKGROUND;
  2671. } else {
  2672. int r = region_from_ui_cursor(state, ui);
  2673. int c = (r < 0) ? -1 : state->colouring[r];
  2674. /*bg = COL_GRID;*/
  2675. bg = (c < 0) ? COL_BACKGROUND : COL_0 + c;
  2676. iscur = true;
  2677. }
  2678. if (ui->cur_visible) {
  2679. cursor_x = COORD(ui->cur_x) + TILESIZE/2 +
  2680. EPSILON_X(ui->cur_lastmove);
  2681. cursor_y = COORD(ui->cur_y) + TILESIZE/2 +
  2682. EPSILON_Y(ui->cur_lastmove);
  2683. } else {
  2684. cursor_x = ui->dragx;
  2685. cursor_y = ui->dragy;
  2686. }
  2687. ds->dragx = cursor_x - TILESIZE/2 - 2;
  2688. ds->dragy = cursor_y - TILESIZE/2 - 2;
  2689. blitter_save(dr, ds->bl, ds->dragx, ds->dragy);
  2690. draw_circle(dr, cursor_x, cursor_y,
  2691. iscur ? TILESIZE/4 : TILESIZE/2, bg, COL_GRID);
  2692. for (i = 0; i < FOUR; i++)
  2693. if (ui->drag_pencil & (1 << i))
  2694. draw_circle(dr, cursor_x + ((i*4+2)%10-3) * TILESIZE/10,
  2695. cursor_y + (i*2-3) * TILESIZE/10,
  2696. TILESIZE/8, COL_0 + i, COL_0 + i);
  2697. draw_update(dr, ds->dragx, ds->dragy, TILESIZE + 3, TILESIZE + 3);
  2698. ds->drag_visible = true;
  2699. }
  2700. }
  2701. static float game_anim_length(const game_state *oldstate,
  2702. const game_state *newstate, int dir, game_ui *ui)
  2703. {
  2704. return 0.0F;
  2705. }
  2706. static float game_flash_length(const game_state *oldstate,
  2707. const game_state *newstate, int dir, game_ui *ui)
  2708. {
  2709. if (!oldstate->completed && newstate->completed &&
  2710. !oldstate->cheated && !newstate->cheated) {
  2711. return flash_length(ui);
  2712. } else
  2713. return 0.0F;
  2714. }
  2715. static void game_get_cursor_location(const game_ui *ui,
  2716. const game_drawstate *ds,
  2717. const game_state *state,
  2718. const game_params *params,
  2719. int *x, int *y, int *w, int *h)
  2720. {
  2721. if(ui->cur_visible) {
  2722. *x = COORD(ui->cur_x);
  2723. *y = COORD(ui->cur_y);
  2724. *w = *h = TILESIZE;
  2725. }
  2726. }
  2727. static int game_status(const game_state *state)
  2728. {
  2729. return state->completed ? +1 : 0;
  2730. }
  2731. static void game_print_size(const game_params *params, const game_ui *ui,
  2732. float *x, float *y)
  2733. {
  2734. int pw, ph;
  2735. /*
  2736. * I'll use 4mm squares by default, I think. Simplest way to
  2737. * compute this size is to compute the pixel puzzle size at a
  2738. * given tile size and then scale.
  2739. */
  2740. game_compute_size(params, 400, ui, &pw, &ph);
  2741. *x = pw / 100.0F;
  2742. *y = ph / 100.0F;
  2743. }
  2744. static void game_print(drawing *dr, const game_state *state, const game_ui *ui,
  2745. int tilesize)
  2746. {
  2747. int w = state->p.w, h = state->p.h, wh = w*h, n = state->p.n;
  2748. int ink, c[FOUR], i;
  2749. int x, y, r;
  2750. int *coords, ncoords, coordsize;
  2751. /* Ick: fake up `ds->tilesize' for macro expansion purposes */
  2752. struct { int tilesize; } ads, *ds = &ads;
  2753. /* We can't call game_set_size() here because we don't want a blitter */
  2754. ads.tilesize = tilesize;
  2755. ink = print_mono_colour(dr, 0);
  2756. for (i = 0; i < FOUR; i++)
  2757. c[i] = print_rgb_hatched_colour(dr, map_colours[i][0],
  2758. map_colours[i][1], map_colours[i][2],
  2759. map_hatching[i]);
  2760. coordsize = 0;
  2761. coords = NULL;
  2762. print_line_width(dr, TILESIZE / 16);
  2763. /*
  2764. * Draw a single filled polygon around each region.
  2765. */
  2766. for (r = 0; r < n; r++) {
  2767. int octants[8], lastdir, d1, d2, ox, oy;
  2768. /*
  2769. * Start by finding a point on the region boundary. Any
  2770. * point will do. To do this, we'll search for a square
  2771. * containing the region and then decide which corner of it
  2772. * to use.
  2773. */
  2774. x = w;
  2775. for (y = 0; y < h; y++) {
  2776. for (x = 0; x < w; x++) {
  2777. if (state->map->map[wh*0+y*w+x] == r ||
  2778. state->map->map[wh*1+y*w+x] == r ||
  2779. state->map->map[wh*2+y*w+x] == r ||
  2780. state->map->map[wh*3+y*w+x] == r)
  2781. break;
  2782. }
  2783. if (x < w)
  2784. break;
  2785. }
  2786. assert(y < h && x < w); /* we must have found one somewhere */
  2787. /*
  2788. * This is the first square in lexicographic order which
  2789. * contains part of this region. Therefore, one of the top
  2790. * two corners of the square must be what we're after. The
  2791. * only case in which it isn't the top left one is if the
  2792. * square is diagonally divided and the region is in the
  2793. * bottom right half.
  2794. */
  2795. if (state->map->map[wh*TE+y*w+x] != r &&
  2796. state->map->map[wh*LE+y*w+x] != r)
  2797. x++; /* could just as well have done y++ */
  2798. /*
  2799. * Now we have a point on the region boundary. Trace around
  2800. * the region until we come back to this point,
  2801. * accumulating coordinates for a polygon draw operation as
  2802. * we go.
  2803. */
  2804. lastdir = -1;
  2805. ox = x;
  2806. oy = y;
  2807. ncoords = 0;
  2808. do {
  2809. /*
  2810. * There are eight possible directions we could head in
  2811. * from here. We identify them by octant numbers, and
  2812. * we also use octant numbers to identify the spaces
  2813. * between them:
  2814. *
  2815. * 6 7 0
  2816. * \ 7|0 /
  2817. * \ | /
  2818. * 6 \|/ 1
  2819. * 5-----+-----1
  2820. * 5 /|\ 2
  2821. * / | \
  2822. * / 4|3 \
  2823. * 4 3 2
  2824. */
  2825. octants[0] = x<w && y>0 ? state->map->map[wh*LE+(y-1)*w+x] : -1;
  2826. octants[1] = x<w && y>0 ? state->map->map[wh*BE+(y-1)*w+x] : -1;
  2827. octants[2] = x<w && y<h ? state->map->map[wh*TE+y*w+x] : -1;
  2828. octants[3] = x<w && y<h ? state->map->map[wh*LE+y*w+x] : -1;
  2829. octants[4] = x>0 && y<h ? state->map->map[wh*RE+y*w+(x-1)] : -1;
  2830. octants[5] = x>0 && y<h ? state->map->map[wh*TE+y*w+(x-1)] : -1;
  2831. octants[6] = x>0 && y>0 ? state->map->map[wh*BE+(y-1)*w+(x-1)] :-1;
  2832. octants[7] = x>0 && y>0 ? state->map->map[wh*RE+(y-1)*w+(x-1)] :-1;
  2833. d1 = d2 = -1;
  2834. for (i = 0; i < 8; i++)
  2835. if ((octants[i] == r) ^ (octants[(i+1)%8] == r)) {
  2836. assert(d2 == -1);
  2837. if (d1 == -1)
  2838. d1 = i;
  2839. else
  2840. d2 = i;
  2841. }
  2842. assert(d1 != -1 && d2 != -1);
  2843. if (d1 == lastdir)
  2844. d1 = d2;
  2845. /*
  2846. * Now we're heading in direction d1. Save the current
  2847. * coordinates.
  2848. */
  2849. if (ncoords + 2 > coordsize) {
  2850. coordsize += 128;
  2851. coords = sresize(coords, coordsize, int);
  2852. }
  2853. coords[ncoords++] = COORD(x);
  2854. coords[ncoords++] = COORD(y);
  2855. /*
  2856. * Compute the new coordinates.
  2857. */
  2858. x += (d1 % 4 == 3 ? 0 : d1 < 4 ? +1 : -1);
  2859. y += (d1 % 4 == 1 ? 0 : d1 > 1 && d1 < 5 ? +1 : -1);
  2860. assert(x >= 0 && x <= w && y >= 0 && y <= h);
  2861. lastdir = d1 ^ 4;
  2862. } while (x != ox || y != oy);
  2863. draw_polygon(dr, coords, ncoords/2,
  2864. state->colouring[r] >= 0 ?
  2865. c[state->colouring[r]] : -1, ink);
  2866. }
  2867. sfree(coords);
  2868. }
  2869. #ifdef COMBINED
  2870. #define thegame map
  2871. #endif
  2872. const struct game thegame = {
  2873. "Map", "games.map", "map",
  2874. default_params,
  2875. game_fetch_preset, NULL,
  2876. decode_params,
  2877. encode_params,
  2878. free_params,
  2879. dup_params,
  2880. true, game_configure, custom_params,
  2881. validate_params,
  2882. new_game_desc,
  2883. validate_desc,
  2884. new_game,
  2885. dup_game,
  2886. free_game,
  2887. true, solve_game,
  2888. false, NULL, NULL, /* can_format_as_text_now, text_format */
  2889. get_prefs, set_prefs,
  2890. new_ui,
  2891. free_ui,
  2892. NULL, /* encode_ui */
  2893. NULL, /* decode_ui */
  2894. NULL, /* game_request_keys */
  2895. game_changed_state,
  2896. current_key_label,
  2897. interpret_move,
  2898. execute_move,
  2899. 20, game_compute_size, game_set_size,
  2900. game_colours,
  2901. game_new_drawstate,
  2902. game_free_drawstate,
  2903. game_redraw,
  2904. game_anim_length,
  2905. game_flash_length,
  2906. game_get_cursor_location,
  2907. game_status,
  2908. true, true, game_print_size, game_print,
  2909. false, /* wants_statusbar */
  2910. false, NULL, /* timing_state */
  2911. 0, /* flags */
  2912. };
  2913. #ifdef STANDALONE_SOLVER
  2914. int main(int argc, char **argv)
  2915. {
  2916. game_params *p;
  2917. game_state *s;
  2918. char *id = NULL, *desc;
  2919. const char *err;
  2920. bool grade = false;
  2921. int ret, diff;
  2922. bool really_verbose = false;
  2923. struct solver_scratch *sc;
  2924. int i;
  2925. while (--argc > 0) {
  2926. char *p = *++argv;
  2927. if (!strcmp(p, "-v")) {
  2928. really_verbose = true;
  2929. } else if (!strcmp(p, "-g")) {
  2930. grade = true;
  2931. } else if (*p == '-') {
  2932. fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
  2933. return 1;
  2934. } else {
  2935. id = p;
  2936. }
  2937. }
  2938. if (!id) {
  2939. fprintf(stderr, "usage: %s [-g | -v] <game_id>\n", argv[0]);
  2940. return 1;
  2941. }
  2942. desc = strchr(id, ':');
  2943. if (!desc) {
  2944. fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]);
  2945. return 1;
  2946. }
  2947. *desc++ = '\0';
  2948. p = default_params();
  2949. decode_params(p, id);
  2950. err = validate_desc(p, desc);
  2951. if (err) {
  2952. fprintf(stderr, "%s: %s\n", argv[0], err);
  2953. return 1;
  2954. }
  2955. s = new_game(NULL, p, desc);
  2956. sc = new_scratch(s->map->graph, s->map->n, s->map->ngraph);
  2957. /*
  2958. * When solving an Easy puzzle, we don't want to bother the
  2959. * user with Hard-level deductions. For this reason, we grade
  2960. * the puzzle internally before doing anything else.
  2961. */
  2962. ret = -1; /* placate optimiser */
  2963. for (diff = 0; diff < DIFFCOUNT; diff++) {
  2964. for (i = 0; i < s->map->n; i++)
  2965. if (!s->map->immutable[i])
  2966. s->colouring[i] = -1;
  2967. ret = map_solver(sc, s->map->graph, s->map->n, s->map->ngraph,
  2968. s->colouring, diff);
  2969. if (ret < 2)
  2970. break;
  2971. }
  2972. if (diff == DIFFCOUNT) {
  2973. if (grade)
  2974. printf("Difficulty rating: harder than Hard, or ambiguous\n");
  2975. else
  2976. printf("Unable to find a unique solution\n");
  2977. } else {
  2978. if (grade) {
  2979. if (ret == 0)
  2980. printf("Difficulty rating: impossible (no solution exists)\n");
  2981. else if (ret == 1)
  2982. printf("Difficulty rating: %s\n", map_diffnames[diff]);
  2983. } else {
  2984. verbose = really_verbose;
  2985. for (i = 0; i < s->map->n; i++)
  2986. if (!s->map->immutable[i])
  2987. s->colouring[i] = -1;
  2988. ret = map_solver(sc, s->map->graph, s->map->n, s->map->ngraph,
  2989. s->colouring, diff);
  2990. if (ret == 0)
  2991. printf("Puzzle is inconsistent\n");
  2992. else {
  2993. int col = 0;
  2994. for (i = 0; i < s->map->n; i++) {
  2995. printf("%5d <- %c%c", i, colnames[s->colouring[i]],
  2996. (col < 6 && i+1 < s->map->n ? ' ' : '\n'));
  2997. if (++col == 7)
  2998. col = 0;
  2999. }
  3000. }
  3001. }
  3002. }
  3003. return 0;
  3004. }
  3005. #endif
  3006. /* vim: set shiftwidth=4 tabstop=8: */