@johnmorrisdotca/kumimoji 1.2.2 → 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 (76) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/README.md +80 -39
  3. package/dist/check.d.ts +26 -1
  4. package/dist/check.js +26 -1
  5. package/dist/computer.types.d.ts +24 -2
  6. package/dist/computerPlay.d.ts +45 -2
  7. package/dist/computerPlay.js +45 -2
  8. package/dist/computerTurn.d.ts +42 -3
  9. package/dist/computerTurn.js +42 -3
  10. package/dist/daily.d.ts +22 -2
  11. package/dist/daily.js +22 -2
  12. package/dist/element-define.d.ts +1 -1
  13. package/dist/element-define.js +3 -13
  14. package/dist/element.d.ts +85 -4
  15. package/dist/element.js +176 -45
  16. package/dist/embed-day.d.ts +4 -0
  17. package/dist/embed-day.js +23 -0
  18. package/dist/export.d.ts +123 -6
  19. package/dist/export.js +91 -4
  20. package/dist/generate.d.ts +14 -0
  21. package/dist/generate.js +14 -0
  22. package/dist/grid.d.ts +181 -10
  23. package/dist/grid.js +122 -7
  24. package/dist/help.d.ts +36 -3
  25. package/dist/help.js +36 -3
  26. package/dist/judge.d.ts +14 -0
  27. package/dist/judge.js +14 -0
  28. package/dist/kana.d.ts +23 -1
  29. package/dist/kana.js +23 -1
  30. package/dist/kumimoji.types.d.ts +70 -5
  31. package/dist/party.d.ts +268 -14
  32. package/dist/party.js +268 -14
  33. package/dist/party.types.d.ts +50 -2
  34. package/dist/partyKept.d.ts +74 -4
  35. package/dist/partyKept.js +74 -4
  36. package/dist/partySeats.d.ts +92 -6
  37. package/dist/partySeats.js +72 -4
  38. package/dist/partyTurns.d.ts +171 -5
  39. package/dist/partyTurns.js +171 -5
  40. package/dist/placement.d.ts +50 -2
  41. package/dist/placement.js +30 -0
  42. package/dist/play.d.ts +247 -15
  43. package/dist/play.js +237 -15
  44. package/dist/random.d.ts +34 -3
  45. package/dist/random.js +23 -2
  46. package/dist/react.d.ts +42 -4
  47. package/dist/react.js +22 -5
  48. package/dist/showcase.d.ts +83 -7
  49. package/dist/showcase.js +49 -4
  50. package/dist/strings.d.ts +54 -5
  51. package/dist/strings.js +34 -3
  52. package/dist/tableView.d.ts +151 -8
  53. package/dist/tableView.js +129 -6
  54. package/dist/tileFace.d.ts +59 -5
  55. package/dist/tileFace.js +48 -4
  56. package/dist/tileFamily.d.ts +9 -0
  57. package/dist/tileFamily.js +9 -0
  58. package/dist/tileWords.d.ts +93 -6
  59. package/dist/tileWords.js +83 -6
  60. package/dist/tileWordsModule.d.ts +11 -1
  61. package/dist/tileWordsModule.js +11 -1
  62. package/dist/tiles.constants.d.ts +99 -5
  63. package/dist/tiles.constants.js +99 -5
  64. package/dist/turn.d.ts +82 -4
  65. package/dist/turn.js +82 -4
  66. package/dist/ui/board.d.ts +60 -5
  67. package/dist/ui/board.js +28 -2
  68. package/dist/ui/mount.d.ts +41 -2
  69. package/dist/ui/mount.js +38 -1
  70. package/dist/ui/style.d.ts +6 -1
  71. package/dist/ui/style.js +6 -0
  72. package/dist/version.d.ts +9 -2
  73. package/dist/version.js +9 -2
  74. package/dist/wilds.d.ts +22 -1
  75. package/dist/wilds.js +22 -1
  76. package/package.json +64 -56
package/dist/grid.js CHANGED
@@ -1,14 +1,46 @@
1
1
  import { KUMIMOJI_GRID_MOST } from "./tiles.constants.js";
