hat.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. /*
  2. * Code to generate patches of the aperiodic 'hat' tiling discovered
  3. * in 2023.
  4. *
  5. * This uses the 'combinatorial coordinates' system documented in my
  6. * public article
  7. * https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/aperiodic-tilings/
  8. *
  9. * The internal document auxiliary/doc/hats.html also contains an
  10. * explanation of the basic ideas of this algorithm (less polished but
  11. * containing more detail).
  12. *
  13. * Neither of those documents can really be put in a source file,
  14. * because they just have too many complicated diagrams. So read at
  15. * least one of those first; the comments in here will refer to it.
  16. *
  17. * Discoverers' website: https://cs.uwaterloo.ca/~csk/hat/
  18. * Preprint of paper: https://arxiv.org/abs/2303.10798
  19. */
  20. #include <assert.h>
  21. #ifdef NO_TGMATH_H
  22. # include <math.h>
  23. #else
  24. # include <tgmath.h>
  25. #endif
  26. #include <stdbool.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include "puzzles.h"
  31. #include "hat.h"
  32. #include "hat-internal.h"
  33. void hat_kiteenum_first(KiteEnum *s, int w, int h)
  34. {
  35. Kite start = { {0,0}, {0, 3}, {3, 0}, {2, 2} };
  36. size_t i;
  37. for (i = 0; i < KE_NKEEP; i++)
  38. s->recent[i] = start; /* initialise to *something* */
  39. s->curr_index = 0;
  40. s->curr = &s->recent[s->curr_index];
  41. s->state = 1;
  42. s->w = w;
  43. s->h = h;
  44. s->x = 0;
  45. s->y = 0;
  46. }
  47. bool hat_kiteenum_next(KiteEnum *s)
  48. {
  49. unsigned lastbut1 = s->last_index;
  50. s->last_index = s->curr_index;
  51. s->curr_index = (s->curr_index + 1) % KE_NKEEP;
  52. s->curr = &s->recent[s->curr_index];
  53. switch (s->state) {
  54. /* States 1,2,3 walk rightwards along the upper side of a
  55. * horizontal grid line with a pointy kite end at the start
  56. * point */
  57. case 1:
  58. s->last_step = KS_F_RIGHT;
  59. s->state = 2;
  60. break;
  61. case 2:
  62. if (s->x+1 >= s->w) {
  63. s->last_step = KS_F_RIGHT;
  64. s->state = 4;
  65. break;
  66. }
  67. s->last_step = KS_RIGHT;
  68. s->state = 3;
  69. s->x++;
  70. break;
  71. case 3:
  72. s->last_step = KS_RIGHT;
  73. s->state = 1;
  74. break;
  75. /* State 4 is special: we've just moved up into a row below a
  76. * grid line, but we can't produce the rightmost tile of that
  77. * row because it's not adjacent any tile so far emitted. So
  78. * instead, emit the second-rightmost tile, and next time,
  79. * we'll emit the rightmost. */
  80. case 4:
  81. s->last_step = KS_LEFT;
  82. s->state = 5;
  83. break;
  84. /* And now we have to emit the third-rightmost tile relative
  85. * to the last but one tile we emitted (the one from state 2,
  86. * not state 4). */
  87. case 5:
  88. s->last_step = KS_RIGHT;
  89. s->last_index = lastbut1;
  90. s->state = 6;
  91. break;
  92. /* Now states 6-8 handle the general case of walking leftwards
  93. * along the lower side of a line, starting from a
  94. * right-angled kite end. */
  95. case 6:
  96. if (s->x <= 0) {
  97. if (s->y+1 >= s->h) {
  98. s->state = 0;
  99. return false;
  100. }
  101. s->last_step = KS_RIGHT;
  102. s->state = 9;
  103. s->y++;
  104. break;
  105. }
  106. s->last_step = KS_F_RIGHT;
  107. s->state = 7;
  108. s->x--;
  109. break;
  110. case 7:
  111. s->last_step = KS_RIGHT;
  112. s->state = 8;
  113. break;
  114. case 8:
  115. s->last_step = KS_RIGHT;
  116. s->state = 6;
  117. break;
  118. /* States 9,10,11 walk rightwards along the upper side of a
  119. * horizontal grid line with a right-angled kite end at the
  120. * start point. This time there's no awkward transition from
  121. * the previous row. */
  122. case 9:
  123. s->last_step = KS_RIGHT;
  124. s->state = 10;
  125. break;
  126. case 10:
  127. s->last_step = KS_RIGHT;
  128. s->state = 11;
  129. break;
  130. case 11:
  131. if (s->x+1 >= s->w) {
  132. /* Another awkward transition to the next row, where we
  133. * have to generate it based on the previous state-9 tile.
  134. * But this time at least we generate the rightmost tile
  135. * of the new row, so the next states will be simple. */
  136. s->last_step = KS_F_RIGHT;
  137. s->last_index = lastbut1;
  138. s->state = 12;
  139. break;
  140. }
  141. s->last_step = KS_F_RIGHT;
  142. s->state = 9;
  143. s->x++;
  144. break;
  145. /* States 12,13,14 walk leftwards along the upper edge of a
  146. * horizontal grid line with a pointy kite end at the start
  147. * point */
  148. case 12:
  149. s->last_step = KS_F_RIGHT;
  150. s->state = 13;
  151. break;
  152. case 13:
  153. if (s->x <= 0) {
  154. if (s->y+1 >= s->h) {
  155. s->state = 0;
  156. return false;
  157. }
  158. s->last_step = KS_LEFT;
  159. s->state = 1;
  160. s->y++;
  161. break;
  162. }
  163. s->last_step = KS_RIGHT;
  164. s->state = 14;
  165. s->x--;
  166. break;
  167. case 14:
  168. s->last_step = KS_RIGHT;
  169. s->state = 12;
  170. break;
  171. default:
  172. return false;
  173. }
  174. *s->curr = kite_step(s->recent[s->last_index], s->last_step);
  175. return true;
  176. }
  177. /*
  178. * The actual tables.
  179. */
  180. #include "hat-tables.h"
  181. /*
  182. * One set of tables that we write by hand: the permitted ways to
  183. * extend the coordinate system outwards from a given metatile.
  184. *
  185. * One obvious approach would be to make a table of all the places
  186. * each metatile can appear in the expansion of another (e.g. H can be
  187. * subtile 0, 1 or 2 of another H, subtile 0 of a T, or 0 or 1 of a P
  188. * or an F), and when we need to decide what our current topmost tile
  189. * turns out to be a subtile of, choose equiprobably at random from
  190. * those options.
  191. *
  192. * That's what I did originally, but a better approach is to skew the
  193. * probabilities. We'd like to generate our patch of actual tiling
  194. * uniformly at random, in the sense that if you selected uniformly
  195. * from a very large region of the plane, the distribution of possible
  196. * finite patches of tiling would converge to some limit as that
  197. * region tended to infinity, and we'd be picking from that limiting
  198. * distribution on finite patches.
  199. *
  200. * For this we have to refer back to the original paper, which
  201. * indicates the subset of each metatile's expansion that can be
  202. * considered to 'belong' to that metatile, such that every subtile
  203. * belongs to exactly one parent metatile, and the overlaps are
  204. * eliminated. Reading out the diagrams from their Figure 2.8:
  205. *
  206. * - H: we discard three of the outer F subtiles, in the symmetric
  207. * positions index by our coordinates as 7, 10, 11. So we keep the
  208. * remaining subtiles {0,1,2,3,4,5,6,8,9,12}, which consist of
  209. * three H, one T, three P and three F.
  210. *
  211. * - T: only the central H expanded from a T is considered to belong
  212. * to it, so we just keep {0}, a single H.
  213. *
  214. * - P: we discard everything intersected by a long edge of the
  215. * parallelogram, leaving the central three tiles and the endmost
  216. * pair of F. That is, we keep {0,1,4,5,10}, consisting of two H,
  217. * one P and two F.
  218. *
  219. * - F: looks like P at one end, and we retain the corresponding set
  220. * of tiles there, but at the other end we keep the two F on either
  221. * side of the endmost one. So we keep {0,1,3,6,8,10}, consisting of
  222. * two H, one P and _three_ F.
  223. *
  224. * Adding up the tile numbers gives us this matrix system:
  225. *
  226. * (H_1) (3 1 2 2)(H_0)
  227. * (T_1) = (1 0 0 0)(T_0)
  228. * (P_1) (3 0 1 1)(P_0)
  229. * (F_1) (3 0 2 3)(F_0)
  230. *
  231. * which says that if you have a patch of metatiling consisting of H_0
  232. * H tiles, T_0 T tiles etc, then this matrix shows the number H_1 of
  233. * smaller H tiles, etc, expanded from it.
  234. *
  235. * If you expand _many_ times, that's equivalent to raising the matrix
  236. * to a power:
  237. *
  238. * n
  239. * (H_n) (3 1 2 2) (H_0)
  240. * (T_n) = (1 0 0 0) (T_0)
  241. * (P_n) (3 0 1 1) (P_0)
  242. * (F_n) (3 0 2 3) (F_0)
  243. *
  244. * The limiting distribution of metatiles is obtained by looking at
  245. * the four-way ratio between H_n, T_n, P_n and F_n as n tends to
  246. * infinity. To calculate this, we find the eigenvalues and
  247. * eigenvectors of the matrix, and extract the eigenvector
  248. * corresponding to the eigenvalue of largest magnitude. (Things get
  249. * more complicated in cases where there isn't a _unique_ eigenvalue
  250. * of largest magnitude, but here, there is.)
  251. *
  252. * That eigenvector is
  253. *
  254. * [ 1 ] [ 1 ]
  255. * [ (7 - 3 sqrt(5)) / 2 ] ~= [ 0.14589803375031545538 ]
  256. * [ 3 sqrt(5) - 6 ] [ 0.70820393249936908922 ]
  257. * [ (9 - 3 sqrt(5)) / 2 ] [ 1.14589803375031545538 ]
  258. *
  259. * So those are the limiting relative proportions of metatiles.
  260. *
  261. * So if we have a particular metatile, how likely is it for its
  262. * parent to be one of those? We have to adjust by the number of
  263. * metatiles of each type that each tile has as its children. For
  264. * example, the P and F tiles have one P child each, but the H has
  265. * three P children. So if we have a P, the proportion of H in its
  266. * potential ancestry is three times what's shown here. (And T can't
  267. * occur at all as a parent.)
  268. *
  269. * In other words, we should choose _each coordinate_ with probability
  270. * corresponding to one of those numbers (scaled down so they all sum
  271. * to 1). Continuing to use P as an example, it will be:
  272. *
  273. * - child 4 of H with relative probability 1
  274. * - child 5 of H with relative probability 1
  275. * - child 6 of H with relative probability 1
  276. * - child 4 of P with relative probability 0.70820393249936908922
  277. * - child 3 of F with relative probability 1.14589803375031545538
  278. *
  279. * and then we obtain the true probabilities by scaling those values
  280. * down so that they sum to 1.
  281. *
  282. * The tables below give a reasonable approximation in 32-bit
  283. * integers to these proportions.
  284. */
  285. typedef struct MetatilePossibleParent {
  286. TileType type;
  287. unsigned index;
  288. unsigned long probability;
  289. } MetatilePossibleParent;
  290. /* The above probabilities scaled up by 10000000 */
  291. #define PROB_H 10000000
  292. #define PROB_T 1458980
  293. #define PROB_P 7082039
  294. #define PROB_F 11458980
  295. static const MetatilePossibleParent parents_H[] = {
  296. { TT_H, 0, PROB_H },
  297. { TT_H, 1, PROB_H },
  298. { TT_H, 2, PROB_H },
  299. { TT_T, 0, PROB_T },
  300. { TT_P, 0, PROB_P },
  301. { TT_P, 1, PROB_P },
  302. { TT_F, 0, PROB_F },
  303. { TT_F, 1, PROB_F },
  304. };
  305. static const MetatilePossibleParent parents_T[] = {
  306. { TT_H, 3, PROB_H },
  307. };
  308. static const MetatilePossibleParent parents_P[] = {
  309. { TT_H, 4, PROB_H },
  310. { TT_H, 5, PROB_H },
  311. { TT_H, 6, PROB_H },
  312. { TT_P, 4, PROB_P },
  313. { TT_F, 3, PROB_F },
  314. };
  315. static const MetatilePossibleParent parents_F[] = {
  316. { TT_H, 8, PROB_H },
  317. { TT_H, 9, PROB_H },
  318. { TT_H, 12, PROB_H },
  319. { TT_P, 5, PROB_P },
  320. { TT_P, 10, PROB_P },
  321. { TT_F, 6, PROB_F },
  322. { TT_F, 8, PROB_F },
  323. { TT_F, 10, PROB_F },
  324. };
  325. static const MetatilePossibleParent *const possible_parents[] = {
  326. parents_H, parents_T, parents_P, parents_F,
  327. };
  328. static const size_t n_possible_parents[] = {
  329. lenof(parents_H), lenof(parents_T), lenof(parents_P), lenof(parents_F),
  330. };
  331. /*
  332. * Similarly, we also want to choose our absolute starting hat with
  333. * close to uniform probability, which again we do by looking at the
  334. * limiting ratio of the metatile types, and this time, scaling by the
  335. * number of hats in each metatile.
  336. *
  337. * We cheatingly use the same MetatilePossibleParent struct, because
  338. * it's got all the right fields, even if it has an inappropriate
  339. * name.
  340. */
  341. static const MetatilePossibleParent starting_hats[] = {
  342. { TT_H, 0, PROB_H },
  343. { TT_H, 1, PROB_H },
  344. { TT_H, 2, PROB_H },
  345. { TT_H, 3, PROB_H },
  346. { TT_T, 0, PROB_P },
  347. { TT_P, 0, PROB_P },
  348. { TT_P, 1, PROB_P },
  349. { TT_F, 0, PROB_F },
  350. { TT_F, 1, PROB_F },
  351. };
  352. #undef PROB_H
  353. #undef PROB_T
  354. #undef PROB_P
  355. #undef PROB_F
  356. HatCoords *hat_coords_new(void)
  357. {
  358. HatCoords *hc = snew(HatCoords);
  359. hc->nc = hc->csize = 0;
  360. hc->c = NULL;
  361. return hc;
  362. }
  363. void hat_coords_free(HatCoords *hc)
  364. {
  365. if (hc) {
  366. sfree(hc->c);
  367. sfree(hc);
  368. }
  369. }
  370. void hat_coords_make_space(HatCoords *hc, size_t size)
  371. {
  372. if (hc->csize < size) {
  373. hc->csize = hc->csize * 5 / 4 + 16;
  374. if (hc->csize < size)
  375. hc->csize = size;
  376. hc->c = sresize(hc->c, hc->csize, HatCoord);
  377. }
  378. }
  379. HatCoords *hat_coords_copy(HatCoords *hc_in)
  380. {
  381. HatCoords *hc_out = hat_coords_new();
  382. hat_coords_make_space(hc_out, hc_in->nc);
  383. memcpy(hc_out->c, hc_in->c, hc_in->nc * sizeof(*hc_out->c));
  384. hc_out->nc = hc_in->nc;
  385. return hc_out;
  386. }
  387. static const MetatilePossibleParent *choose_mpp(
  388. random_state *rs, const MetatilePossibleParent *parents, size_t nparents)
  389. {
  390. /*
  391. * If we needed to do this _efficiently_, we'd rewrite all those
  392. * tables above as cumulative frequency tables and use binary
  393. * search. But this happens about log n times in a grid of area n,
  394. * so it hardly matters, and it's easier to keep the tables
  395. * legible.
  396. */
  397. unsigned long limit = 0, value;
  398. size_t i;
  399. for (i = 0; i < nparents; i++)
  400. limit += parents[i].probability;
  401. value = random_upto(rs, limit);
  402. for (i = 0; i+1 < nparents; i++) {
  403. if (value < parents[i].probability)
  404. return &parents[i];
  405. value -= parents[i].probability;
  406. }
  407. assert(i == nparents - 1);
  408. assert(value < parents[i].probability);
  409. return &parents[i];
  410. }
  411. void hatctx_init_random(HatContext *ctx, random_state *rs)
  412. {
  413. const MetatilePossibleParent *starting_hat = choose_mpp(
  414. rs, starting_hats, lenof(starting_hats));
  415. ctx->rs = rs;
  416. ctx->prototype = hat_coords_new();
  417. hat_coords_make_space(ctx->prototype, 3);
  418. ctx->prototype->c[2].type = starting_hat->type;
  419. ctx->prototype->c[2].index = -1;
  420. ctx->prototype->c[1].type = TT_HAT;
  421. ctx->prototype->c[1].index = starting_hat->index;
  422. ctx->prototype->c[0].type = TT_KITE;
  423. ctx->prototype->c[0].index = random_upto(rs, HAT_KITES);
  424. ctx->prototype->nc = 3;
  425. }
  426. static inline int metatile_char_to_enum(char metatile)
  427. {
  428. return (metatile == 'H' ? TT_H :
  429. metatile == 'T' ? TT_T :
  430. metatile == 'P' ? TT_P :
  431. metatile == 'F' ? TT_F : -1);
  432. }
  433. static void init_coords_params(HatContext *ctx,
  434. const struct HatPatchParams *hp)
  435. {
  436. size_t i;
  437. ctx->rs = NULL;
  438. ctx->prototype = hat_coords_new();
  439. assert(hp->ncoords >= 3);
  440. hat_coords_make_space(ctx->prototype, hp->ncoords + 1);
  441. ctx->prototype->nc = hp->ncoords + 1;
  442. for (i = 0; i < hp->ncoords; i++)
  443. ctx->prototype->c[i].index = hp->coords[i];
  444. ctx->prototype->c[hp->ncoords].type =
  445. metatile_char_to_enum(hp->final_metatile);
  446. ctx->prototype->c[hp->ncoords].index = -1;
  447. ctx->prototype->c[0].type = TT_KITE;
  448. ctx->prototype->c[1].type = TT_HAT;
  449. for (i = hp->ncoords - 1; i > 1; i--) {
  450. TileType metatile = ctx->prototype->c[i+1].type;
  451. assert(hp->coords[i] < nchildren[metatile]);
  452. ctx->prototype->c[i].type = children[metatile][hp->coords[i]];
  453. }
  454. assert(hp->coords[0] < 8);
  455. }
  456. HatCoords *hatctx_initial_coords(HatContext *ctx)
  457. {
  458. return hat_coords_copy(ctx->prototype);
  459. }
  460. /*
  461. * Extend hc until it has at least n coordinates in, by copying from
  462. * ctx->prototype if needed, and extending ctx->prototype if needed in
  463. * order to do that.
  464. */
  465. void hatctx_extend_coords(HatContext *ctx, HatCoords *hc, size_t n)
  466. {
  467. if (ctx->prototype->nc < n) {
  468. hat_coords_make_space(ctx->prototype, n);
  469. while (ctx->prototype->nc < n) {
  470. TileType type = ctx->prototype->c[ctx->prototype->nc - 1].type;
  471. assert(ctx->prototype->c[ctx->prototype->nc - 1].index == -1);
  472. const MetatilePossibleParent *parent;
  473. if (ctx->rs)
  474. parent = choose_mpp(ctx->rs, possible_parents[type],
  475. n_possible_parents[type]);
  476. else
  477. parent = possible_parents[type];
  478. ctx->prototype->c[ctx->prototype->nc - 1].index = parent->index;
  479. ctx->prototype->c[ctx->prototype->nc].index = -1;
  480. ctx->prototype->c[ctx->prototype->nc].type = parent->type;
  481. ctx->prototype->nc++;
  482. }
  483. }
  484. hat_coords_make_space(hc, n);
  485. while (hc->nc < n) {
  486. assert(hc->c[hc->nc - 1].index == -1);
  487. assert(hc->c[hc->nc - 1].type == ctx->prototype->c[hc->nc - 1].type);
  488. hc->c[hc->nc - 1].index = ctx->prototype->c[hc->nc - 1].index;
  489. hc->c[hc->nc].index = -1;
  490. hc->c[hc->nc].type = ctx->prototype->c[hc->nc].type;
  491. hc->nc++;
  492. }
  493. }
  494. void hatctx_cleanup(HatContext *ctx)
  495. {
  496. hat_coords_free(ctx->prototype);
  497. }
  498. /*
  499. * The actual system for finding the coordinates of an adjacent kite.
  500. */
  501. /*
  502. * Kitemap step: ensure we have enough coordinates to know two levels
  503. * of meta-tiling, and use the kite map for the outer layer to move
  504. * around the individual kites. If this fails, return NULL.
  505. */
  506. static HatCoords *try_step_coords_kitemap(
  507. HatContext *ctx, HatCoords *hc_in, KiteStep step)
  508. {
  509. hatctx_extend_coords(ctx, hc_in, 4);
  510. hat_coords_debug(" try kitemap ", hc_in, "\n");
  511. unsigned kite = hc_in->c[0].index;
  512. unsigned hat = hc_in->c[1].index;
  513. unsigned meta = hc_in->c[2].index;
  514. TileType meta2type = hc_in->c[3].type;
  515. const KitemapEntry *ke = &kitemap[meta2type][
  516. kitemap_index(step, kite, hat, meta)];
  517. if (ke->kite >= 0) {
  518. /*
  519. * Success! We've got coordinates for the next kite in this
  520. * direction.
  521. */
  522. HatCoords *hc_out = hat_coords_copy(hc_in);
  523. hc_out->c[2].index = ke->meta;
  524. hc_out->c[2].type = children[meta2type][ke->meta];
  525. hc_out->c[1].index = ke->hat;
  526. hc_out->c[1].type = TT_HAT;
  527. hc_out->c[0].index = ke->kite;
  528. hc_out->c[0].type = TT_KITE;
  529. hat_coords_debug(" success! ", hc_out, "\n");
  530. return hc_out;
  531. }
  532. return NULL;
  533. }
  534. /*
  535. * Recursive metamap step. Try using the metamap to rewrite the
  536. * coordinates at hc->c[depth] and hc->c[depth+1] (using the metamap
  537. * for the tile type described in hc->c[depth+2]). If successful,
  538. * recurse back down to see if this led to a successful step via the
  539. * kitemap. If even that fails (so that we need to try a higher-order
  540. * metamap rewrite), return NULL.
  541. */
  542. static HatCoords *try_step_coords_metamap(
  543. HatContext *ctx, HatCoords *hc_in, KiteStep step, size_t depth)
  544. {
  545. HatCoords *hc_tmp = NULL, *hc_out;
  546. hatctx_extend_coords(ctx, hc_in, depth+3);
  547. #ifdef HAT_COORDS_DEBUG
  548. fprintf(stderr, " try meta %-4d", (int)depth);
  549. hat_coords_debug("", hc_in, "\n");
  550. #endif
  551. unsigned meta_orig = hc_in->c[depth].index;
  552. unsigned meta2_orig = hc_in->c[depth+1].index;
  553. TileType meta3type = hc_in->c[depth+2].type;
  554. unsigned meta = meta_orig, meta2 = meta2_orig;
  555. while (true) {
  556. const MetamapEntry *me;
  557. HatCoords *hc_curr = hc_tmp ? hc_tmp : hc_in;
  558. if (depth > 2)
  559. hc_out = try_step_coords_metamap(ctx, hc_curr, step, depth - 1);
  560. else
  561. hc_out = try_step_coords_kitemap(ctx, hc_curr, step);
  562. if (hc_out) {
  563. hat_coords_free(hc_tmp);
  564. return hc_out;
  565. }
  566. me = &metamap[meta3type][metamap_index(meta, meta2)];
  567. assert(me->meta != -1);
  568. if (me->meta == meta_orig && me->meta2 == meta2_orig) {
  569. hat_coords_free(hc_tmp);
  570. return NULL;
  571. }
  572. meta = me->meta;
  573. meta2 = me->meta2;
  574. /*
  575. * We must do the rewrite in a copy of hc_in. It's not
  576. * _necessarily_ obvious that that's the case (any successful
  577. * rewrite leaves the coordinates still valid and still
  578. * referring to the same kite, right?). But the problem is
  579. * that we might do a rewrite at this level more than once,
  580. * and in between, a metamap rewrite at the next level down
  581. * might have modified _one_ of the two coordinates we're
  582. * messing about with. So it's easiest to let the recursion
  583. * just use a separate copy.
  584. */
  585. if (!hc_tmp)
  586. hc_tmp = hat_coords_copy(hc_in);
  587. hc_tmp->c[depth+1].index = meta2;
  588. hc_tmp->c[depth+1].type = children[meta3type][meta2];
  589. hc_tmp->c[depth].index = meta;
  590. hc_tmp->c[depth].type = children[hc_tmp->c[depth+1].type][meta];
  591. hat_coords_debug(" rewritten -> ", hc_tmp, "\n");
  592. }
  593. }
  594. /*
  595. * The top-level algorithm for finding the next tile.
  596. */
  597. HatCoords *hatctx_step(HatContext *ctx, HatCoords *hc_in, KiteStep step)
  598. {
  599. HatCoords *hc_out;
  600. size_t depth;
  601. #ifdef HAT_COORDS_DEBUG
  602. static const char *const directions[] = {
  603. " left\n", " right\n", " forward left\n", " forward right\n" };
  604. hat_coords_debug("step start ", hc_in, directions[step]);
  605. #endif
  606. /*
  607. * First, just try a kitemap step immediately. If that succeeds,
  608. * we're done.
  609. */
  610. if ((hc_out = try_step_coords_kitemap(ctx, hc_in, step)) != NULL)
  611. return hc_out;
  612. /*
  613. * Otherwise, try metamap rewrites at successively higher layers
  614. * until one works. Each one will recurse back down to the
  615. * kitemap, as described above.
  616. */
  617. for (depth = 2;; depth++) {
  618. if ((hc_out = try_step_coords_metamap(
  619. ctx, hc_in, step, depth)) != NULL)
  620. return hc_out;
  621. }
  622. }
  623. /*
  624. * Generate a random set of parameters for a tiling of a given size.
  625. * To do this, we iterate over the whole tiling via hat_kiteenum_first
  626. * and hat_kiteenum_next, and for each kite, calculate its
  627. * coordinates. But then we throw the coordinates away and don't do
  628. * anything with them!
  629. *
  630. * But the side effect of _calculating_ all those coordinates is that
  631. * we found out how far ctx->prototype needed to be extended, and did
  632. * so, pulling random choices out of our random_state. So after this
  633. * iteration, ctx->prototype contains everything we need to replicate
  634. * the same piece of tiling next time.
  635. */
  636. void hat_tiling_randomise(struct HatPatchParams *hp, int w, int h,
  637. random_state *rs)
  638. {
  639. HatContext ctx[1];
  640. HatCoords *coords[KE_NKEEP];
  641. KiteEnum s[1];
  642. size_t i;
  643. hatctx_init_random(ctx, rs);
  644. for (i = 0; i < lenof(coords); i++)
  645. coords[i] = NULL;
  646. hat_kiteenum_first(s, w, h);
  647. coords[s->curr_index] = hatctx_initial_coords(ctx);
  648. while (hat_kiteenum_next(s)) {
  649. hat_coords_free(coords[s->curr_index]);
  650. coords[s->curr_index] = hatctx_step(
  651. ctx, coords[s->last_index], s->last_step);
  652. }
  653. hp->ncoords = ctx->prototype->nc - 1;
  654. hp->coords = snewn(hp->ncoords, unsigned char);
  655. for (i = 0; i < hp->ncoords; i++)
  656. hp->coords[i] = ctx->prototype->c[i].index;
  657. hp->final_metatile = tilechars[ctx->prototype->c[hp->ncoords].type];
  658. hatctx_cleanup(ctx);
  659. for (i = 0; i < lenof(coords); i++)
  660. hat_coords_free(coords[i]);
  661. }
  662. const char *hat_tiling_params_invalid(const struct HatPatchParams *hp)
  663. {
  664. TileType metatile;
  665. size_t i;
  666. if (hp->ncoords < 3)
  667. return "Grid parameters require at least three coordinates";
  668. if (metatile_char_to_enum(hp->final_metatile) < 0)
  669. return "Grid parameters contain an invalid final metatile";
  670. if (hp->coords[0] >= 8)
  671. return "Grid parameters contain an invalid kite index";
  672. metatile = metatile_char_to_enum(hp->final_metatile);
  673. for (i = hp->ncoords - 1; i > 1; i--) {
  674. if (hp->coords[i] >= nchildren[metatile])
  675. return "Grid parameters contain an invalid metatile index";
  676. metatile = children[metatile][hp->coords[i]];
  677. }
  678. if (hp->coords[1] >= hats_in_metatile[metatile])
  679. return "Grid parameters contain an invalid hat index";
  680. return NULL;
  681. }
  682. void maybe_report_hat(int w, int h, Kite kite, HatCoords *hc,
  683. internal_hat_callback_fn cb, void *cbctx)
  684. {
  685. Kite kite0;
  686. Point vertices[14];
  687. size_t i, j;
  688. bool reversed = false;
  689. int coords[28];
  690. /* Only iterate from kite #0 of a hat */
  691. if (hc->c[0].index != 0)
  692. return;
  693. kite0 = kite;
  694. /*
  695. * Identify reflected hats: they are always hat #3 of an H
  696. * metatile. If we find one, reflect the starting kite so that the
  697. * kite_step operations below will go in the other direction.
  698. */
  699. if (hc->c[2].type == TT_H && hc->c[1].index == 3) {
  700. reversed = true;
  701. Point tmp = kite.left;
  702. kite.left = kite.right;
  703. kite.right = tmp;
  704. }
  705. vertices[0] = kite.centre;
  706. vertices[1] = kite.right;
  707. vertices[2] = kite.outer;
  708. vertices[3] = kite.left;
  709. kite = kite_left(kite); /* now on kite #1 */
  710. kite = kite_forward_right(kite); /* now on kite #2 */
  711. vertices[4] = kite.centre;
  712. kite = kite_right(kite); /* now on kite #3 */
  713. vertices[5] = kite.right;
  714. vertices[6] = kite.outer;
  715. kite = kite_forward_left(kite); /* now on kite #4 */
  716. vertices[7] = kite.left;
  717. vertices[8] = kite.centre;
  718. kite = kite_right(kite); /* now on kite #5 */
  719. kite = kite_right(kite); /* now on kite #6 */
  720. kite = kite_right(kite); /* now on kite #7 */
  721. vertices[9] = kite.right;
  722. vertices[10] = kite.outer;
  723. vertices[11] = kite.left;
  724. kite = kite_left(kite); /* now on kite #6 again */
  725. vertices[12] = kite.outer;
  726. vertices[13] = kite.left;
  727. if (reversed) {
  728. /* For a reversed kite, also reverse the vertex order, so that
  729. * we report every polygon in a consistent orientation */
  730. for (i = 0, j = 13; i < j; i++, j--) {
  731. Point tmp = vertices[i];
  732. vertices[i] = vertices[j];
  733. vertices[j] = tmp;
  734. }
  735. }
  736. /*
  737. * Convert from our internal coordinate system into the orthogonal
  738. * one used in this module's external API. In the same loop, we
  739. * might as well do the bounds check.
  740. */
  741. for (i = 0; i < 14; i++) {
  742. Point v = vertices[i];
  743. int x = (v.x * 2 + v.y) / 3, y = v.y;
  744. if (x < 0 || x > 4*w || y < 0 || y > 6*h)
  745. return; /* a vertex of this kite is out of bounds */
  746. coords[2*i] = x;
  747. coords[2*i+1] = y;
  748. }
  749. cb(cbctx, kite0, hc, coords);
  750. }
  751. struct internal_ctx {
  752. hat_tile_callback_fn external_cb;
  753. void *external_cbctx;
  754. };
  755. static void report_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
  756. {
  757. struct internal_ctx *ctx = (struct internal_ctx *)vctx;
  758. ctx->external_cb(ctx->external_cbctx, 14, coords);
  759. }
  760. /*
  761. * Generate a hat tiling from a previously generated set of parameters.
  762. */
  763. void hat_tiling_generate(const struct HatPatchParams *hp, int w, int h,
  764. hat_tile_callback_fn cb, void *cbctx)
  765. {
  766. HatContext ctx[1];
  767. HatCoords *coords[KE_NKEEP];
  768. KiteEnum s[1];
  769. size_t i;
  770. struct internal_ctx report_hat_ctx[1];
  771. report_hat_ctx->external_cb = cb;
  772. report_hat_ctx->external_cbctx = cbctx;
  773. init_coords_params(ctx, hp);
  774. for (i = 0; i < lenof(coords); i++)
  775. coords[i] = NULL;
  776. hat_kiteenum_first(s, w, h);
  777. coords[s->curr_index] = hatctx_initial_coords(ctx);
  778. maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
  779. report_hat, report_hat_ctx);
  780. while (hat_kiteenum_next(s)) {
  781. hat_coords_free(coords[s->curr_index]);
  782. coords[s->curr_index] = hatctx_step(
  783. ctx, coords[s->last_index], s->last_step);
  784. maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
  785. report_hat, report_hat_ctx);
  786. }
  787. hatctx_cleanup(ctx);
  788. for (i = 0; i < lenof(coords); i++)
  789. hat_coords_free(coords[i]);
  790. }