@johnmorrisdotca/kumimoji 1.2.1 → 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 (77) hide show
  1. package/CHANGELOG.md +37 -1
  2. package/CONTRIBUTING.md +81 -44
  3. package/README.md +478 -327
  4. package/dist/check.d.ts +26 -1
  5. package/dist/check.js +26 -1
  6. package/dist/computer.types.d.ts +24 -2
  7. package/dist/computerPlay.d.ts +45 -2
  8. package/dist/computerPlay.js +45 -2
  9. package/dist/computerTurn.d.ts +42 -3
  10. package/dist/computerTurn.js +42 -3
  11. package/dist/daily.d.ts +22 -2
  12. package/dist/daily.js +22 -2
  13. package/dist/element-define.d.ts +1 -1
  14. package/dist/element-define.js +3 -13
  15. package/dist/element.d.ts +85 -4
  16. package/dist/element.js +176 -45
  17. package/dist/embed-day.d.ts +4 -0
  18. package/dist/embed-day.js +23 -0
  19. package/dist/export.d.ts +123 -6
  20. package/dist/export.js +91 -4
  21. package/dist/generate.d.ts +14 -0
  22. package/dist/generate.js +14 -0
  23. package/dist/grid.d.ts +181 -10
  24. package/dist/grid.js +122 -7
  25. package/dist/help.d.ts +36 -3
  26. package/dist/help.js +36 -3
  27. package/dist/judge.d.ts +14 -0
  28. package/dist/judge.js +14 -0
  29. package/dist/kana.d.ts +23 -1
  30. package/dist/kana.js +23 -1
  31. package/dist/kumimoji.types.d.ts +70 -5
  32. package/dist/party.d.ts +268 -14
  33. package/dist/party.js +268 -14
  34. package/dist/party.types.d.ts +50 -2
  35. package/dist/partyKept.d.ts +74 -4
  36. package/dist/partyKept.js +74 -4
  37. package/dist/partySeats.d.ts +92 -6
  38. package/dist/partySeats.js +72 -4
  39. package/dist/partyTurns.d.ts +171 -5
  40. package/dist/partyTurns.js +171 -5
  41. package/dist/placement.d.ts +50 -2
  42. package/dist/placement.js +30 -0
  43. package/dist/play.d.ts +247 -15
  44. package/dist/play.js +237 -15
  45. package/dist/random.d.ts +34 -3
  46. package/dist/random.js +23 -2
  47. package/dist/react.d.ts +42 -4
  48. package/dist/react.js +22 -5
  49. package/dist/showcase.d.ts +83 -7
  50. package/dist/showcase.js +49 -4
  51. package/dist/strings.d.ts +54 -5
  52. package/dist/strings.js +34 -3
  53. package/dist/tableView.d.ts +151 -8
  54. package/dist/tableView.js +129 -6
  55. package/dist/tileFace.d.ts +59 -5
  56. package/dist/tileFace.js +48 -4
  57. package/dist/tileFamily.d.ts +9 -0
  58. package/dist/tileFamily.js +9 -0
  59. package/dist/tileWords.d.ts +93 -6
  60. package/dist/tileWords.js +83 -6
  61. package/dist/tileWordsModule.d.ts +11 -1
  62. package/dist/tileWordsModule.js +11 -1
  63. package/dist/tiles.constants.d.ts +99 -5
  64. package/dist/tiles.constants.js +99 -5
  65. package/dist/turn.d.ts +82 -4
  66. package/dist/turn.js +82 -4
  67. package/dist/ui/board.d.ts +60 -5
  68. package/dist/ui/board.js +28 -2
  69. package/dist/ui/mount.d.ts +41 -2
  70. package/dist/ui/mount.js +38 -1
  71. package/dist/ui/style.d.ts +6 -1
  72. package/dist/ui/style.js +6 -0
  73. package/dist/version.d.ts +9 -2
  74. package/dist/version.js +9 -2
  75. package/dist/wilds.d.ts +22 -1
  76. package/dist/wilds.js +22 -1
  77. package/package.json +66 -57
