@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.
- package/CHANGELOG.md +21 -1
- package/README.md +80 -39
- package/dist/check.d.ts +26 -1
- package/dist/check.js +26 -1
- package/dist/computer.types.d.ts +24 -2
- package/dist/computerPlay.d.ts +45 -2
- package/dist/computerPlay.js +45 -2
- package/dist/computerTurn.d.ts +42 -3
- package/dist/computerTurn.js +42 -3
- package/dist/daily.d.ts +22 -2
- package/dist/daily.js +22 -2
- package/dist/element-define.d.ts +1 -1
- package/dist/element-define.js +3 -13
- package/dist/element.d.ts +85 -4
- package/dist/element.js +176 -45
- package/dist/embed-day.d.ts +4 -0
- package/dist/embed-day.js +23 -0
- package/dist/export.d.ts +123 -6
- package/dist/export.js +91 -4
- package/dist/generate.d.ts +14 -0
- package/dist/generate.js +14 -0
- package/dist/grid.d.ts +181 -10
- package/dist/grid.js +122 -7
- package/dist/help.d.ts +36 -3
- package/dist/help.js +36 -3
- package/dist/judge.d.ts +14 -0
- package/dist/judge.js +14 -0
- package/dist/kana.d.ts +23 -1
- package/dist/kana.js +23 -1
- package/dist/kumimoji.types.d.ts +70 -5
- package/dist/party.d.ts +268 -14
- package/dist/party.js +268 -14
- package/dist/party.types.d.ts +50 -2
- package/dist/partyKept.d.ts +74 -4
- package/dist/partyKept.js +74 -4
- package/dist/partySeats.d.ts +92 -6
- package/dist/partySeats.js +72 -4
- package/dist/partyTurns.d.ts +171 -5
- package/dist/partyTurns.js +171 -5
- package/dist/placement.d.ts +50 -2
- package/dist/placement.js +30 -0
- package/dist/play.d.ts +247 -15
- package/dist/play.js +237 -15
- package/dist/random.d.ts +34 -3
- package/dist/random.js +23 -2
- package/dist/react.d.ts +42 -4
- package/dist/react.js +22 -5
- package/dist/showcase.d.ts +83 -7
- package/dist/showcase.js +49 -4
- package/dist/strings.d.ts +54 -5
- package/dist/strings.js +34 -3
- package/dist/tableView.d.ts +151 -8
- package/dist/tableView.js +129 -6
- package/dist/tileFace.d.ts +59 -5
- package/dist/tileFace.js +48 -4
- package/dist/tileFamily.d.ts +9 -0
- package/dist/tileFamily.js +9 -0
- package/dist/tileWords.d.ts +93 -6
- package/dist/tileWords.js +83 -6
- package/dist/tileWordsModule.d.ts +11 -1
- package/dist/tileWordsModule.js +11 -1
- package/dist/tiles.constants.d.ts +99 -5
- package/dist/tiles.constants.js +99 -5
- package/dist/turn.d.ts +82 -4
- package/dist/turn.js +82 -4
- package/dist/ui/board.d.ts +60 -5
- package/dist/ui/board.js +28 -2
- package/dist/ui/mount.d.ts +41 -2
- package/dist/ui/mount.js +38 -1
- package/dist/ui/style.d.ts +6 -1
- package/dist/ui/style.js +6 -0
- package/dist/version.d.ts +9 -2
- package/dist/version.js +9 -2
- package/dist/wilds.d.ts +22 -1
- package/dist/wilds.js +22 -1
- 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
|
か: "が", き: "ぎ", く: "ぐ", け: "げ", こ: "ご",
|
package/dist/kumimoji.types.d.ts
CHANGED
|
@@ -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";
|