@johnmorrisdotca/kazu 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +424 -10
  3. package/dist/akari-draw-entry.d.ts +2 -0
  4. package/dist/akari-draw-entry.js +1 -0
  5. package/dist/akari-entry.d.ts +13 -0
  6. package/dist/akari-entry.js +11 -0
  7. package/dist/akari-play-entry.d.ts +2 -0
  8. package/dist/akari-play-entry.js +1 -0
  9. package/dist/akari.constants.d.ts +7 -0
  10. package/dist/akari.constants.js +7 -0
  11. package/dist/akari.types.d.ts +52 -0
  12. package/dist/akari.types.js +1 -0
  13. package/dist/akariBoard.d.ts +11 -0
  14. package/dist/akariBoard.js +96 -0
  15. package/dist/akariDraw.d.ts +4 -0
  16. package/dist/akariDraw.js +38 -0
  17. package/dist/akariGame.d.ts +15 -0
  18. package/dist/akariGame.js +71 -0
  19. package/dist/akariGenerate.d.ts +10 -0
  20. package/dist/akariGenerate.js +101 -0
  21. package/dist/akariLogic.d.ts +10 -0
  22. package/dist/akariLogic.js +84 -0
  23. package/dist/akariMount.d.ts +3 -0
  24. package/dist/akariMount.js +214 -0
  25. package/dist/akariPlay.types.d.ts +25 -0
  26. package/dist/akariPlay.types.js +1 -0
  27. package/dist/akariRate.d.ts +6 -0
  28. package/dist/akariRate.js +34 -0
  29. package/dist/akariSolve.d.ts +6 -0
  30. package/dist/akariSolve.js +18 -0
  31. package/dist/akariStrings.d.ts +98 -0
  32. package/dist/akariStrings.js +53 -0
  33. package/dist/akariStyle.d.ts +1 -0
  34. package/dist/akariStyle.js +9 -0
  35. package/dist/akariTemplate.d.ts +7 -0
  36. package/dist/akariTemplate.js +78 -0
  37. package/dist/csp.d.ts +63 -0
  38. package/dist/csp.js +162 -0
  39. package/dist/fillomino-draw-entry.d.ts +2 -0
  40. package/dist/fillomino-draw-entry.js +1 -0
  41. package/dist/fillomino-entry.d.ts +9 -0
  42. package/dist/fillomino-entry.js +8 -0
  43. package/dist/fillomino-play-entry.d.ts +4 -0
  44. package/dist/fillomino-play-entry.js +3 -0
  45. package/dist/fillomino.constants.d.ts +9 -0
  46. package/dist/fillomino.constants.js +9 -0
  47. package/dist/fillomino.types.d.ts +47 -0
  48. package/dist/fillomino.types.js +1 -0
  49. package/dist/fillominoBoard.d.ts +6 -0
  50. package/dist/fillominoBoard.js +84 -0
  51. package/dist/fillominoBuild.d.ts +10 -0
  52. package/dist/fillominoBuild.js +78 -0
  53. package/dist/fillominoDraw.d.ts +3 -0
  54. package/dist/fillominoDraw.js +31 -0
  55. package/dist/fillominoGame.d.ts +13 -0
  56. package/dist/fillominoGame.js +65 -0
  57. package/dist/fillominoGenerate.d.ts +9 -0
  58. package/dist/fillominoGenerate.js +93 -0
  59. package/dist/fillominoLogic.d.ts +14 -0
  60. package/dist/fillominoLogic.js +177 -0
  61. package/dist/fillominoMount.d.ts +2 -0
  62. package/dist/fillominoMount.js +214 -0
  63. package/dist/fillominoPlay.types.d.ts +25 -0
  64. package/dist/fillominoPlay.types.js +1 -0
  65. package/dist/fillominoRate.d.ts +3 -0
  66. package/dist/fillominoRate.js +57 -0
  67. package/dist/fillominoSolve.d.ts +6 -0
  68. package/dist/fillominoSolve.js +38 -0
  69. package/dist/fillominoStrings.d.ts +102 -0
  70. package/dist/fillominoStrings.js +13 -0
  71. package/dist/fillominoStyle.d.ts +1 -0
  72. package/dist/fillominoStyle.js +13 -0
  73. package/dist/fillominoWorker.d.ts +1 -0
  74. package/dist/fillominoWorker.js +10 -0
  75. package/dist/heyawake-draw-entry.d.ts +2 -0
  76. package/dist/heyawake-draw-entry.js +1 -0
  77. package/dist/heyawake-entry.d.ts +13 -0
  78. package/dist/heyawake-entry.js +11 -0
  79. package/dist/heyawake-play-entry.d.ts +2 -0
  80. package/dist/heyawake-play-entry.js +1 -0
  81. package/dist/heyawake.constants.d.ts +5 -0
  82. package/dist/heyawake.constants.js +5 -0
  83. package/dist/heyawake.types.d.ts +35 -0
  84. package/dist/heyawake.types.js +1 -0
  85. package/dist/heyawakeBoard.d.ts +7 -0
  86. package/dist/heyawakeBoard.js +116 -0
  87. package/dist/heyawakeDraw.d.ts +3 -0
  88. package/dist/heyawakeDraw.js +27 -0
  89. package/dist/heyawakeGame.d.ts +12 -0
  90. package/dist/heyawakeGame.js +51 -0
  91. package/dist/heyawakeGenerate.d.ts +2 -0
  92. package/dist/heyawakeGenerate.js +114 -0
  93. package/dist/heyawakeMount.d.ts +2 -0
  94. package/dist/heyawakeMount.js +106 -0
  95. package/dist/heyawakePlay.types.d.ts +24 -0
  96. package/dist/heyawakePlay.types.js +1 -0
  97. package/dist/heyawakeSolve.d.ts +5 -0
  98. package/dist/heyawakeSolve.js +52 -0
  99. package/dist/heyawakeStrings.d.ts +19 -0
  100. package/dist/heyawakeStrings.js +7 -0
  101. package/dist/heyawakeStyle.d.ts +1 -0
  102. package/dist/heyawakeStyle.js +2 -0
  103. package/dist/heyawakeWorker.d.ts +1 -0
  104. package/dist/heyawakeWorker.js +10 -0
  105. package/dist/hitori-draw-entry.d.ts +2 -0
  106. package/dist/hitori-draw-entry.js +1 -0
  107. package/dist/hitori-entry.d.ts +7 -0
  108. package/dist/hitori-entry.js +7 -0
  109. package/dist/hitori-play-entry.d.ts +4 -0
  110. package/dist/hitori-play-entry.js +3 -0
  111. package/dist/hitori.constants.d.ts +8 -0
  112. package/dist/hitori.constants.js +8 -0
  113. package/dist/hitori.types.d.ts +37 -0
  114. package/dist/hitori.types.js +1 -0
  115. package/dist/hitoriBoard.d.ts +8 -0
  116. package/dist/hitoriBoard.js +73 -0
  117. package/dist/hitoriBuild.d.ts +12 -0
  118. package/dist/hitoriBuild.js +117 -0
  119. package/dist/hitoriDraw.d.ts +4 -0
  120. package/dist/hitoriDraw.js +25 -0
  121. package/dist/hitoriGame.d.ts +10 -0
  122. package/dist/hitoriGame.js +48 -0
  123. package/dist/hitoriGenerate.d.ts +10 -0
  124. package/dist/hitoriGenerate.js +65 -0
  125. package/dist/hitoriLogic.d.ts +12 -0
  126. package/dist/hitoriLogic.js +189 -0
  127. package/dist/hitoriMount.d.ts +3 -0
  128. package/dist/hitoriMount.js +111 -0
  129. package/dist/hitoriPlay.types.d.ts +25 -0
  130. package/dist/hitoriPlay.types.js +1 -0
  131. package/dist/hitoriRate.d.ts +3 -0
  132. package/dist/hitoriRate.js +32 -0
  133. package/dist/hitoriSolve.d.ts +9 -0
  134. package/dist/hitoriSolve.js +18 -0
  135. package/dist/hitoriStrings.d.ts +70 -0
  136. package/dist/hitoriStrings.js +17 -0
  137. package/dist/hitoriStyle.d.ts +1 -0
  138. package/dist/hitoriStyle.js +9 -0
  139. package/dist/index.d.ts +11 -0
  140. package/dist/index.js +11 -0
  141. package/dist/juosan-draw-entry.d.ts +2 -0
  142. package/dist/juosan-draw-entry.js +1 -0
  143. package/dist/juosan-entry.d.ts +11 -0
  144. package/dist/juosan-entry.js +10 -0
  145. package/dist/juosan-play-entry.d.ts +4 -0
  146. package/dist/juosan-play-entry.js +3 -0
  147. package/dist/juosan.constants.d.ts +4 -0
  148. package/dist/juosan.constants.js +4 -0
  149. package/dist/juosan.types.d.ts +33 -0
  150. package/dist/juosan.types.js +1 -0
  151. package/dist/juosanBoard.d.ts +7 -0
  152. package/dist/juosanBoard.js +102 -0
  153. package/dist/juosanDraw.d.ts +4 -0
  154. package/dist/juosanDraw.js +49 -0
  155. package/dist/juosanGame.d.ts +20 -0
  156. package/dist/juosanGame.js +86 -0
  157. package/dist/juosanGenerate.d.ts +3 -0
  158. package/dist/juosanGenerate.js +31 -0
  159. package/dist/juosanMount.d.ts +3 -0
  160. package/dist/juosanMount.js +206 -0
  161. package/dist/juosanPlay.types.d.ts +24 -0
  162. package/dist/juosanPlay.types.js +1 -0
  163. package/dist/juosanSolve.d.ts +3 -0
  164. package/dist/juosanSolve.js +82 -0
  165. package/dist/juosanStrings.d.ts +77 -0
  166. package/dist/juosanStrings.js +43 -0
  167. package/dist/juosanStyle.d.ts +1 -0
  168. package/dist/juosanStyle.js +1 -0
  169. package/dist/kakuro-draw-entry.d.ts +2 -0
  170. package/dist/kakuro-draw-entry.js +1 -0
  171. package/dist/kakuro-entry.d.ts +13 -0
  172. package/dist/kakuro-entry.js +11 -0
  173. package/dist/kakuro-play-entry.d.ts +4 -0
  174. package/dist/kakuro-play-entry.js +3 -0
  175. package/dist/kakuro.constants.d.ts +11 -0
  176. package/dist/kakuro.constants.js +11 -0
  177. package/dist/kakuro.types.d.ts +65 -0
  178. package/dist/kakuro.types.js +1 -0
  179. package/dist/kakuroBoard.d.ts +8 -0
  180. package/dist/kakuroBoard.js +117 -0
  181. package/dist/kakuroBuild.d.ts +30 -0
  182. package/dist/kakuroBuild.js +337 -0
  183. package/dist/kakuroDraw.d.ts +10 -0
  184. package/dist/kakuroDraw.js +21 -0
  185. package/dist/kakuroGame.d.ts +12 -0
  186. package/dist/kakuroGame.js +74 -0
  187. package/dist/kakuroGenerate.d.ts +10 -0
  188. package/dist/kakuroGenerate.js +62 -0
  189. package/dist/kakuroLogic.d.ts +13 -0
  190. package/dist/kakuroLogic.js +153 -0
  191. package/dist/kakuroMount.d.ts +2 -0
  192. package/dist/kakuroMount.js +109 -0
  193. package/dist/kakuroPlay.types.d.ts +20 -0
  194. package/dist/kakuroPlay.types.js +1 -0
  195. package/dist/kakuroRate.d.ts +3 -0
  196. package/dist/kakuroRate.js +40 -0
  197. package/dist/kakuroSolve.d.ts +6 -0
  198. package/dist/kakuroSolve.js +33 -0
  199. package/dist/kakuroStrings.d.ts +82 -0
  200. package/dist/kakuroStrings.js +5 -0
  201. package/dist/kakuroStyle.d.ts +1 -0
  202. package/dist/kakuroStyle.js +1 -0
  203. package/dist/kakuroTemplate.d.ts +3 -0
  204. package/dist/kakuroTemplate.js +130 -0
  205. package/dist/masyu-draw-entry.d.ts +2 -0
  206. package/dist/masyu-draw-entry.js +1 -0
  207. package/dist/masyu-entry.d.ts +6 -0
  208. package/dist/masyu-entry.js +6 -0
  209. package/dist/masyu-play-entry.d.ts +4 -0
  210. package/dist/masyu-play-entry.js +3 -0
  211. package/dist/masyu.constants.d.ts +2 -0
  212. package/dist/masyu.constants.js +2 -0
  213. package/dist/masyu.types.d.ts +46 -0
  214. package/dist/masyu.types.js +1 -0
  215. package/dist/masyuBoard.d.ts +10 -0
  216. package/dist/masyuBoard.js +88 -0
  217. package/dist/masyuDraw.d.ts +2 -0
  218. package/dist/masyuDraw.js +33 -0
  219. package/dist/masyuGame.d.ts +9 -0
  220. package/dist/masyuGame.js +46 -0
  221. package/dist/masyuGenerate.d.ts +3 -0
  222. package/dist/masyuGenerate.js +56 -0
  223. package/dist/masyuMount.d.ts +2 -0
  224. package/dist/masyuMount.js +118 -0
  225. package/dist/masyuPlay.types.d.ts +1 -0
  226. package/dist/masyuPlay.types.js +1 -0
  227. package/dist/masyuSolve.d.ts +6 -0
  228. package/dist/masyuSolve.js +88 -0
  229. package/dist/masyuStrings.d.ts +28 -0
  230. package/dist/masyuStrings.js +4 -0
  231. package/dist/masyuStyle.d.ts +1 -0
  232. package/dist/masyuStyle.js +11 -0
  233. package/dist/nurikabe-draw-entry.d.ts +2 -0
  234. package/dist/nurikabe-draw-entry.js +1 -0
  235. package/dist/nurikabe-entry.d.ts +6 -0
  236. package/dist/nurikabe-entry.js +6 -0
  237. package/dist/nurikabe-play-entry.d.ts +4 -0
  238. package/dist/nurikabe-play-entry.js +3 -0
  239. package/dist/nurikabe.constants.d.ts +2 -0
  240. package/dist/nurikabe.constants.js +2 -0
  241. package/dist/nurikabe.types.d.ts +20 -0
  242. package/dist/nurikabe.types.js +1 -0
  243. package/dist/nurikabeBoard.d.ts +8 -0
  244. package/dist/nurikabeBoard.js +72 -0
  245. package/dist/nurikabeDraw.d.ts +4 -0
  246. package/dist/nurikabeDraw.js +15 -0
  247. package/dist/nurikabeGame.d.ts +8 -0
  248. package/dist/nurikabeGame.js +40 -0
  249. package/dist/nurikabeGenerate.d.ts +3 -0
  250. package/dist/nurikabeGenerate.js +31 -0
  251. package/dist/nurikabeMount.d.ts +3 -0
  252. package/dist/nurikabeMount.js +99 -0
  253. package/dist/nurikabePlay.types.d.ts +25 -0
  254. package/dist/nurikabePlay.types.js +1 -0
  255. package/dist/nurikabeSolve.d.ts +6 -0
  256. package/dist/nurikabeSolve.js +75 -0
  257. package/dist/nurikabeStrings.d.ts +70 -0
  258. package/dist/nurikabeStrings.js +5 -0
  259. package/dist/nurikabeStyle.d.ts +1 -0
  260. package/dist/nurikabeStyle.js +9 -0
  261. package/dist/ripple-draw-entry.d.ts +2 -0
  262. package/dist/ripple-draw-entry.js +1 -0
  263. package/dist/ripple-entry.d.ts +12 -0
  264. package/dist/ripple-entry.js +11 -0
  265. package/dist/ripple-play-entry.d.ts +4 -0
  266. package/dist/ripple-play-entry.js +3 -0
  267. package/dist/ripple.constants.d.ts +4 -0
  268. package/dist/ripple.constants.js +4 -0
  269. package/dist/ripple.types.d.ts +34 -0
  270. package/dist/ripple.types.js +1 -0
  271. package/dist/rippleBoard.d.ts +7 -0
  272. package/dist/rippleBoard.js +99 -0
  273. package/dist/rippleDraw.d.ts +3 -0
  274. package/dist/rippleDraw.js +32 -0
  275. package/dist/rippleGame.d.ts +13 -0
  276. package/dist/rippleGame.js +85 -0
  277. package/dist/rippleGenerate.d.ts +3 -0
  278. package/dist/rippleGenerate.js +57 -0
  279. package/dist/rippleMount.d.ts +2 -0
  280. package/dist/rippleMount.js +179 -0
  281. package/dist/ripplePlay.types.d.ts +23 -0
  282. package/dist/ripplePlay.types.js +1 -0
  283. package/dist/rippleSolve.d.ts +6 -0
  284. package/dist/rippleSolve.js +83 -0
  285. package/dist/rippleStrings.d.ts +86 -0
  286. package/dist/rippleStrings.js +5 -0
  287. package/dist/rippleStyle.d.ts +1 -0
  288. package/dist/rippleStyle.js +1 -0
  289. package/dist/shikaku-entry.d.ts +2 -0
  290. package/dist/shikaku-entry.js +2 -0
  291. package/dist/shikaku.constants.d.ts +5 -2
  292. package/dist/shikaku.constants.js +5 -2
  293. package/dist/shikaku.types.d.ts +18 -1
  294. package/dist/shikakuBuild.d.ts +21 -0
  295. package/dist/shikakuBuild.js +135 -0
  296. package/dist/shikakuGenerate.d.ts +6 -1
  297. package/dist/shikakuGenerate.js +50 -35
  298. package/dist/shikakuLogic.d.ts +13 -0
  299. package/dist/shikakuLogic.js +84 -0
  300. package/dist/shikakuPacks.d.ts +27 -0
  301. package/dist/shikakuPacks.js +26 -0
  302. package/dist/shikakuRate.d.ts +3 -0
  303. package/dist/shikakuRate.js +27 -0
  304. package/dist/shikakuSolve.d.ts +1 -1
  305. package/dist/shikakuSolve.js +23 -44
  306. package/dist/shikakuTemplate.d.ts +3 -0
  307. package/dist/shikakuTemplate.js +43 -0
  308. package/dist/slitherlink-draw-entry.d.ts +2 -0
  309. package/dist/slitherlink-draw-entry.js +1 -0
  310. package/dist/slitherlink-entry.d.ts +12 -0
  311. package/dist/slitherlink-entry.js +10 -0
  312. package/dist/slitherlink-play-entry.d.ts +4 -0
  313. package/dist/slitherlink-play-entry.js +3 -0
  314. package/dist/slitherlink.constants.d.ts +7 -0
  315. package/dist/slitherlink.constants.js +7 -0
  316. package/dist/slitherlink.types.d.ts +52 -0
  317. package/dist/slitherlink.types.js +1 -0
  318. package/dist/slitherlinkBoard.d.ts +12 -0
  319. package/dist/slitherlinkBoard.js +132 -0
  320. package/dist/slitherlinkDraw.d.ts +4 -0
  321. package/dist/slitherlinkDraw.js +51 -0
  322. package/dist/slitherlinkGame.d.ts +8 -0
  323. package/dist/slitherlinkGame.js +63 -0
  324. package/dist/slitherlinkGenerate.d.ts +10 -0
  325. package/dist/slitherlinkGenerate.js +182 -0
  326. package/dist/slitherlinkLogic.d.ts +10 -0
  327. package/dist/slitherlinkLogic.js +267 -0
  328. package/dist/slitherlinkMount.d.ts +3 -0
  329. package/dist/slitherlinkMount.js +267 -0
  330. package/dist/slitherlinkPlay.types.d.ts +23 -0
  331. package/dist/slitherlinkPlay.types.js +1 -0
  332. package/dist/slitherlinkRate.d.ts +3 -0
  333. package/dist/slitherlinkRate.js +26 -0
  334. package/dist/slitherlinkSolve.d.ts +6 -0
  335. package/dist/slitherlinkSolve.js +19 -0
  336. package/dist/slitherlinkStrings.d.ts +86 -0
  337. package/dist/slitherlinkStrings.js +47 -0
  338. package/dist/slitherlinkStyle.d.ts +1 -0
  339. package/dist/slitherlinkStyle.js +18 -0
  340. package/dist/slitherlinkTemplate.d.ts +3 -0
  341. package/dist/slitherlinkTemplate.js +101 -0
  342. package/dist/version.d.ts +1 -1
  343. package/dist/version.js +1 -1
  344. package/dist/yajilin-draw-entry.d.ts +2 -0
  345. package/dist/yajilin-draw-entry.js +1 -0
  346. package/dist/yajilin-entry.d.ts +6 -0
  347. package/dist/yajilin-entry.js +6 -0
  348. package/dist/yajilin-play-entry.d.ts +4 -0
  349. package/dist/yajilin-play-entry.js +3 -0
  350. package/dist/yajilin.constants.d.ts +2 -0
  351. package/dist/yajilin.constants.js +2 -0
  352. package/dist/yajilin.types.d.ts +63 -0
  353. package/dist/yajilin.types.js +1 -0
  354. package/dist/yajilinBoard.d.ts +9 -0
  355. package/dist/yajilinBoard.js +91 -0
  356. package/dist/yajilinDraw.d.ts +2 -0
  357. package/dist/yajilinDraw.js +33 -0
  358. package/dist/yajilinGame.d.ts +15 -0
  359. package/dist/yajilinGame.js +58 -0
  360. package/dist/yajilinGenerate.d.ts +3 -0
  361. package/dist/yajilinGenerate.js +224 -0
  362. package/dist/yajilinMount.d.ts +2 -0
  363. package/dist/yajilinMount.js +162 -0
  364. package/dist/yajilinPlay.types.d.ts +1 -0
  365. package/dist/yajilinPlay.types.js +1 -0
  366. package/dist/yajilinSolve.d.ts +6 -0
  367. package/dist/yajilinSolve.js +82 -0
  368. package/dist/yajilinStrings.d.ts +32 -0
  369. package/dist/yajilinStrings.js +4 -0
  370. package/dist/yajilinStyle.d.ts +1 -0
  371. package/dist/yajilinStyle.js +12 -0
  372. package/package.json +180 -3