2
- /** A square's name, "row,col". */
2
+ /** A square's name, "row,col".
3
+ *
4
+ * @param row - The integer row coordinate, which may be negative.
5
+ * @param col - The integer column coordinate, which may be negative.
6
+ * @returns A square's name, "row,col".
7
+ * @example
8
+ * ```ts
9
+ * import { squareAt } from "@johnmorrisdotca/kumimoji";
10
+ *
11
+ * console.log(squareAt(-1,2));
12
+ * ```
13
+ */
3
14
  export function squareAt(row, col) {
4
15
  return `${row},${col}`;
5
16
  }
6
- /** A square's row and column, from its name. */
17
+ /** A square's row and column, from its name.
18
+ *
19
+ * @param square - The row,column square name.
20
+ * @returns A square's row and column, from its name.
21
+ * @example
22
+ * ```ts
23
+ * import { placeOf } from "@johnmorrisdotca/kumimoji";
24
+ *
25
+ * console.log(placeOf("-1,2"));
26
+ * ```
27
+ */
7
28
  export function placeOf(square) {
8
29
  const [row, col] = square.split(",").map(Number);
9
30
  return { row: row, col: col };
10
31
  }
11
- /** The rows and columns the tiles stand within, or null for no tiles. */
32
+ /** The rows and columns the tiles stand within, or null for no tiles.
33
+ *
34
+ * @param tiles - The map from row,column square names to internal tile codes.
35
+ * @returns The rows and columns the tiles stand within, or null for no tiles.
36
+ * @example
37
+ * ```ts
38
+ * import { boundsOf } from "@johnmorrisdotca/kumimoji";
39
+ *
40
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
41
+ * console.log(boundsOf(tiles));
42
+ * ```
43
+ */
12
44
  export function boundsOf(tiles) {
13
45
  let bounds = null;
14
46
  for (const square of tiles.keys()) {
@@ -20,7 +52,18 @@ export function boundsOf(tiles) {
20
52
  }
21
53
  return bounds;
22
54
  }
23
- /** A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back. */
55
+ /** A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back.
56
+ *
57
+ * @param tiles - The map from row,column square names to internal tile codes.
58
+ * @returns A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back.
59
+ * @example
60
+ * ```ts
61
+ * import { encodeGrid } from "@johnmorrisdotca/kumimoji";
62
+ *
63
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
64
+ * console.log(encodeGrid(tiles));
65
+ * ```
66
+ */
24
67
  export function encodeGrid(tiles) {
25
68
  const bounds = boundsOf(tiles);
26
69
  if (bounds === null)
@@ -48,6 +91,15 @@ export function encodeGrid(tiles) {
48
91
  * A grid read back, its first row at row 0, or null for anything that is not
49
92
  * one: a stray character, a capital, a grid wider or taller than any grid of
50
93
  * fifty tiles can be. An empty string is no tiles.
94
+ *
95
+ * @param code - The encoded grid or progress text.
96
+ * @returns A grid read back, its first row at row 0, or null for anything that is not one: a stray character, a capital, a grid wider or taller than any grid of fifty tiles can be. An empty string is no tiles.
97
+ * @example
98
+ * ```ts
99
+ * import { decodeGrid } from "@johnmorrisdotca/kumimoji";
100
+ *
101
+ * console.log(decodeGrid("cat"));
102
+ * ```
51
103
  */
52
104
  export function decodeGrid(code) {
53
105
  if (typeof code !== "string")
@@ -97,7 +149,17 @@ export function decodeGrid(code) {
97
149
  }
98
150
  return tiles;
99
151
  }
100
- /** How many of each letter. */
152
+ /** How many of each letter.
153
+ *
154
+ * @param letters - The iterable tile letters to count.
155
+ * @returns How many of each letter.
156
+ * @example
157
+ * ```ts
158
+ * import { lettersOf } from "@johnmorrisdotca/kumimoji";
159
+ *
160
+ * console.log(lettersOf("cat"));
161
+ * ```
162
+ */
101
163
  export function lettersOf(letters) {
102
164
  const counts = new Map();
103
165
  for (const letter of letters)
@@ -105,7 +167,18 @@ export function lettersOf(letters) {
105
167
  counts.set(letter, (counts.get(letter) ?? 0) + 1);
106
168
  return counts;
107
169
  }
108
- /** Whether two tallies hold the same letters, as many of each. */
170
+ /** Whether two tallies hold the same letters, as many of each.
171
+ *
172
+ * @param a - The first letter-count map.
173
+ * @param b - The second letter-count map.
174
+ * @returns Whether two tallies hold the same letters, as many of each.
175
+ * @example
176
+ * ```ts
177
+ * import { lettersOf, sameLetters } from "@johnmorrisdotca/kumimoji";
178
+ *
179
+ * console.log(sameLetters(lettersOf("cat"),lettersOf("act")));
180
+ * ```
181
+ */
109
182
  export function sameLetters(a, b) {
110
183
  if (a.size !== b.size)
111
184
  return false;
@@ -121,6 +194,12 @@ const STEP = { across: [0, 1], down: [1, 0], downRight: [1, 1], downLeft: [1, -1
121
194
  * at a corner are what every crossword is full of — the letter above a word
122
195
  * and the one beside it — so a pair is free, and only three or more in a
123
196
  * line are a diagonal word.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * import { DIAGONAL_RUN_LEAST } from "@johnmorrisdotca/kumimoji";
201
+ * console.log(DIAGONAL_RUN_LEAST);
202
+ * ```
124
203
  */
125
204
  export const DIAGONAL_RUN_LEAST = 3;
126
205
  function runsAlong(tiles, line, least) {
@@ -147,6 +226,17 @@ function runsAlong(tiles, line, least) {
147
226
  * Every run the grid is read by: two or more tiles across, then down, and
148
227
  * with Diagonals three or more down to the right, then down to the left. A
149
228
  * tile with nothing beside it in a line is no run.
229
+ *
230
+ * @param tiles - The map from row,column square names to internal tile codes.
231
+ * @param rules - Whether diagonal runs are also judged.
232
+ * @returns Every run the grid is read by: two or more tiles across, then down, and with Diagonals three or more down to the right, then down to the left. A tile with nothing beside it in a line is no run.
233
+ * @example
234
+ * ```ts
235
+ * import { runsOf } from "@johnmorrisdotca/kumimoji";
236
+ *
237
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
238
+ * console.log(runsOf(tiles));
239
+ * ```
150
240
  */
151
241
  export function runsOf(tiles, rules = {}) {
152
242
  const runs = [...runsAlong(tiles, "across", 2), ...runsAlong(tiles, "down", 2)];
@@ -160,6 +250,17 @@ export function runsOf(tiles, rules = {}) {
160
250
  * other in one of those runs are joined too: a diagonal word holds a
161
251
  * crossword together as a word across does. A pair touching at a corner is
162
252
  * never a link, because it is never read.
253
+ *
254
+ * @param tiles - The map from row,column square names to internal tile codes.
255
+ * @param links - The runs connecting groups; computed from the grid when omitted.
256
+ * @returns The tiles in groups that touch across or down, largest first. With `links` — the diagonal runs a grid with Diagonals reads — the tiles next to each other in one of those runs are joined too: a diagonal word holds a crossword together as a word across does. A pair touching at a corner is never a link, because it is never read.
257
+ * @example
258
+ * ```ts
259
+ * import { groupsOf } from "@johnmorrisdotca/kumimoji";
260
+ *
261
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
262
+ * console.log(groupsOf(tiles));
263
+ * ```
163
264
  */
164
265
  export function groupsOf(tiles, links = []) {
165
266
  const joined = new Map();
@@ -193,7 +294,21 @@ export function groupsOf(tiles, links = []) {
193
294
  }
194
295
  return groups.sort((a, b) => b.length - a.length);
195
296
  }
196
- /** A grid judged against any test of a word: `isWord` answers for a run as spelt, and `readable` says how to name one that is not. `judgeWithWords` is this with a language's list. */
297
+ /** A grid judged against any test of a word: `isWord` answers for a run as spelt, and `readable` says how to name one that is not. `judgeWithWords` is this with a language's list.
298
+ *
299
+ * @param tiles - The map from row,column square names to internal tile codes.
300
+ * @param isWord - The predicate that accepts a readable word.
301
+ * @param readable - The conversion from tile codes to readable words.
302
+ * @param rules - Whether diagonal runs are also judged.
303
+ * @returns A grid judged against any test of a word: `isWord` answers for a run as spelt, and `readable` says how to name one that is not. `judgeWithWords` is this with a language's list.
304
+ * @example
305
+ * ```ts
306
+ * import { judgeGrid } from "@johnmorrisdotca/kumimoji";
307
+ *
308
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
309
+ * console.log(judgeGrid(tiles,word=>word==="cat"));
310
+ * ```
311
+ */
197
312
  export function judgeGrid(tiles, isWord, readable = (word) => word, rules = {}) {
198
313
  const misspelt = new Set();
199
314
  const notWords = [];
package/dist/help.d.ts CHANGED
@@ -12,9 +12,42 @@ import type { TileWords } from "./tileWords.ts";
12
12
  * Only the hand's own tiles are read — a wild is left for the player to place
13
13
  * — and nothing on the table is moved.
14
14
  */
15
- /** How many words one hand offers before the presses go round again: the longest first. */
15
+ /** How many words one hand offers before the presses go round again: the longest first.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { HELP_WORDS_MOST } from "@johnmorrisdotca/kumimoji";
20
+ * console.log(HELP_WORDS_MOST);
21
+ * ```
22
+ */
16
23
  export declare const HELP_WORDS_MOST = 40;
17
- /** The words the hand's own tiles spell, longest first and then in the list's order; wilds are not used. */
24
+ /** The words the hand's own tiles spell, longest first and then in the list's order; wilds are not used.
25
+ *
26
+ * @param hand - The hand size or tile codes, as declared by the function signature.
27
+ * @param words - The loaded native language word list and tile mappings.
28
+ * @returns The words the hand's own tiles spell, longest first and then in the list's order; wilds are not used.
29
+ * @example
30
+ * ```ts
31
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
32
+ * import { wordsInHand } from "@johnmorrisdotca/kumimoji";
33
+ *
34
+ * const words = await loadTileWordsFromModule("english");
35
+ * console.log(wordsInHand(["c","a","t"],words));
36
+ * ```
37
+ */
18
38
  export declare function wordsInHand(hand: readonly string[], words: TileWords): string[];
19
- /** The hand with `word`'s tiles first, in its order, and the rest after them as they were. */
39
+ /** The hand with `word`'s tiles first, in its order, and the rest after them as they were.
40
+ *
41
+ * @param play - The current immutable solo-game progress.
42
+ * @param word - The encoded word to lay or spell.
43
+ * @returns The hand with `word`'s tiles first, in its order, and the rest after them as they were.
44
+ * @example
45
+ * ```ts
46
+ * import { deal, handSpelling } from "@johnmorrisdotca/kumimoji";
47
+ *
48
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
49
+ * const play = deal("catdog",3);
50
+ * console.log(handSpelling(play,"cat").tiles);
51
+ * ```
52
+ */
20
53
  export declare function handSpelling(play: TilePlay, word: string): TilePlay;
package/dist/help.js CHANGED
@@ -10,9 +10,29 @@
10
10
  * Only the hand's own tiles are read — a wild is left for the player to place
11
11
  * — and nothing on the table is moved.
12
12
  */
13
- /** How many words one hand offers before the presses go round again: the longest first. */
13
+ /** How many words one hand offers before the presses go round again: the longest first.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { HELP_WORDS_MOST } from "@johnmorrisdotca/kumimoji";
18
+ * console.log(HELP_WORDS_MOST);
19
+ * ```
20
+ */
14
21
  export const HELP_WORDS_MOST = 40;
15
- /** The words the hand's own tiles spell, longest first and then in the list's order; wilds are not used. */
22
+ /** The words the hand's own tiles spell, longest first and then in the list's order; wilds are not used.
23
+ *
24
+ * @param hand - The hand size or tile codes, as declared by the function signature.
25
+ * @param words - The loaded native language word list and tile mappings.
26
+ * @returns The words the hand's own tiles spell, longest first and then in the list's order; wilds are not used.
27
+ * @example
28
+ * ```ts
29
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
30
+ * import { wordsInHand } from "@johnmorrisdotca/kumimoji";
31
+ *
32
+ * const words = await loadTileWordsFromModule("english");
33
+ * console.log(wordsInHand(["c","a","t"],words));
34
+ * ```
35
+ */
16
36
  export function wordsInHand(hand, words) {
17
37
  const have = new Map();
18
38
  for (const tile of hand)
@@ -42,7 +62,20 @@ export function wordsInHand(hand, words) {
42
62
  }
43
63
  return found;
44
64
  }
45
- /** The hand with `word`'s tiles first, in its order, and the rest after them as they were. */
65
+ /** The hand with `word`'s tiles first, in its order, and the rest after them as they were.
66
+ *
67
+ * @param play - The current immutable solo-game progress.
68
+ * @param word - The encoded word to lay or spell.
69
+ * @returns The hand with `word`'s tiles first, in its order, and the rest after them as they were.
70
+ * @example
71
+ * ```ts
72
+ * import { deal, handSpelling } from "@johnmorrisdotca/kumimoji";
73
+ *
74
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
75
+ * const play = deal("catdog",3);
76
+ * console.log(handSpelling(play,"cat").tiles);
77
+ * ```
78
+ */
46
79
  export function handSpelling(play, word) {
47
80
  const rest = [...play.hand];
48
81
  const front = [];
package/dist/judge.d.ts CHANGED
@@ -9,5 +9,19 @@ import type { TileWords } from "./tileWords.ts";
9
9
  * through it a word (`readWilds`); where none does, the grid is judged as
10
10
  * laid and the run is named with its `*`. `rules` says whether the diagonals
11
11
  * are read (`GridRules`).
12
+ *
13
+ * @param tiles - The map from row,column square names to internal tile codes.
14
+ * @param words - The loaded native language word list and tile mappings.
15
+ * @param rules - Whether diagonal runs are also judged.
16
+ * @returns A GRID JUDGED AGAINST ITS LANGUAGE'S LIST, the one way the solo game, each seat of a pass-and-play game and the server's check all ask it: a run is a word when its tiles spell one the list holds (`wordOf`, so a wild reads as the letter or kana it was given), and a run that is not is named as it reads. A wild given no letter reads as whichever letter makes every run through it a word (`readWilds`); where none does, the grid is judged as laid and the run is named with its `*`. `rules` says whether the diagonals are read (`GridRules`).
17
+ * @example
18
+ * ```ts
19
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
20
+ * import { judgeWithWords } from "@johnmorrisdotca/kumimoji";
21
+ *
22
+ * const words = await loadTileWordsFromModule("english");
23
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
24
+ * console.log(judgeWithWords(tiles,words));
25
+ * ```
12
26
  */
13
27
  export declare function judgeWithWords(tiles: Tiles, words: TileWords, rules?: GridRules): GridVerdict;
package/dist/judge.js CHANGED
@@ -9,6 +9,20 @@ import { readWilds } from "./wilds.js";
9
9
  * through it a word (`readWilds`); where none does, the grid is judged as
10
10
  * laid and the run is named with its `*`. `rules` says whether the diagonals
11
11
  * are read (`GridRules`).
12
+ *
13
+ * @param tiles - The map from row,column square names to internal tile codes.
14
+ * @param words - The loaded native language word list and tile mappings.
15
+ * @param rules - Whether diagonal runs are also judged.
16
+ * @returns A GRID JUDGED AGAINST ITS LANGUAGE'S LIST, the one way the solo game, each seat of a pass-and-play game and the server's check all ask it: a run is a word when its tiles spell one the list holds (`wordOf`, so a wild reads as the letter or kana it was given), and a run that is not is named as it reads. A wild given no letter reads as whichever letter makes every run through it a word (`readWilds`); where none does, the grid is judged as laid and the run is named with its `*`. `rules` says whether the diagonals are read (`GridRules`).
17
+ * @example
18
+ * ```ts
19
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
20
+ * import { judgeWithWords } from "@johnmorrisdotca/kumimoji";
21
+ *
22
+ * const words = await loadTileWordsFromModule("english");
23
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
24
+ * console.log(judgeWithWords(tiles,words));
25
+ * ```
12
26
  */
13
27
  export function judgeWithWords(tiles, words, rules = {}) {
14
28
  const read = readWilds(tiles, words, rules) ?? tiles;
package/dist/kana.d.ts CHANGED
@@ -12,14 +12,36 @@
12
12
  * form: は then ん is はん, ばん and ぱん at once. The word list is stored
13
13
  * already read this way (`scripts/word-lists-ja.mjs` folds it with the same
14
14
  * table), so checking a line is one lookup.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { BASE_KANA } from "@johnmorrisdotca/kumimoji";
19
+ * console.log(BASE_KANA);
20
+ * ```
15
21
  */
16
22
  export declare const BASE_KANA = "\u3042\u3044\u3046\u3048\u304A\u304B\u304D\u304F\u3051\u3053\u3055\u3057\u3059\u305B\u305D\u305F\u3061\u3064\u3066\u3068\u306A\u306B\u306C\u306D\u306E\u306F\u3072\u3075\u3078\u307B\u307E\u307F\u3080\u3081\u3082\u3084\u3086\u3088\u3089\u308A\u308B\u308C\u308D\u308F\u3093";
17
- /** The tile a kana is played with, or null for anything that is not hiragana (ー, katakana, a letter). */
23
+ /** The tile a kana is played with, or null for anything that is not hiragana (ー, katakana, a letter).
24
+ *
25
+ * @param kana - The hiragana reading to map to a base tile.
26
+ * @returns The tile a kana is played with, or null for anything that is not hiragana (ー, katakana, a letter).
27
+ * @example
28
+ * ```ts
29
+ * import { tileKana } from "@johnmorrisdotca/kumimoji";
30
+ *
31
+ * console.log(tileKana("が"));
32
+ * ```
33
+ */
18
34
  export declare function tileKana(kana: string): string | null;
19
35
  /**
20
36
  * WHAT A TILE SHOWS SMALL IN ITS CORNER: the other ways it is commonly played
21
37
  * (John, 2026-09-28: "the tiles like Yu can show the regular and small version
22
38
  * in that tile to show its versatility"). Only the forms a player reaches for;
23
39
  * the rare ones (ぁ, ゎ, ゔ) still play, and the rules say so.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import { CORNER_FORMS } from "@johnmorrisdotca/kumimoji";
44
+ * console.log(CORNER_FORMS);
45
+ * ```
24
46
  */
25
47
  export declare const CORNER_FORMS: Readonly<Record<string, string>>;
package/dist/kana.js CHANGED
@@ -12,12 +12,28 @@
12
12
  * form: は then ん is はん, ばん and ぱん at once. The word list is stored
13
13
  * already read this way (`scripts/word-lists-ja.mjs` folds it with the same
14
14
  * table), so checking a line is one lookup.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { BASE_KANA } from "@johnmorrisdotca/kumimoji";
19
+ * console.log(BASE_KANA);
20
+ * ```
15
21
  */
16
22
  export const BASE_KANA = "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわん";
17
23
  const SMALL_AND_OLD = {
18
24
  ぁ: "あ", ぃ: "い", ぅ: "う", ぇ: "え", ぉ: "お", っ: "つ", ゃ: "や", ゅ: "ゆ", ょ: "よ", ゎ: "わ", ゕ: "か", ゖ: "け", を: "お", ゐ: "い", ゑ: "え",
19
25
  };
20
- /** The tile a kana is played with, or null for anything that is not hiragana (ー, katakana, a letter). */
26
+ /** The tile a kana is played with, or null for anything that is not hiragana (ー, katakana, a letter).
27
+ *
28
+ * @param kana - The hiragana reading to map to a base tile.
29
+ * @returns The tile a kana is played with, or null for anything that is not hiragana (ー, katakana, a letter).
30
+ * @example
31
+ * ```ts
32
+ * import { tileKana } from "@johnmorrisdotca/kumimoji";
33
+ *
34
+ * console.log(tileKana("が"));
35
+ * ```
36
+ */
21
37
  export function tileKana(kana) {
22
38
  const bare = kana.normalize("NFD").replace(/[゙゚]/gu, "").normalize("NFC");
23
39
  const base = SMALL_AND_OLD[bare] ?? bare;
@@ -28,6 +44,12 @@ export function tileKana(kana) {
28
44
  * (John, 2026-09-28: "the tiles like Yu can show the regular and small version
29
45
  * in that tile to show its versatility"). Only the forms a player reaches for;
30
46
  * the rare ones (ぁ, ゎ, ゔ) still play, and the rules say so.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * import { CORNER_FORMS } from "@johnmorrisdotca/kumimoji";
51
+ * console.log(CORNER_FORMS);
52
+ * ```
31
53
  */
32
54
  export const CORNER_FORMS = {
33
55
  か: "が", き: "ぎ", く: "ぐ", け: "げ", こ: "ご",
@@ -1,16 +1,60 @@
1
- /** How much of the set a game's bag holds: a short game, half the set, or all of it. */
1
+ /** How much of the set a game's bag holds: a short game, half the set, or all of it.
2
+ *
3
+ * @example
4
+ * ```ts
5
+ * import type { KumimojiLength } from "@johnmorrisdotca/kumimoji";
6
+ *
7
+ * const value: KumimojiLength = "short";
8
+ * console.log(value);
9
+ * ```
10
+ */
2
11
  export type KumimojiLength = "short" | "medium" | "full";
3
- /** How many of the bag's tiles are wild: easy the most, hard none (`KUMIMOJI_WILDS`). */
12
+ /** How many of the bag's tiles are wild: easy the most, hard none (`KUMIMOJI_WILDS`).
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import type { KumimojiLevel } from "@johnmorrisdotca/kumimoji";
17
+ *
18
+ * const value: KumimojiLevel = "hard";
19
+ * console.log(value);
20
+ * ```
21
+ */
4
22
  export type KumimojiLevel = "easy" | "medium" | "hard";
5
- /** The language of the tiles and of the word list they are judged by. */
23
+ /** The language of the tiles and of the word list they are judged by.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import type { KumimojiLanguage } from "@johnmorrisdotca/kumimoji";
28
+ *
29
+ * const value: KumimojiLanguage = "japanese";
30
+ * console.log(value);
31
+ * ```
32
+ */
6
33
  export type KumimojiLanguage = "english" | "japanese";
7
- /** How far the player has turned the table to look at it: quarter turns clockwise, 0 to 3. The view alone; the grid never turns. */
34
+ /** How far the player has turned the table to look at it: quarter turns clockwise, 0 to 3. The view alone; the grid never turns.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import type { Turn } from "@johnmorrisdotca/kumimoji";
39
+ *
40
+ * const value: Turn = 1;
41
+ * console.log(value);
42
+ * ```
43
+ */
8
44
  export type Turn = 0 | 1 | 2 | 3;
9
45
  /**
10
46
  * WHAT A KUMIMOJI WAS SET UP AS, beyond its hand and level: the choices that
11
47
  * make one game a different game from another at the same seed, carried
12
48
  * together wherever a game is made, checked, kept or raced. Each is optional,
13
49
  * and its absence is the default: Short, English, one set, no diagonals.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * import type { KumimojiOptions } from "@johnmorrisdotca/kumimoji";
54
+ *
55
+ * const value: KumimojiOptions = {language:"english",diagonals:false};
56
+ * console.log(value);
57
+ * ```
14
58
  */
15
59
  export type KumimojiOptions = {
16
60
  gameLength?: KumimojiLength;
@@ -24,7 +68,16 @@ export type KumimojiOptions = {
24
68
  */
25
69
  diagonals?: boolean;
26
70
  };
27
- /** The answer to "does this grid finish the game?": yes, or no and why. */
71
+ /** The answer to "does this grid finish the game?": yes, or no and why.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import type { KumimojiCheck } from "@johnmorrisdotca/kumimoji";
76
+ *
77
+ * const value: KumimojiCheck = {ok:false,reason:"Not a finished grid"};
78
+ * console.log(value);
79
+ * ```
80
+ */
28
81
  export type KumimojiCheck = {
29
82
  ok: true;
30
83
  } | {
@@ -35,6 +88,18 @@ export type KumimojiCheck = {
35
88
  * A GAME DEALT (`generateKumimoji`): the bag, in the order its tiles come out,
36
89
  * as one string of tile codes (`*` a wild), and one finished grid of those
37
90
  * tiles that proves the bag can be finished, never shown to the player.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * import { generateKumimoji } from "@johnmorrisdotca/kumimoji";
95
+ * import type { KumimojiDeal } from "@johnmorrisdotca/kumimoji";
96
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
97
+ *
98
+ * await loadTileWordsFromModule("english");
99
+ * const dealt = generateKumimoji(3,"hard",44);
100
+ * const value: KumimojiDeal = dealt;
101
+ * console.log(value);
102
+ * ```
38
103
  */
39
104
  export type KumimojiDeal = {
40
105
  kind: "kumimoji";