@johnmorrisdotca/kumimoji 1.2.2 → 1.3.1

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 (83) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/CONTRIBUTING.md +11 -2
  3. package/README.md +80 -39
  4. package/dist/check.d.ts +26 -1
  5. package/dist/check.js +30 -3
  6. package/dist/computer.types.d.ts +24 -2
  7. package/dist/computerPlay.d.ts +45 -2
  8. package/dist/computerPlay.js +56 -6
  9. package/dist/computerTurn.d.ts +42 -3
  10. package/dist/computerTurn.js +47 -5
  11. package/dist/daily.d.ts +22 -2
  12. package/dist/daily.js +23 -3
  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 +359 -77
  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 +109 -9
  21. package/dist/generate.d.ts +14 -0
  22. package/dist/generate.js +32 -5
  23. package/dist/grid.d.ts +181 -10
  24. package/dist/grid.js +148 -11
  25. package/dist/help.d.ts +36 -3
  26. package/dist/help.js +36 -3
  27. package/dist/index.d.ts +22 -22
  28. package/dist/index.js +22 -22
  29. package/dist/judge.d.ts +14 -0
  30. package/dist/judge.js +14 -0
  31. package/dist/kana.d.ts +23 -1
  32. package/dist/kana.js +62 -7
  33. package/dist/kumimoji.types.d.ts +70 -5
  34. package/dist/party.d.ts +268 -14
  35. package/dist/party.js +296 -19
  36. package/dist/party.types.d.ts +50 -2
  37. package/dist/partyKept.d.ts +74 -4
  38. package/dist/partyKept.js +127 -12
  39. package/dist/partySeats.d.ts +92 -6
  40. package/dist/partySeats.js +83 -8
  41. package/dist/partyTurns.d.ts +171 -5
  42. package/dist/partyTurns.js +187 -8
  43. package/dist/placement.d.ts +50 -2
  44. package/dist/placement.js +35 -2
  45. package/dist/play.d.ts +247 -15
  46. package/dist/play.js +251 -18
  47. package/dist/random.d.ts +34 -3
  48. package/dist/random.js +23 -2
  49. package/dist/react.d.ts +42 -4
  50. package/dist/react.js +54 -7
  51. package/dist/showcase.d.ts +83 -7
  52. package/dist/showcase.js +61 -7
  53. package/dist/strings.d.ts +54 -5
  54. package/dist/strings.js +34 -3
  55. package/dist/tableView.d.ts +151 -8
  56. package/dist/tableView.js +129 -6
  57. package/dist/tileFace.d.ts +59 -5
  58. package/dist/tileFace.js +48 -4
  59. package/dist/tileFamily.d.ts +9 -0
  60. package/dist/tileFamily.js +9 -0
  61. package/dist/tileWords.d.ts +93 -6
  62. package/dist/tileWords.js +94 -12
  63. package/dist/tileWordsModule.d.ts +12 -2
  64. package/dist/tileWordsModule.js +14 -2
  65. package/dist/tiles.constants.d.ts +99 -5
  66. package/dist/tiles.constants.js +171 -13
  67. package/dist/turn.d.ts +82 -4
  68. package/dist/turn.js +88 -5
  69. package/dist/ui/board.d.ts +60 -5
  70. package/dist/ui/board.js +44 -4
  71. package/dist/ui/draw.d.ts +62 -0
  72. package/dist/ui/draw.js +229 -0
  73. package/dist/ui/mount.d.ts +41 -2
  74. package/dist/ui/mount.js +190 -265
  75. package/dist/ui/style.d.ts +6 -1
  76. package/dist/ui/style.js +6 -0
  77. package/dist/ui.d.ts +3 -3
  78. package/dist/ui.js +2 -2
  79. package/dist/version.d.ts +9 -2
  80. package/dist/version.js +9 -2
  81. package/dist/wilds.d.ts +22 -1
  82. package/dist/wilds.js +25 -3
  83. package/package.json +68 -61
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()) {
@@ -16,11 +48,27 @@ export function boundsOf(tiles) {
16
48
  bounds =
17
49
  bounds === null
18
50
  ? { top: row, left: col, bottom: row, right: col }
19
- : { top: Math.min(bounds.top, row), left: Math.min(bounds.left, col), bottom: Math.max(bounds.bottom, row), right: Math.max(bounds.right, col) };
51
+ : {
52
+ top: Math.min(bounds.top, row),
53
+ left: Math.min(bounds.left, col),
54
+ bottom: Math.max(bounds.bottom, row),
55
+ right: Math.max(bounds.right, col),
56
+ };
20
57
  }
21
58
  return bounds;
22
59
  }