@@ -0,0 +1,4 @@
1
+ export { mountYajilin } from "./yajilinMount.ts";
2
+ export { YAJILIN_PLAY_STYLE } from "./yajilinStyle.ts";
3
+ export { YAJILIN_STRINGS } from "./yajilinStrings.ts";
4
+ export type * from "./yajilinPlay.types.ts";
@@ -0,0 +1,3 @@
1
+ export { mountYajilin } from "./yajilinMount.js";
2
+ export { YAJILIN_PLAY_STYLE } from "./yajilinStyle.js";
3
+ export { YAJILIN_STRINGS } from "./yajilinStrings.js";
@@ -0,0 +1,2 @@
1
+ export declare const YAJILIN_SIZES: readonly [5, 7];
2
+ export declare const YAJILIN_NODE_BUDGET = 250000;
@@ -0,0 +1,2 @@
1
+ export const YAJILIN_SIZES = [5, 7];
2
+ export const YAJILIN_NODE_BUDGET = 250000;
@@ -0,0 +1,63 @@
1
+ export type YajilinDirection = "up" | "right" | "down" | "left";
2
+ export type YajilinClue = {
3
+ direction: YajilinDirection;
4
+ count: number;
5
+ };
6
+ export type YajilinBoard = {
7
+ width: number;
8
+ height: number;
9
+ clues: readonly (YajilinClue | null)[];
10
+ };
11
+ export type YajilinPuzzle = YajilinBoard & {
12
+ seed: number;
13
+ solution: {
14
+ shaded: readonly boolean[];
15
+ edges: readonly number[];
16
+ };
17
+ };
18
+ export type YajilinCheck = {
19
+ ok: boolean;
20
+ errors: readonly number[];
21
+ };
22
+ export type YajilinSolution = {
23
+ shaded: readonly boolean[];
24
+ edges: readonly number[];
25
+ };
26
+ export type YajilinSolve = {
27
+ count: number;
28
+ solution: YajilinSolution | null;
29
+ complete: boolean;
30
+ nodes: number;
31
+ };
32
+ export type YajilinGame = {
33
+ board: YajilinBoard;
34
+ shaded: readonly boolean[];
35
+ edges: readonly number[];
36
+ history: readonly {
37
+ shaded: readonly boolean[];
38
+ edges: readonly number[];
39
+ }[];
40
+ helped: boolean;
41
+ };
42
+ export type YajilinDrawOptions = {
43
+ shaded?: readonly boolean[];
44
+ edges?: readonly number[];
45
+ selected?: number;
46
+ errors?: readonly number[];
47
+ material?: "ivory" | "wood" | "slate";
48
+ pieces?: "plain" | "tiles";
49
+ language?: "en" | "ja";
50
+ };
51
+ export type YajilinMountOptions = YajilinDrawOptions & {
52
+ board: YajilinBoard;
53
+ progress?: string;
54
+ onChange?: (game: YajilinGame) => void;
55
+ onFinish?: (game: YajilinGame) => void;
56
+ };
57
+ export type YajilinMount = {
58
+ game: () => YajilinGame;
59
+ progress: () => string;
60
+ set: (options: YajilinDrawOptions) => void;
61
+ restart: () => void;
62
+ destroy: () => void;
63
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { YajilinBoard, YajilinCheck, YajilinDirection } from "./yajilin.types.ts";
2
+ export declare const yajilinEdgeCount: (board: YajilinBoard) => number;
3
+ export declare function isYajilinBoard(value: unknown): value is YajilinBoard;
4
+ export declare function yajilinNeighbors(board: YajilinBoard, cell: number): {
5
+ cell: number;
6
+ edge: number;
7
+ }[];
8
+ export declare function checkYajilin(board: YajilinBoard, shaded: readonly boolean[], lines: readonly number[]): YajilinCheck;
9
+ export declare function yajilinRay(board: YajilinBoard, cell: number, direction: YajilinDirection): number[];
@@ -0,0 +1,91 @@
1
+ import { YAJILIN_SIZES } from "./yajilin.constants.js";
2
+ const directionDelta = { up: [0, -1], right: [1, 0], down: [0, 1], left: [-1, 0] };
3
+ export const yajilinEdgeCount = (board) => board.height * (board.width - 1) + board.width * (board.height - 1);
4
+ export function isYajilinBoard(value) {
5
+ if (!value || typeof value !== "object")
6
+ return false;
7
+ const board = value;
8
+ if (!YAJILIN_SIZES.includes(board.width) || board.width !== board.height
9
+ || !Array.isArray(board.clues) || board.clues.length !== board.width * board.height)
10
+ return false;
11
+ return board.clues.every(clue => clue === null || (!!clue && typeof clue === "object"
12
+ && Object.hasOwn(directionDelta, clue.direction) && Number.isInteger(clue.count) && clue.count >= 0 && clue.count < board.width));
13
+ }
14
+ export function yajilinNeighbors(board, cell) {
15
+ const x = cell % board.width, y = Math.floor(cell / board.width), horizontal = board.height * (board.width - 1), result = [];
16
+ if (y > 0)
17
+ result.push({ cell: cell - board.width, edge: horizontal + (y - 1) * board.width + x });
18
+ if (x < board.width - 1)
19
+ result.push({ cell: cell + 1, edge: y * (board.width - 1) + x });
20
+ if (y < board.height - 1)
21
+ result.push({ cell: cell + board.width, edge: horizontal + y * board.width + x });
22
+ if (x > 0)
23
+ result.push({ cell: cell - 1, edge: y * (board.width - 1) + x - 1 });
24
+ return result;
25
+ }
26
+ function ray(board, cell, direction) {
27
+ const [dx, dy] = directionDelta[direction], cells = [];
28
+ let x = cell % board.width + dx, y = Math.floor(cell / board.width) + dy;
29
+ while (x >= 0 && x < board.width && y >= 0 && y < board.height) {
30
+ cells.push(y * board.width + x);
31
+ x += dx;
32
+ y += dy;
33
+ }
34
+ return cells;
35
+ }
36
+ export function checkYajilin(board, shaded, lines) {
37
+ if (!isYajilinBoard(board))
38
+ throw new RangeError("Invalid Yajilin board");
39
+ const size = board.width, total = size * size, edges = new Set(lines), errors = new Set();
40
+ if (shaded.length !== total || !shaded.every(value => typeof value === "boolean"))
41
+ return { ok: false, errors: [] };
42
+ if (edges.size !== lines.length || lines.some(edge => !Number.isInteger(edge) || edge < 0 || edge >= yajilinEdgeCount(board)))
43
+ return { ok: false, errors: [] };
44
+ for (let cell = 0; cell < total; cell += 1) {
45
+ const clue = board.clues[cell];
46
+ if (clue && shaded[cell])
47
+ errors.add(cell);
48
+ if (shaded[cell]) {
49
+ if (cell % size < size - 1 && shaded[cell + 1]) {
50
+ errors.add(cell);
51
+ errors.add(cell + 1);
52
+ }
53
+ if (cell + size < total && shaded[cell + size]) {
54
+ errors.add(cell);
55
+ errors.add(cell + size);
56
+ }
57
+ }
58
+ if (clue && ray(board, cell, clue.direction).filter(next => shaded[next]).length !== clue.count)
59
+ errors.add(cell);
60
+ }
61
+ const degrees = board.clues.map((clue, cell) => {
62
+ const degree = yajilinNeighbors(board, cell).filter(next => edges.has(next.edge)).length;
63
+ if ((clue || shaded[cell]) && degree > 0)
64
+ errors.add(cell);
65
+ if (!clue && !shaded[cell] && degree !== 2)
66
+ errors.add(cell);
67
+ return degree;
68
+ });
69
+ if (edges.size) {
70
+ const first = degrees.findIndex(degree => degree > 0), reached = new Set([first]), stack = [first];
71
+ while (stack.length) {
72
+ const cell = stack.pop();
73
+ for (const next of yajilinNeighbors(board, cell))
74
+ if (edges.has(next.edge) && !reached.has(next.cell)) {
75
+ reached.add(next.cell);
76
+ stack.push(next.cell);
77
+ }
78
+ }
79
+ const loopCells = degrees.filter(degree => degree > 0).length;
80
+ if (reached.size !== loopCells || edges.size !== loopCells)
81
+ for (const cell of reached)
82
+ errors.add(cell);
83
+ }
84
+ const playable = board.clues.filter((clue, cell) => !clue && !shaded[cell]).length;
85
+ const ok = playable >= 4 && edges.size === playable && errors.size === 0
86
+ && degrees.every((degree, cell) => board.clues[cell] || shaded[cell] ? degree === 0 : degree === 2);
87
+ return { ok, errors: [...errors] };
88
+ }
89
+ export function yajilinRay(board, cell, direction) {
90
+ return ray(board, cell, direction);
91
+ }
@@ -0,0 +1,2 @@
1
+ import type { YajilinBoard, YajilinDrawOptions } from "./yajilin.types.ts";
2
+ export declare function drawYajilin(board: YajilinBoard, options?: YajilinDrawOptions): string;
@@ -0,0 +1,33 @@
1
+ import { isYajilinBoard, yajilinNeighbors } from "./yajilinBoard.js";
2
+ import { YAJILIN_STRINGS } from "./yajilinStrings.js";
3
+ const arrows = { up: "↑", right: "→", down: "↓", left: "←" };
4
+ export function drawYajilin(board, options = {}) {
5
+ if (!isYajilinBoard(board))
6
+ throw new RangeError("Invalid Yajilin board");
7
+ const words = YAJILIN_STRINGS[options.language ?? "en"], size = 52, pad = 14;
8
+ const palette = { ivory: ["var(--kz-paper,#fbf8f1)", "var(--kz-ink,#1f2320)", "var(--kz-grid,#cfc6b2)"], wood: ["#e5cda6", "#493e2f", "#bca582"], slate: ["#262a27", "#ece8dc", "#454a44"] };
9
+ const [paper, ink, grid] = palette[options.material ?? "ivory"], edges = new Set(options.edges ?? []), parts = [];
10
+ for (let cell = 0; cell < board.clues.length; cell += 1) {
11
+ const x = pad + cell % board.width * size, y = pad + Math.floor(cell / board.width) * size, clue = board.clues[cell];
12
+ const bad = options.errors?.includes(cell), active = options.selected === cell;
13
+ parts.push(`<rect x="${x - size / 2}" y="${y - size / 2}" width="${size}" height="${size}" fill="${active ? ink : "transparent"}" fill-opacity="${active ? ".08" : "1"}" stroke="${grid}" stroke-width="1"/>`);
14
+ if (options.shaded?.[cell])
15
+ parts.push(`<rect x="${x - 17}" y="${y - 17}" width="34" height="34" rx="2" fill="${bad ? "var(--kz-bad,#b5452c)" : ink}"/>`);
16
+ if (clue) {
17
+ if (options.pieces === "tiles")
18
+ parts.push(`<rect x="${x - 19}" y="${y - 19}" width="38" height="38" rx="5" fill="${paper}" stroke="${grid}"/>`);
19
+ parts.push(`<text x="${x - 2}" y="${y + 1}" text-anchor="middle" dominant-baseline="middle" fill="${bad ? "var(--kz-bad,#b5452c)" : ink}" font-size="20" font-weight="700" font-family="system-ui,sans-serif">${arrows[clue.direction]}</text>`);
20
+ parts.push(`<text x="${x + 11}" y="${y + 14}" text-anchor="middle" dominant-baseline="middle" fill="${ink}" font-size="12" font-weight="700" font-family="system-ui,sans-serif">${clue.count}</text>`);
21
+ }
22
+ for (const next of yajilinNeighbors(board, cell))
23
+ if (cell < next.cell && edges.has(next.edge)) {
24
+ const nx = pad + next.cell % board.width * size, ny = pad + Math.floor(next.cell / board.width) * size;
25
+ parts.push(`<line x1="${x}" y1="${y}" x2="${nx}" y2="${ny}" stroke="${bad ? "var(--kz-bad,#b5452c)" : ink}" stroke-width="5" stroke-linecap="round"/>`);
26
+ }
27
+ }
28
+ for (let y = 0; y < board.height; y += 1)
29
+ for (let x = 0; x < board.width; x += 1) {
30
+ parts.push(`<circle cx="${pad + x * size}" cy="${pad + y * size}" r="2" fill="${grid}"/>`);
31
+ }
32
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pad * 2 + (board.width - 1) * size} ${pad * 2 + (board.height - 1) * size}" role="img" aria-label="${words.title}" style="display:block;width:100%;height:auto;background:${paper}">${parts.join("")}</svg>`;
33
+ }
@@ -0,0 +1,15 @@
1
+ import type { YajilinBoard, YajilinGame } from "./yajilin.types.ts";
2
+ export declare function newYajilin(board: YajilinBoard): YajilinGame;
3
+ export declare function toggleYajilinShade(game: YajilinGame, cell: number): YajilinGame;
4
+ export declare function toggleYajilinEdge(game: YajilinGame, edge: number): YajilinGame;
5
+ export declare function undoYajilin(game: YajilinGame): YajilinGame;
6
+ export declare function restartYajilin(game: YajilinGame): YajilinGame;
7
+ export declare function hintYajilin(game: YajilinGame): {
8
+ type: "shade";
9
+ cell: number;
10
+ } | {
11
+ type: "edge";
12
+ edge: number;
13
+ } | null;
14
+ export declare function encodeYajilin(game: YajilinGame): string;
15
+ export declare function decodeYajilin(code: string): YajilinGame | null;
@@ -0,0 +1,58 @@
1
+ import { isYajilinBoard, yajilinEdgeCount } from "./yajilinBoard.js";
2
+ import { solveYajilin } from "./yajilinSolve.js";
3
+ export function newYajilin(board) {
4
+ if (!isYajilinBoard(board))
5
+ throw new RangeError("Invalid Yajilin board");
6
+ return { board: { width: board.width, height: board.height, clues: board.clues.map(clue => clue ? { ...clue } : null) }, shaded: Array(board.width * board.height).fill(false), edges: [], history: [], helped: false };
7
+ }
8
+ function snapshot(game) { return { shaded: [...game.shaded], edges: [...game.edges] }; }
9
+ export function toggleYajilinShade(game, cell) {
10
+ if (!Number.isInteger(cell) || cell < 0 || cell >= game.shaded.length || game.board.clues[cell])
11
+ return game;
12
+ const shaded = [...game.shaded];
13
+ shaded[cell] = !shaded[cell];
14
+ return { ...game, shaded, history: [...game.history, snapshot(game)] };
15
+ }
16
+ export function toggleYajilinEdge(game, edge) {
17
+ if (!Number.isInteger(edge) || edge < 0 || edge >= yajilinEdgeCount(game.board))
18
+ return game;
19
+ const edges = game.edges.includes(edge) ? game.edges.filter(value => value !== edge) : [...game.edges, edge].sort((a, b) => a - b);
20
+ return { ...game, edges, history: [...game.history, snapshot(game)] };
21
+ }
22
+ export function undoYajilin(game) {
23
+ const previous = game.history.at(-1);
24
+ return previous ? { ...game, shaded: [...previous.shaded], edges: [...previous.edges], history: game.history.slice(0, -1) } : game;
25
+ }
26
+ export function restartYajilin(game) { return { ...newYajilin(game.board), helped: false }; }
27
+ export function hintYajilin(game) {
28
+ const result = solveYajilin(game.board);
29
+ if (!result.complete || result.count !== 1)
30
+ return null;
31
+ const cell = result.solution.shaded.findIndex((value, index) => value !== game.shaded[index]);
32
+ if (cell >= 0)
33
+ return { type: "shade", cell };
34
+ const edge = result.solution.edges.find(value => !game.edges.includes(value));
35
+ return edge === undefined ? null : { type: "edge", edge };
36
+ }
37
+ export function encodeYajilin(game) {
38
+ return JSON.stringify({ version: 1, board: game.board, shaded: game.shaded, edges: game.edges, helped: game.helped });
39
+ }
40
+ export function decodeYajilin(code) {
41
+ try {
42
+ if (code.length > 40000)
43
+ return null;
44
+ const value = JSON.parse(code);
45
+ if (value.version !== 1 || !isYajilinBoard(value.board) || !Array.isArray(value.shaded)
46
+ || value.shaded.length !== value.board.width * value.board.height || !value.shaded.every((cell) => typeof cell === "boolean")
47
+ || !Array.isArray(value.edges) || !value.edges.every((edge) => Number.isInteger(edge))
48
+ || typeof value.helped !== "boolean")
49
+ return null;
50
+ const edges = [...new Set(value.edges)].sort((a, b) => a - b);
51
+ if (edges.length !== value.edges.length || edges.some(edge => edge < 0 || edge >= yajilinEdgeCount(value.board)))
52
+ return null;
53
+ return { ...newYajilin(value.board), shaded: [...value.shaded], edges, helped: value.helped };
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ }
@@ -0,0 +1,3 @@
1
+ import type { YajilinPuzzle } from "./yajilin.types.ts";
2
+ /** Seeded original 5×5 families, accepted only after a completed uniqueness proof. */
3
+ export declare function generateYajilin(size?: 5, seed?: number): YajilinPuzzle;
@@ -0,0 +1,224 @@
1
+ import { isKazuSeed, seededRandom } from "./random.js";
2
+ import { checkYajilin, isYajilinBoard, yajilinNeighbors } from "./yajilinBoard.js";
3
+ import { solveYajilin } from "./yajilinSolve.js";
4
+ const layouts = [
5
+ {
6
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
7
+ shaded: [1, 22, 5, 9, 24, 12, 20],
8
+ clues: [
9
+ [0, "left", 0],
10
+ [2, "up", 0],
11
+ [3, "up", 0],
12
+ [4, "down", 2],
13
+ [10, "up", 1],
14
+ [14, "down", 1],
15
+ [15, "left", 0],
16
+ [19, "up", 1],
17
+ [21, "down", 0],
18
+ [23, "up", 0],
19
+ ],
20
+ },
21
+ {
22
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
23
+ shaded: [0, 21, 15, 2, 14, 4, 12],
24
+ clues: [
25
+ [1, "right", 2],
26
+ [3, "left", 2],
27
+ [5, "down", 1],
28
+ [9, "right", 0],
29
+ [10, "down", 1],
30
+ [19, "up", 2],
31
+ [20, "left", 0],
32
+ [22, "up", 2],
33
+ [23, "right", 0],
34
+ [24, "down", 0],
35
+ ],
36
+ },
37
+ {
38
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
39
+ shaded: [24, 12, 22, 4, 15, 0, 2],
40
+ clues: [
41
+ [1, "right", 2],
42
+ [3, "down", 0],
43
+ [5, "down", 1],
44
+ [9, "right", 0],
45
+ [10, "left", 0],
46
+ [14, "up", 1],
47
+ [19, "left", 1],
48
+ [20, "left", 0],
49
+ [21, "down", 0],
50
+ [23, "right", 1],
51
+ ],
52
+ },
53
+ {
54
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
55
+ shaded: [12, 9, 2, 21, 0, 19, 10],
56
+ clues: [
57
+ [1, "right", 1],
58
+ [3, "up", 0],
59
+ [4, "down", 2],
60
+ [5, "up", 1],
61
+ [14, "left", 2],
62
+ [15, "right", 1],
63
+ [20, "down", 0],
64
+ [22, "up", 2],
65
+ [23, "up", 0],
66
+ [24, "up", 2],
67
+ ],
68
+ },
69
+ {
70
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
71
+ shaded: [20, 3, 22, 14, 1, 12, 24],
72
+ clues: [
73
+ [0, "left", 0],
74
+ [2, "down", 2],
75
+ [4, "up", 0],
76
+ [5, "right", 0],
77
+ [9, "down", 2],
78
+ [10, "up", 0],
79
+ [15, "right", 0],
80
+ [19, "up", 1],
81
+ [21, "right", 2],
82
+ [23, "up", 1],
83
+ ],
84
+ },
85
+ {
86
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
87
+ shaded: [14, 3, 21, 15, 24, 0, 12],
88
+ clues: [
89
+ [1, "up", 0],
90
+ [2, "right", 1],
91
+ [4, "left", 2],
92
+ [5, "right", 0],
93
+ [9, "left", 0],
94
+ [10, "down", 1],
95
+ [19, "left", 1],
96
+ [20, "right", 2],
97
+ [22, "right", 1],
98
+ [23, "left", 1],
99
+ ],
100
+ },
101
+ {
102
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
103
+ shaded: [15, 24, 9, 21, 5, 3, 1],
104
+ clues: [
105
+ [0, "left", 0],
106
+ [2, "right", 1],
107
+ [4, "right", 0],
108
+ [10, "up", 1],
109
+ [12, "down", 0],
110
+ [14, "right", 0],
111
+ [19, "left", 1],
112
+ [20, "down", 0],
113
+ [22, "up", 0],
114
+ [23, "down", 0],
115
+ ],
116
+ },
117
+ {
118
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
119
+ shaded: [4, 2, 0, 10, 23, 21, 19],
120
+ clues: [
121
+ [1, "right", 2],
122
+ [3, "left", 2],
123
+ [5, "up", 1],
124
+ [9, "down", 1],
125
+ [12, "down", 0],
126
+ [14, "up", 1],
127
+ [15, "right", 1],
128
+ [20, "right", 2],
129
+ [22, "right", 1],
130
+ [24, "up", 2],
131
+ ],
132
+ },
133
+ {
134
+ loop: [6, 7, 8, 13, 18, 23, 22, 21, 16, 11],
135
+ shaded: [10, 4, 2, 17, 0, 24],
136
+ clues: [
137
+ [1, "right", 2],
138
+ [3, "up", 0],
139
+ [5, "down", 1],
140
+ [9, "down", 1],
141
+ [12, "down", 1],
142
+ [14, "up", 1],
143
+ [15, "right", 1],
144
+ [19, "left", 1],
145
+ [20, "down", 0],
146
+ ],
147
+ },
148
+ {
149
+ loop: [6, 7, 8, 13, 18, 23, 22, 21, 16, 11],
150
+ shaded: [3, 15, 19, 17, 1, 5],
151
+ clues: [
152
+ [0, "left", 0],
153
+ [2, "right", 1],
154
+ [4, "down", 1],
155
+ [9, "down", 1],
156
+ [10, "down", 1],
157
+ [12, "right", 0],
158
+ [14, "down", 1],
159
+ [20, "left", 0],
160
+ [24, "up", 1],
161
+ ],
162
+ },
163
+ {
164
+ loop: [6, 7, 8, 13, 18, 23, 22, 21, 16, 11],
165
+ shaded: [2, 17, 4, 0, 20, 10],
166
+ clues: [
167
+ [1, "left", 1],
168
+ [3, "right", 1],
169
+ [5, "up", 1],
170
+ [9, "left", 0],
171
+ [12, "up", 1],
172
+ [14, "down", 0],
173
+ [15, "up", 2],
174
+ [19, "right", 0],
175
+ [24, "down", 0],
176
+ ],
177
+ },
178
+ ];
179
+ function transformCell(cell, turns, reflect) {
180
+ let x = cell % 5, y = Math.floor(cell / 5);
181
+ if (reflect)
182
+ x = 4 - x;
183
+ for (let turn = 0; turn < turns; turn += 1)
184
+ [x, y] = [4 - y, x];
185
+ return y * 5 + x;
186
+ }
187
+ function transformDirection(direction, turns, reflect) {
188
+ const vector = { up: [0, -1], right: [1, 0], down: [0, 1], left: [-1, 0] };
189
+ let [x, y] = vector[direction];
190
+ if (reflect)
191
+ x = -x;
192
+ for (let turn = 0; turn < turns; turn += 1)
193
+ [x, y] = [-y, x];
194
+ return (Object.entries(vector).find(([, value]) => value[0] === x && value[1] === y)?.[0] ?? "up");
195
+ }
196
+ function edgesFromLoop(board, loop) {
197
+ return loop.map((cell, index) => {
198
+ const next = loop[(index + 1) % loop.length];
199
+ return yajilinNeighbors(board, cell).find(item => item.cell === next).edge;
200
+ }).sort((a, b) => a - b);
201
+ }
202
+ /** Seeded original 5×5 families, accepted only after a completed uniqueness proof. */
203
+ export function generateYajilin(size = 5, seed = 1) {
204
+ if (size !== 5 || !isKazuSeed(seed))
205
+ throw new RangeError("Invalid Yajilin settings");
206
+ const random = seededRandom(seed), layout = layouts[Math.floor(random() * layouts.length)];
207
+ const turns = Math.floor(random() * 4), reflect = random() < 0.5;
208
+ const clues = Array(25).fill(null);
209
+ for (const [cell, direction, count] of layout.clues) {
210
+ const transformed = transformCell(cell, turns, reflect);
211
+ clues[transformed] = { direction: transformDirection(direction, turns, reflect), count };
212
+ }
213
+ const board = { width: 5, height: 5, clues };
214
+ const shaded = Array(25).fill(false);
215
+ for (const cell of layout.shaded)
216
+ shaded[transformCell(cell, turns, reflect)] = true;
217
+ const expectedEdges = edgesFromLoop(board, layout.loop.map(cell => transformCell(cell, turns, reflect)));
218
+ if (!isYajilinBoard(board) || !checkYajilin(board, shaded, expectedEdges).ok)
219
+ throw new Error("Invalid Yajilin layout");
220
+ const proof = solveYajilin(board);
221
+ if (!proof.complete || proof.count !== 1 || !proof.solution)
222
+ throw new Error("No uniquely proved Yajilin found within the generation budget; try another seed");
223
+ return { ...board, seed, solution: proof.solution };
224
+ }
@@ -0,0 +1,2 @@
1
+ import type { YajilinMount, YajilinMountOptions } from "./yajilin.types.ts";
2
+ export declare function mountYajilin(element: HTMLElement, initial: YajilinMountOptions): YajilinMount;