package/dist/generate.js CHANGED
@@ -29,6 +29,20 @@ import { tileWords } from "./tileWords.js";
29
29
  *
30
30
  * Deterministic in the seed, like every generator here: two browsers in a
31
31
  * race, or one tomorrow, deal the same bag in the same order.
32
+ *
33
+ * @param size - The supported initial hand size.
34
+ * @param level - The difficulty that determines the wildcard allowance.
35
+ * @param seed - The numeric seed for deterministic deals or random draws.
36
+ * @param options - Native game, component or presentation options.
37
+ * @returns MAKING A KUMIMOJI, in the browser, from a seed: the bag the game is played from, in the order its tiles come out.
38
+ * @example
39
+ * ```ts
40
+ * import { generateKumimoji } from "@johnmorrisdotca/kumimoji";
41
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
42
+ *
43
+ * await loadTileWordsFromModule("english");
44
+ * console.log(generateKumimoji(3,"hard",44).givens);
45
+ * ```
32
46
  */
33
47
  export function generateKumimoji(size, level, seed, options = {}) {
34
48
  const gameLength = options.gameLength ?? "short";
package/dist/grid.d.ts CHANGED
@@ -11,40 +11,139 @@
11
11
  * and COW down from its C. Only
12
12
  * where the tiles stand beside one another is written, never where on the
13
13
  * table they were, so one grid has one spelling however far it was dragged.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import type { Tiles } from "@johnmorrisdotca/kumimoji";
18
+ *
19
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
20
+ * const value: Tiles = tiles;
21
+ * console.log(value);
22
+ * ```
14
23
  */
15
24
  export type Tiles = ReadonlyMap<string, string>;
16
- /** A square's name, "row,col". */
25
+ /** A square's name, "row,col".
26
+ *
27
+ * @param row - The integer row coordinate, which may be negative.
28
+ * @param col - The integer column coordinate, which may be negative.
29
+ * @returns A square's name, "row,col".
30
+ * @example
31
+ * ```ts
32
+ * import { squareAt } from "@johnmorrisdotca/kumimoji";
33
+ *
34
+ * console.log(squareAt(-1,2));
35
+ * ```
36
+ */
17
37
  export declare function squareAt(row: number, col: number): string;
18
- /** A square's row and column, from its name. */
38
+ /** A square's row and column, from its name.
39
+ *
40
+ * @param square - The row,column square name.
41
+ * @returns A square's row and column, from its name.
42
+ * @example
43
+ * ```ts
44
+ * import { placeOf } from "@johnmorrisdotca/kumimoji";
45
+ *
46
+ * console.log(placeOf("-1,2"));
47
+ * ```
48
+ */
19
49
  export declare function placeOf(square: string): {
20
50
  row: number;
21
51
  col: number;
22
52
  };
23
- /** The rows and columns a grid's tiles stand within. */
53
+ /** The rows and columns a grid's tiles stand within.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * import type { Bounds } from "@johnmorrisdotca/kumimoji";
58
+ *
59
+ * const value: Bounds = {top:0,left:0,bottom:0,right:2};
60
+ * console.log(value);
61
+ * ```
62
+ */
24
63
  export type Bounds = {
25
64
  top: number;
26
65
  left: number;
27
66
  bottom: number;
28
67
  right: number;
29
68
  };
30
- /** The rows and columns the tiles stand within, or null for no tiles. */
69
+ /** The rows and columns the tiles stand within, or null for no tiles.
70
+ *
71
+ * @param tiles - The map from row,column square names to internal tile codes.
72
+ * @returns The rows and columns the tiles stand within, or null for no tiles.
73
+ * @example
74
+ * ```ts
75
+ * import { boundsOf } from "@johnmorrisdotca/kumimoji";
76
+ *
77
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
78
+ * console.log(boundsOf(tiles));
79
+ * ```
80
+ */
31
81
  export declare function boundsOf(tiles: Tiles): Bounds | null;
32
- /** A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back. */
82
+ /** A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back.
83
+ *
84
+ * @param tiles - The map from row,column square names to internal tile codes.
85
+ * @returns A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back.
86
+ * @example
87
+ * ```ts
88
+ * import { encodeGrid } from "@johnmorrisdotca/kumimoji";
89
+ *
90
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
91
+ * console.log(encodeGrid(tiles));
92
+ * ```
93
+ */
33
94
  export declare function encodeGrid(tiles: Tiles): string;
34
95
  /**
35
96
  * A grid read back, its first row at row 0, or null for anything that is not
36
97
  * one: a stray character, a capital, a grid wider or taller than any grid of
37
98
  * fifty tiles can be. An empty string is no tiles.
99
+ *
100
+ * @param code - The encoded grid or progress text.
101
+ * @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.
102
+ * @example
103
+ * ```ts
104
+ * import { decodeGrid } from "@johnmorrisdotca/kumimoji";
105
+ *
106
+ * console.log(decodeGrid("cat"));
107
+ * ```
38
108
  */
39
109
  export declare function decodeGrid(code: string): Map<string, string> | null;
40
- /** How many of each letter. */
110
+ /** How many of each letter.
111
+ *
112
+ * @param letters - The iterable tile letters to count.
113
+ * @returns How many of each letter.
114
+ * @example
115
+ * ```ts
116
+ * import { lettersOf } from "@johnmorrisdotca/kumimoji";
117
+ *
118
+ * console.log(lettersOf("cat"));
119
+ * ```
120
+ */
41
121
  export declare function lettersOf(letters: Iterable<string>): Map<string, number>;
42
- /** Whether two tallies hold the same letters, as many of each. */
122
+ /** Whether two tallies hold the same letters, as many of each.
123
+ *
124
+ * @param a - The first letter-count map.
125
+ * @param b - The second letter-count map.
126
+ * @returns Whether two tallies hold the same letters, as many of each.
127
+ * @example
128
+ * ```ts
129
+ * import { lettersOf, sameLetters } from "@johnmorrisdotca/kumimoji";
130
+ *
131
+ * console.log(sameLetters(lettersOf("cat"),lettersOf("act")));
132
+ * ```
133
+ */
43
134
  export declare function sameLetters(a: Map<string, number>, b: Map<string, number>): boolean;
44
135
  /**
45
136
  * THE LINES A RUN MAY LIE ALONG, each read top to bottom (and across, left to
46
137
  * right): across and down always, and the two diagonals when the game was set
47
138
  * up with Diagonals — down to the right, and down to the left.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * import type { RunLine } from "@johnmorrisdotca/kumimoji";
143
+ *
144
+ * const value: RunLine = "across";
145
+ * console.log(value);
146
+ * ```
48
147
  */
49
148
  export type RunLine = "across" | "down" | "downRight" | "downLeft";
50
149
  /**
@@ -52,13 +151,37 @@ export type RunLine = "across" | "down" | "downRight" | "downLeft";
52
151
  * at a corner are what every crossword is full of — the letter above a word
53
152
  * and the one beside it — so a pair is free, and only three or more in a
54
153
  * line are a diagonal word.
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * import { DIAGONAL_RUN_LEAST } from "@johnmorrisdotca/kumimoji";
158
+ * console.log(DIAGONAL_RUN_LEAST);
159
+ * ```
55
160
  */
56
161
  export declare const DIAGONAL_RUN_LEAST = 3;
57
- /** How a grid is read: whether its diagonals are (`KumimojiOptions.diagonals`). */
162
+ /** How a grid is read: whether its diagonals are (`KumimojiOptions.diagonals`).
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * import type { GridRules } from "@johnmorrisdotca/kumimoji";
167
+ *
168
+ * const value: GridRules = {diagonals:true};
169
+ * console.log(value);
170
+ * ```
171
+ */
58
172
  export type GridRules = {
59
173
  diagonals?: boolean;
60
174
  };
61
- /** A run of tiles along one line: the word it spells and the squares it stands on, in reading order. */
175
+ /** A run of tiles along one line: the word it spells and the squares it stands on, in reading order.
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * import type { Run } from "@johnmorrisdotca/kumimoji";
180
+ *
181
+ * const value: Run = {word:"cat",squares:["0,0","0,1","0,2"],line:"across"};
182
+ * console.log(value);
183
+ * ```
184
+ */
62
185
  export type Run = {
63
186
  word: string;
64
187
  squares: string[];
@@ -68,6 +191,17 @@ export type Run = {
68
191
  * Every run the grid is read by: two or more tiles across, then down, and
69
192
  * with Diagonals three or more down to the right, then down to the left. A
70
193
  * tile with nothing beside it in a line is no run.
194
+ *
195
+ * @param tiles - The map from row,column square names to internal tile codes.
196
+ * @param rules - Whether diagonal runs are also judged.
197
+ * @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.
198
+ * @example
199
+ * ```ts
200
+ * import { runsOf } from "@johnmorrisdotca/kumimoji";
201
+ *
202
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
203
+ * console.log(runsOf(tiles));
204
+ * ```
71
205
  */
72
206
  export declare function runsOf(tiles: Tiles, rules?: GridRules): Run[];
73
207
  /**
@@ -76,6 +210,17 @@ export declare function runsOf(tiles: Tiles, rules?: GridRules): Run[];
76
210
  * other in one of those runs are joined too: a diagonal word holds a
77
211
  * crossword together as a word across does. A pair touching at a corner is
78
212
  * never a link, because it is never read.
213
+ *
214
+ * @param tiles - The map from row,column square names to internal tile codes.
215
+ * @param links - The runs connecting groups; computed from the grid when omitted.
216
+ * @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.
217
+ * @example
218
+ * ```ts
219
+ * import { groupsOf } from "@johnmorrisdotca/kumimoji";
220
+ *
221
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
222
+ * console.log(groupsOf(tiles));
223
+ * ```
79
224
  */
80
225
  export declare function groupsOf(tiles: Tiles, links?: readonly Run[]): string[][];
81
226
  /**
@@ -85,6 +230,18 @@ export declare function groupsOf(tiles: Tiles, links?: readonly Run[]): string[]
85
230
  * With Diagonals (`rules`), the diagonal runs of three or more are runs too:
86
231
  * each must be a word, a misspelt one is marked as any other is, and each
87
232
  * joins its tiles (`groupsOf`).
233
+ *
234
+ * @example
235
+ * ```ts
236
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
237
+ * import { judgeWithWords } from "@johnmorrisdotca/kumimoji";
238
+ * import type { GridVerdict } from "@johnmorrisdotca/kumimoji";
239
+ *
240
+ * const words = await loadTileWordsFromModule("english");
241
+ * const verdict = judgeWithWords(new Map([["0,0","c"],["0,1","a"],["0,2","t"]]),words);
242
+ * const value: GridVerdict = verdict;
243
+ * console.log(value);
244
+ * ```
88
245
  */
89
246
  export type GridVerdict = {
90
247
  sound: boolean;
@@ -96,5 +253,19 @@ export type GridVerdict = {
96
253
  /** The runs that are not words, as spelled, for the line under the table. */
97
254
  notWords: readonly string[];
98
255
  };
99
- /** 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. */
256
+ /** 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.
257
+ *
258
+ * @param tiles - The map from row,column square names to internal tile codes.
259
+ * @param isWord - The predicate that accepts a readable word.
260
+ * @param readable - The conversion from tile codes to readable words.
261
+ * @param rules - Whether diagonal runs are also judged.
262
+ * @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.
263
+ * @example
264
+ * ```ts
265
+ * import { judgeGrid } from "@johnmorrisdotca/kumimoji";
266
+ *
267
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
268
+ * console.log(judgeGrid(tiles,word=>word==="cat"));
269
+ * ```
270
+ */
100
271
  export declare function judgeGrid(tiles: Tiles, isWord: (word: string) => boolean, readable?: (word: string) => string, rules?: GridRules): GridVerdict;
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>>;