23
- /** A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back. */
60
+ /** A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back.
61
+ *
62
+ * @param tiles - The map from row,column square names to internal tile codes.
63
+ * @returns A grid as a string, drawn from its own top-left tile: `cat/2o/2w`. `decodeGrid` reads it back.
64
+ * @example
65
+ * ```ts
66
+ * import { encodeGrid } from "@johnmorrisdotca/kumimoji";
67
+ *
68
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
69
+ * console.log(encodeGrid(tiles));
70
+ * ```
71
+ */
24
72
  export function encodeGrid(tiles) {
25
73
  const bounds = boundsOf(tiles);
26
74
  if (bounds === null)
@@ -48,6 +96,15 @@ export function encodeGrid(tiles) {
48
96
  * A grid read back, its first row at row 0, or null for anything that is not
49
97
  * one: a stray character, a capital, a grid wider or taller than any grid of
50
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
+ * ```
51
108
  */
52
109
  export function decodeGrid(code) {
53
110
  if (typeof code !== "string")
@@ -97,7 +154,17 @@ export function decodeGrid(code) {
97
154
  }
98
155
  return tiles;
99
156
  }
100
- /** How many of each letter. */
157
+ /** How many of each letter.
158
+ *
159
+ * @param letters - The iterable tile letters to count.
160
+ * @returns How many of each letter.
161
+ * @example
162
+ * ```ts
163
+ * import { lettersOf } from "@johnmorrisdotca/kumimoji";
164
+ *
165
+ * console.log(lettersOf("cat"));
166
+ * ```
167
+ */
101
168
  export function lettersOf(letters) {
102
169
  const counts = new Map();
103
170
  for (const letter of letters)
@@ -105,7 +172,18 @@ export function lettersOf(letters) {
105
172
  counts.set(letter, (counts.get(letter) ?? 0) + 1);
106
173
  return counts;
107
174
  }
108
- /** Whether two tallies hold the same letters, as many of each. */
175
+ /** Whether two tallies hold the same letters, as many of each.
176
+ *
177
+ * @param a - The first letter-count map.
178
+ * @param b - The second letter-count map.
179
+ * @returns Whether two tallies hold the same letters, as many of each.
180
+ * @example
181
+ * ```ts
182
+ * import { lettersOf, sameLetters } from "@johnmorrisdotca/kumimoji";
183
+ *
184
+ * console.log(sameLetters(lettersOf("cat"),lettersOf("act")));
185
+ * ```
186
+ */
109
187
  export function sameLetters(a, b) {
110
188
  if (a.size !== b.size)
111
189
  return false;
@@ -115,12 +193,23 @@ export function sameLetters(a, b) {
115
193
  return true;
116
194
  }
117
195
  /** One step along each line, as rows and columns. */
118
- const STEP = { across: [0, 1], down: [1, 0], downRight: [1, 1], downLeft: [1, -1] };
196
+ const STEP = {
197
+ across: [0, 1],
198
+ down: [1, 0],
199
+ downRight: [1, 1],
200
+ downLeft: [1, -1],
201
+ };
119
202
  /**
120
203
  * The fewest tiles a diagonal run needs before it is read. Two tiles touching
121
204
  * at a corner are what every crossword is full of — the letter above a word
122
205
  * and the one beside it — so a pair is free, and only three or more in a
123
206
  * line are a diagonal word.
207
+ *
208
+ * @example
209
+ * ```ts
210
+ * import { DIAGONAL_RUN_LEAST } from "@johnmorrisdotca/kumimoji";
211
+ * console.log(DIAGONAL_RUN_LEAST);
212
+ * ```
124
213
  */
125
214
  export const DIAGONAL_RUN_LEAST = 3;
126
215
  function runsAlong(tiles, line, least) {
@@ -147,6 +236,17 @@ function runsAlong(tiles, line, least) {
147
236
  * Every run the grid is read by: two or more tiles across, then down, and
148
237
  * with Diagonals three or more down to the right, then down to the left. A
149
238
  * tile with nothing beside it in a line is no run.
239
+ *
240
+ * @param tiles - The map from row,column square names to internal tile codes.
241
+ * @param rules - Whether diagonal runs are also judged.
242
+ * @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.
243
+ * @example
244
+ * ```ts
245
+ * import { runsOf } from "@johnmorrisdotca/kumimoji";
246
+ *
247
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
248
+ * console.log(runsOf(tiles));
249
+ * ```
150
250
  */
151
251
  export function runsOf(tiles, rules = {}) {
152
252
  const runs = [...runsAlong(tiles, "across", 2), ...runsAlong(tiles, "down", 2)];
@@ -160,6 +260,17 @@ export function runsOf(tiles, rules = {}) {
160
260
  * other in one of those runs are joined too: a diagonal word holds a
161
261
  * crossword together as a word across does. A pair touching at a corner is
162
262
  * never a link, because it is never read.
263
+ *
264
+ * @param tiles - The map from row,column square names to internal tile codes.
265
+ * @param links - The runs connecting groups; computed from the grid when omitted.
266
+ * @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.
267
+ * @example
268
+ * ```ts
269
+ * import { groupsOf } from "@johnmorrisdotca/kumimoji";
270
+ *
271
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
272
+ * console.log(groupsOf(tiles));
273
+ * ```
163
274
  */
164
275
  export function groupsOf(tiles, links = []) {
165
276
  const joined = new Map();
@@ -182,7 +293,13 @@ export function groupsOf(tiles, links = []) {
182
293
  const at = queue.pop();
183
294
  group.push(at);
184
295
  const { row, col } = placeOf(at);
185
- for (const near of [squareAt(row - 1, col), squareAt(row + 1, col), squareAt(row, col - 1), squareAt(row, col + 1), ...(joined.get(at) ?? [])]) {
296
+ for (const near of [
297
+ squareAt(row - 1, col),
298
+ squareAt(row + 1, col),
299
+ squareAt(row, col - 1),
300
+ squareAt(row, col + 1),
301
+ ...(joined.get(at) ?? []),
302
+ ]) {
186
303
  if (tiles.has(near) && !seen.has(near)) {
187
304
  seen.add(near);
188
305
  queue.push(near);
@@ -193,7 +310,21 @@ export function groupsOf(tiles, links = []) {
193
310
  }
194
311
  return groups.sort((a, b) => b.length - a.length);
195
312
  }
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. */
313
+ /** 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.
314
+ *
315
+ * @param tiles - The map from row,column square names to internal tile codes.
316
+ * @param isWord - The predicate that accepts a readable word.
317
+ * @param readable - The conversion from tile codes to readable words.
318
+ * @param rules - Whether diagonal runs are also judged.
319
+ * @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.
320
+ * @example
321
+ * ```ts
322
+ * import { judgeGrid } from "@johnmorrisdotca/kumimoji";
323
+ *
324
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
325
+ * console.log(judgeGrid(tiles,word=>word==="cat"));
326
+ * ```
327
+ */
197
328
  export function judgeGrid(tiles, isWord, readable = (word) => word, rules = {}) {
198
329
  const misspelt = new Set();
199
330
  const notWords = [];
@@ -207,5 +338,11 @@ export function judgeGrid(tiles, isWord, readable = (word) => word, rules = {})
207
338
  }
208
339
  const groups = groupsOf(tiles, runs.filter((run) => run.line === "downRight" || run.line === "downLeft"));
209
340
  const apart = new Set(groups.slice(1).flat());
210
- return { sound: tiles.size >= 2 && groups.length === 1 && notWords.length === 0, tiles: tiles.size, misspelt, apart, notWords };
341
+ return {
342
+ sound: tiles.size >= 2 && groups.length === 1 && notWords.length === 0,
343
+ tiles: tiles.size,
344
+ misspelt,
345
+ apart,
346
+ notWords,
347
+ };
211
348
  }
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/index.d.ts CHANGED
@@ -16,33 +16,33 @@
16
16
  * a test through `@johnmorrisdotca/kumimoji/words`, which reads them from
17
17
  * disk.
18
18
  */
19
- export * from "./kumimoji.types.ts";
20
- export * from "./tiles.constants.ts";
21
- export * from "./kana.ts";
22
- export * from "./tileFace.ts";
23
- export * from "./tileFamily.ts";
24
- export * from "./tileWords.ts";
25
- export * from "./grid.ts";
26
- export * from "./placement.ts";
27
- export * from "./wilds.ts";
28
- export * from "./judge.ts";
29
19
  export * from "./check.ts";
30
- export * from "./generate.ts";
31
- export * from "./play.ts";
32
- export * from "./help.ts";
33
- export * from "./turn.ts";
34
- export * from "./tableView.ts";
35
- export * from "./showcase.ts";
36
- export * from "./party.types.ts";
37
- export * from "./party.ts";
38
- export * from "./partyTurns.ts";
39
- export * from "./partySeats.ts";
40
- export * from "./partyKept.ts";
41
20
  export * from "./computer.types.ts";
42
21
  export * from "./computerPlay.ts";
43
22
  export * from "./computerTurn.ts";
44
- export * from "./random.ts";
45
23
  export * from "./daily.ts";
46
24
  export * from "./export.ts";
25
+ export * from "./generate.ts";
26
+ export * from "./grid.ts";
27
+ export * from "./help.ts";
28
+ export * from "./judge.ts";
29
+ export * from "./kana.ts";
30
+ export * from "./kumimoji.types.ts";
31
+ export * from "./party.ts";
32
+ export * from "./party.types.ts";
33
+ export * from "./partyKept.ts";
34
+ export * from "./partySeats.ts";
35
+ export * from "./partyTurns.ts";
36
+ export * from "./placement.ts";
37
+ export * from "./play.ts";
38
+ export * from "./random.ts";
39
+ export * from "./showcase.ts";
47
40
  export * from "./strings.ts";
41
+ export * from "./tableView.ts";
42
+ export * from "./tileFace.ts";
43
+ export * from "./tileFamily.ts";
44
+ export * from "./tiles.constants.ts";
45
+ export * from "./tileWords.ts";
46
+ export * from "./turn.ts";
48
47
  export { KUMIMOJI_VERSION } from "./version.ts";
48
+ export * from "./wilds.ts";