@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.
- package/CHANGELOG.md +33 -1
- package/CONTRIBUTING.md +11 -2
- package/README.md +80 -39
- package/dist/check.d.ts +26 -1
- package/dist/check.js +30 -3
- package/dist/computer.types.d.ts +24 -2
- package/dist/computerPlay.d.ts +45 -2
- package/dist/computerPlay.js +56 -6
- package/dist/computerTurn.d.ts +42 -3
- package/dist/computerTurn.js +47 -5
- package/dist/daily.d.ts +22 -2
- package/dist/daily.js +23 -3
- 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 +359 -77
- 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 +109 -9
- package/dist/generate.d.ts +14 -0
- package/dist/generate.js +32 -5
- package/dist/grid.d.ts +181 -10
- package/dist/grid.js +148 -11
- package/dist/help.d.ts +36 -3
- package/dist/help.js +36 -3
- package/dist/index.d.ts +22 -22
- package/dist/index.js +22 -22
- package/dist/judge.d.ts +14 -0
- package/dist/judge.js +14 -0
- package/dist/kana.d.ts +23 -1
- package/dist/kana.js +62 -7
- package/dist/kumimoji.types.d.ts +70 -5
- package/dist/party.d.ts +268 -14
- package/dist/party.js +296 -19
- package/dist/party.types.d.ts +50 -2
- package/dist/partyKept.d.ts +74 -4
- package/dist/partyKept.js +127 -12
- package/dist/partySeats.d.ts +92 -6
- package/dist/partySeats.js +83 -8
- package/dist/partyTurns.d.ts +171 -5
- package/dist/partyTurns.js +187 -8
- package/dist/placement.d.ts +50 -2
- package/dist/placement.js +35 -2
- package/dist/play.d.ts +247 -15
- package/dist/play.js +251 -18
- package/dist/random.d.ts +34 -3
- package/dist/random.js +23 -2
- package/dist/react.d.ts +42 -4
- package/dist/react.js +54 -7
- package/dist/showcase.d.ts +83 -7
- package/dist/showcase.js +61 -7
- 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 +94 -12
- package/dist/tileWordsModule.d.ts +12 -2
- package/dist/tileWordsModule.js +14 -2
- package/dist/tiles.constants.d.ts +99 -5
- package/dist/tiles.constants.js +171 -13
- package/dist/turn.d.ts +82 -4
- package/dist/turn.js +88 -5
- package/dist/ui/board.d.ts +60 -5
- package/dist/ui/board.js +44 -4
- package/dist/ui/draw.d.ts +62 -0
- package/dist/ui/draw.js +229 -0
- package/dist/ui/mount.d.ts +41 -2
- package/dist/ui/mount.js +190 -265
- package/dist/ui/style.d.ts +6 -1
- package/dist/ui/style.js +6 -0
- package/dist/ui.d.ts +3 -3
- package/dist/ui.js +2 -2
- package/dist/version.d.ts +9 -2
- package/dist/version.js +9 -2
- package/dist/wilds.d.ts +22 -1
- package/dist/wilds.js +25 -3
- package/package.json +68 -61
package/dist/tiles.constants.js
CHANGED
|
@@ -13,10 +13,40 @@
|
|
|
13
13
|
*
|
|
14
14
|
* To tune the letters, change the counts here. The total is checked by
|
|
15
15
|
* `tiles.test.ts`, so an edit that loses a tile says so.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { TILE_MIX } from "@johnmorrisdotca/kumimoji";
|
|
20
|
+
* console.log(TILE_MIX);
|
|
21
|
+
* ```
|
|
16
22
|
*/
|
|
17
23
|
export const TILE_MIX = {
|
|
18
|
-
a: 13,
|
|
19
|
-
|
|
24
|
+
a: 13,
|
|
25
|
+
b: 3,
|
|
26
|
+
c: 3,
|
|
27
|
+
d: 6,
|
|
28
|
+
e: 18,
|
|
29
|
+
f: 3,
|
|
30
|
+
g: 4,
|
|
31
|
+
h: 3,
|
|
32
|
+
i: 12,
|
|
33
|
+
j: 2,
|
|
34
|
+
k: 2,
|
|
35
|
+
l: 5,
|
|
36
|
+
m: 3,
|
|
37
|
+
n: 8,
|
|
38
|
+
o: 11,
|
|
39
|
+
p: 3,
|
|
40
|
+
q: 2,
|
|
41
|
+
r: 9,
|
|
42
|
+
s: 6,
|
|
43
|
+
t: 9,
|
|
44
|
+
u: 6,
|
|
45
|
+
v: 3,
|
|
46
|
+
w: 3,
|
|
47
|
+
x: 2,
|
|
48
|
+
y: 3,
|
|
49
|
+
z: 2,
|
|
20
50
|
};
|
|
21
51
|
/**
|
|
22
52
|
* THE JAPANESE SET: 144 hiragana tiles in 45 kinds (`kana.ts`), as the English
|
|
@@ -31,15 +61,68 @@ export const TILE_MIX = {
|
|
|
31
61
|
* Fixed here rather than taken from the monthly dictionary refresh, which
|
|
32
62
|
* prints what it measures beside this table (`scripts/word-lists-ja.mjs`): a
|
|
33
63
|
* kept game's bag is checked against these counts.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { JAPANESE_TILE_MIX } from "@johnmorrisdotca/kumimoji";
|
|
68
|
+
* console.log(JAPANESE_TILE_MIX);
|
|
69
|
+
* ```
|
|
34
70
|
*/
|
|
35
71
|
export const JAPANESE_TILE_MIX = {
|
|
36
|
-
あ: 2,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
72
|
+
あ: 2,
|
|
73
|
+
い: 11,
|
|
74
|
+
う: 12,
|
|
75
|
+
え: 1,
|
|
76
|
+
お: 2,
|
|
77
|
+
か: 7,
|
|
78
|
+
き: 6,
|
|
79
|
+
く: 6,
|
|
80
|
+
け: 3,
|
|
81
|
+
こ: 4,
|
|
82
|
+
さ: 3,
|
|
83
|
+
し: 10,
|
|
84
|
+
す: 2,
|
|
85
|
+
せ: 3,
|
|
86
|
+
そ: 2,
|
|
87
|
+
た: 4,
|
|
88
|
+
ち: 3,
|
|
89
|
+
つ: 6,
|
|
90
|
+
て: 2,
|
|
91
|
+
と: 3,
|
|
92
|
+
な: 1,
|
|
93
|
+
に: 1,
|
|
94
|
+
ぬ: 1,
|
|
95
|
+
ね: 1,
|
|
96
|
+
の: 1,
|
|
97
|
+
は: 2,
|
|
98
|
+
ひ: 2,
|
|
99
|
+
ふ: 2,
|
|
100
|
+
へ: 1,
|
|
101
|
+
ほ: 1,
|
|
102
|
+
ま: 2,
|
|
103
|
+
み: 1,
|
|
104
|
+
む: 1,
|
|
105
|
+
め: 1,
|
|
106
|
+
も: 1,
|
|
107
|
+
や: 2,
|
|
108
|
+
ゆ: 4,
|
|
109
|
+
よ: 6,
|
|
110
|
+
ら: 1,
|
|
111
|
+
り: 3,
|
|
112
|
+
る: 3,
|
|
113
|
+
れ: 1,
|
|
114
|
+
ろ: 1,
|
|
115
|
+
わ: 1,
|
|
116
|
+
ん: 11,
|
|
41
117
|
};
|
|
42
|
-
/** The whole set, counted from the table.
|
|
118
|
+
/** The whole set, counted from the table.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* import { TILE_MIX_TOTAL } from "@johnmorrisdotca/kumimoji";
|
|
123
|
+
* console.log(TILE_MIX_TOTAL);
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
43
126
|
export const TILE_MIX_TOTAL = Object.values(TILE_MIX).reduce((sum, count) => sum + count, 0);
|
|
44
127
|
/**
|
|
45
128
|
* THERE IS NO BOARD. John, 2026-09-26: "curious if we just have a large board
|
|
@@ -48,6 +131,12 @@ export const TILE_MIX_TOTAL = Object.values(TILE_MIX).reduce((sum, count) => sum
|
|
|
48
131
|
* grows with them (`tableView.ts`), so a grid is as wide and as tall as its
|
|
49
132
|
* player builds it. This is only the most a finished grid may measure either
|
|
50
133
|
* way before the check refuses it unread: fifty tiles in one line is fifty.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* import { KUMIMOJI_GRID_MOST } from "@johnmorrisdotca/kumimoji";
|
|
138
|
+
* console.log(KUMIMOJI_GRID_MOST);
|
|
139
|
+
* ```
|
|
51
140
|
*/
|
|
52
141
|
export const KUMIMOJI_GRID_MOST = 60;
|
|
53
142
|
/**
|
|
@@ -55,24 +144,56 @@ export const KUMIMOJI_GRID_MOST = 60;
|
|
|
55
144
|
* 2026-09-26: "you were given seven or 11 starting tiles". Three is for the
|
|
56
145
|
* browser tests alone — a game that can be finished in a few presses — and is
|
|
57
146
|
* never offered on the set-up screen.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { KUMIMOJI_HANDS } from "@johnmorrisdotca/kumimoji";
|
|
151
|
+
* console.log(KUMIMOJI_HANDS);
|
|
152
|
+
* ```
|
|
58
153
|
*/
|
|
59
154
|
export const KUMIMOJI_HANDS = { tiny: 3, quick: 7, classic: 11 };
|
|
60
155
|
/**
|
|
61
156
|
* SHORT GAME TOTALS, by opening hand. Medium and Full derive from the tile
|
|
62
157
|
* inventory in `kumimojiTileCount`; these stay the existing Short lengths.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* import { KUMIMOJI_BAG } from "@johnmorrisdotca/kumimoji";
|
|
162
|
+
* console.log(KUMIMOJI_BAG);
|
|
163
|
+
* ```
|
|
63
164
|
*/
|
|
64
165
|
export const KUMIMOJI_BAG = {
|
|
65
166
|
[KUMIMOJI_HANDS.tiny]: 5,
|
|
66
167
|
[KUMIMOJI_HANDS.quick]: 40,
|
|
67
168
|
[KUMIMOJI_HANDS.classic]: 50,
|
|
68
169
|
};
|
|
69
|
-
/** Wild tiles per original 40/50-tile game, included within the bag total.
|
|
170
|
+
/** Wild tiles per original 40/50-tile game, included within the bag total.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* import { KUMIMOJI_WILDS } from "@johnmorrisdotca/kumimoji";
|
|
175
|
+
* console.log(KUMIMOJI_WILDS);
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
70
178
|
export const KUMIMOJI_WILDS = {
|
|
71
179
|
[KUMIMOJI_HANDS.tiny]: { easy: 0, medium: 0, hard: 0 },
|
|
72
180
|
[KUMIMOJI_HANDS.quick]: { easy: 6, medium: 3, hard: 0 },
|
|
73
181
|
[KUMIMOJI_HANDS.classic]: { easy: 8, medium: 4, hard: 0 },
|
|
74
182
|
};
|
|
75
|
-
/** Tile count for a selected length and inventory size. Double supplies two sets.
|
|
183
|
+
/** Tile count for a selected length and inventory size. Double supplies two sets.
|
|
184
|
+
*
|
|
185
|
+
* @param hand - The hand size or tile codes, as declared by the function signature.
|
|
186
|
+
* @param length - The game length or decoded word length, as declared.
|
|
187
|
+
* @param setSize - The number of physical tiles in the language set.
|
|
188
|
+
* @param doubleSet - Whether to use two English tile sets.
|
|
189
|
+
* @returns Tile count for a selected length and inventory size. Double supplies two sets.
|
|
190
|
+
* @example
|
|
191
|
+
* ```ts
|
|
192
|
+
* import { kumimojiTileCount } from "@johnmorrisdotca/kumimoji";
|
|
193
|
+
*
|
|
194
|
+
* console.log(kumimojiTileCount(7,"short"));
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
76
197
|
export function kumimojiTileCount(hand, length, setSize = TILE_MIX_TOTAL, doubleSet = false) {
|
|
77
198
|
const short = KUMIMOJI_BAG[hand];
|
|
78
199
|
if (short === undefined)
|
|
@@ -89,7 +210,19 @@ export function kumimojiTileCount(hand, length, setSize = TILE_MIX_TOTAL, double
|
|
|
89
210
|
return Math.floor(available / 2);
|
|
90
211
|
return available;
|
|
91
212
|
}
|
|
92
|
-
/** Wilds scale with the bag; doubling the tile set doubles the wild count too.
|
|
213
|
+
/** Wilds scale with the bag; doubling the tile set doubles the wild count too.
|
|
214
|
+
*
|
|
215
|
+
* @param hand - The hand size or tile codes, as declared by the function signature.
|
|
216
|
+
* @param level - The difficulty that determines the wildcard allowance.
|
|
217
|
+
* @param totalTiles - The total number of physical tiles in this bag.
|
|
218
|
+
* @returns Wilds scale with the bag; doubling the tile set doubles the wild count too.
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* import { kumimojiWildCount, kumimojiTileCount } from "@johnmorrisdotca/kumimoji";
|
|
222
|
+
*
|
|
223
|
+
* console.log(kumimojiWildCount(7,"easy",kumimojiTileCount(7,"short")));
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
93
226
|
export function kumimojiWildCount(hand, level, totalTiles) {
|
|
94
227
|
const short = KUMIMOJI_BAG[hand];
|
|
95
228
|
const wilds = KUMIMOJI_WILDS[hand];
|
|
@@ -99,13 +232,26 @@ export function kumimojiWildCount(hand, level, totalTiles) {
|
|
|
99
232
|
throw new Error(`Invalid Kumimoji tile count: ${totalTiles}.`);
|
|
100
233
|
return Math.round((wilds[level] * totalTiles) / short);
|
|
101
234
|
}
|
|
102
|
-
/** How many tiles one Draw takes from the bag, once the hand is used and the grid is sound.
|
|
235
|
+
/** How many tiles one Draw takes from the bag, once the hand is used and the grid is sound.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* import { KUMIMOJI_DRAW } from "@johnmorrisdotca/kumimoji";
|
|
240
|
+
* console.log(KUMIMOJI_DRAW);
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
103
243
|
export const KUMIMOJI_DRAW = 1;
|
|
104
244
|
/**
|
|
105
245
|
* THE TRADE: one awkward tile back into the bag for three new ones — the
|
|
106
246
|
* classic way out of a hand of Q, X and J. The tile given back goes to the
|
|
107
247
|
* bottom of the bag, so it comes round again before the end; offered only
|
|
108
248
|
* while the bag has three to give.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* import { KUMIMOJI_TRADE } from "@johnmorrisdotca/kumimoji";
|
|
253
|
+
* console.log(KUMIMOJI_TRADE);
|
|
254
|
+
* ```
|
|
109
255
|
*/
|
|
110
256
|
export const KUMIMOJI_TRADE = { give: 1, take: 3 };
|
|
111
257
|
/**
|
|
@@ -114,8 +260,14 @@ export const KUMIMOJI_TRADE = { give: 1, take: 3 };
|
|
|
114
260
|
* speed, which falls away evenly until a game that took half a minute a tile
|
|
115
261
|
* earns no speed at all. A Classic game of fifty tiles in ten minutes is
|
|
116
262
|
* 500 + 300 = 800. The time is the browser's clock, as every solo time here is.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* import { KUMIMOJI_SCORE } from "@johnmorrisdotca/kumimoji";
|
|
267
|
+
* console.log(KUMIMOJI_SCORE);
|
|
268
|
+
* ```
|
|
117
269
|
*/
|
|
118
|
-
export const KUMIMOJI_SCORE = { tile: 10, slowestMsATile:
|
|
270
|
+
export const KUMIMOJI_SCORE = { tile: 10, slowestMsATile: 30_000 };
|
|
119
271
|
/**
|
|
120
272
|
* PASS AND PLAY: up to eight people round one device, each with a hand and a
|
|
121
273
|
* table of their own from one shared bag (`party.ts`). John, 2026-09-28: "pass
|
|
@@ -128,5 +280,11 @@ export const KUMIMOJI_SCORE = { tile: 10, slowestMsATile: 30000 };
|
|
|
128
280
|
* set, and chooses it when the count reaches it (John, 2026-09-28: "when having
|
|
129
281
|
* 6 or more players, we should recommend the double size 288 version"); in
|
|
130
282
|
* Japanese, which has no Double, the Full game instead.
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```ts
|
|
286
|
+
* import { KUMIMOJI_PARTY } from "@johnmorrisdotca/kumimoji";
|
|
287
|
+
* console.log(KUMIMOJI_PARTY);
|
|
288
|
+
* ```
|
|
131
289
|
*/
|
|
132
290
|
export const KUMIMOJI_PARTY = { least: 2, most: 8, nameMost: 20, doubleFrom: 6 };
|
package/dist/turn.d.ts
CHANGED
|
@@ -17,24 +17,69 @@ import type { Area, View } from "./tableView.ts";
|
|
|
17
17
|
* Pure, like the rest of the view (`tableView.ts`), which works on the turned
|
|
18
18
|
* squares unchanged: fitting, zooming and panning are all in screen terms.
|
|
19
19
|
*/
|
|
20
|
-
/** The next turn a press gives: a quarter clockwise, and four presses back to the start.
|
|
20
|
+
/** The next turn a press gives: a quarter clockwise, and four presses back to the start.
|
|
21
|
+
*
|
|
22
|
+
* @param turn - The number of quarter turns of the view.
|
|
23
|
+
* @returns The next turn a press gives: a quarter clockwise, and four presses back to the start.
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { nextTurn } from "@johnmorrisdotca/kumimoji";
|
|
27
|
+
*
|
|
28
|
+
* console.log(nextTurn(3));
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
21
31
|
export declare function nextTurn(turn: Turn): Turn;
|
|
22
32
|
/**
|
|
23
33
|
* Where square (row, col) of the grid is drawn with the table turned: a
|
|
24
34
|
* quarter clockwise sends a word running right to one running down, and one
|
|
25
35
|
* running down to one running left. It is linear, so it turns a step (a
|
|
26
36
|
* direction) as well as a square.
|
|
37
|
+
*
|
|
38
|
+
* @param row - The integer row coordinate, which may be negative.
|
|
39
|
+
* @param col - The integer column coordinate, which may be negative.
|
|
40
|
+
* @param turn - The number of quarter turns of the view.
|
|
41
|
+
* @returns Where square (row, col) of the grid is drawn with the table turned: a quarter clockwise sends a word running right to one running down, and one running down to one running left. It is linear, so it turns a step (a direction) as well as a square.
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { turnPlace } from "@johnmorrisdotca/kumimoji";
|
|
45
|
+
*
|
|
46
|
+
* console.log(turnPlace(1,2,1));
|
|
47
|
+
* ```
|
|
27
48
|
*/
|
|
28
49
|
export declare function turnPlace(row: number, col: number, turn: Turn): {
|
|
29
50
|
row: number;
|
|
30
51
|
col: number;
|
|
31
52
|
};
|
|
32
|
-
/** The grid's square drawn at (row, col) of the turned table: `turnPlace` undone.
|
|
53
|
+
/** The grid's square drawn at (row, col) of the turned table: `turnPlace` undone.
|
|
54
|
+
*
|
|
55
|
+
* @param row - The integer row coordinate, which may be negative.
|
|
56
|
+
* @param col - The integer column coordinate, which may be negative.
|
|
57
|
+
* @param turn - The number of quarter turns of the view.
|
|
58
|
+
* @returns The grid's square drawn at (row, col) of the turned table: `turnPlace` undone.
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { unturnPlace } from "@johnmorrisdotca/kumimoji";
|
|
62
|
+
*
|
|
63
|
+
* console.log(unturnPlace(1,2,1));
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
33
66
|
export declare function unturnPlace(row: number, col: number, turn: Turn): {
|
|
34
67
|
row: number;
|
|
35
68
|
col: number;
|
|
36
69
|
};
|
|
37
|
-
/** The squares a turned table shows: the grid's area, turned.
|
|
70
|
+
/** The squares a turned table shows: the grid's area, turned.
|
|
71
|
+
*
|
|
72
|
+
* @param area - The occupied table bounds.
|
|
73
|
+
* @param turn - The number of quarter turns of the view.
|
|
74
|
+
* @returns The squares a turned table shows: the grid's area, turned.
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* import { turnArea } from "@johnmorrisdotca/kumimoji";
|
|
78
|
+
*
|
|
79
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
80
|
+
* console.log(turnArea(area,1));
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
38
83
|
export declare function turnArea(area: Area, turn: Turn): Area;
|
|
39
84
|
/**
|
|
40
85
|
* A view the player zoomed or panned, turned a quarter clockwise with the
|
|
@@ -44,18 +89,51 @@ export declare function turnArea(area: Area, turn: Turn): Area;
|
|
|
44
89
|
* On the screen a square's corner is `x + col * tile`; the turn takes a point
|
|
45
90
|
* (row v, col u) of the table to (row u, col 1 - v), which is a quarter turn
|
|
46
91
|
* about the middle of square (0, 0) — the same turn as `turnPlace`.
|
|
92
|
+
*
|
|
93
|
+
* @param view - The current tile size and pixel translation.
|
|
94
|
+
* @param width - The available viewport width in pixels.
|
|
95
|
+
* @param height - The available viewport height in pixels.
|
|
96
|
+
* @returns A view the player zoomed or panned, turned a quarter clockwise with the table about the middle of its box: the same zoom, and the spot of the table that was in the middle stays there. (A fitted view simply fits again.)
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* import { turnView } from "@johnmorrisdotca/kumimoji";
|
|
100
|
+
*
|
|
101
|
+
* const view = {tile:40,x:100,y:100};
|
|
102
|
+
* console.log(turnView(view,640,480));
|
|
103
|
+
* ```
|
|
47
104
|
*/
|
|
48
105
|
export declare function turnView(view: View, width: number, height: number): View;
|
|
49
106
|
/**
|
|
50
107
|
* Which way typed letters run ON THE SCREEN. Typing lays a word across or
|
|
51
108
|
* down the grid, so that it reads as a word; with the table turned, that is
|
|
52
109
|
* another way on the screen, and the cursor's arrow points it.
|
|
110
|
+
*
|
|
111
|
+
* @param across - Whether to lay or type horizontally rather than vertically.
|
|
112
|
+
* @param turn - The number of quarter turns of the view.
|
|
113
|
+
* @returns Which way typed letters run ON THE SCREEN. Typing lays a word across or down the grid, so that it reads as a word; with the table turned, that is another way on the screen, and the cursor's arrow points it.
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* import { typingWay } from "@johnmorrisdotca/kumimoji";
|
|
117
|
+
*
|
|
118
|
+
* console.log(typingWay(true,1));
|
|
119
|
+
* ```
|
|
53
120
|
*/
|
|
54
121
|
export declare function typingWay(across: boolean, turn: Turn): {
|
|
55
122
|
arrow: string;
|
|
56
123
|
name: string;
|
|
57
124
|
};
|
|
58
|
-
/** The step in the grid an arrow key means: the square that way on the screen, with the table turned. Null for any other key.
|
|
125
|
+
/** The step in the grid an arrow key means: the square that way on the screen, with the table turned. Null for any other key.
|
|
126
|
+
*
|
|
127
|
+
* @param key - The keyboard key identifier.
|
|
128
|
+
* @param turn - The number of quarter turns of the view.
|
|
129
|
+
* @returns The step in the grid an arrow key means: the square that way on the screen, with the table turned. null for any other key.
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* import { arrowStep } from "@johnmorrisdotca/kumimoji";
|
|
133
|
+
*
|
|
134
|
+
* console.log(arrowStep("ArrowRight",1));
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
59
137
|
export declare function arrowStep(key: string, turn: Turn): {
|
|
60
138
|
row: number;
|
|
61
139
|
col: number;
|
package/dist/turn.js
CHANGED
|
@@ -15,7 +15,17 @@
|
|
|
15
15
|
* Pure, like the rest of the view (`tableView.ts`), which works on the turned
|
|
16
16
|
* squares unchanged: fitting, zooming and panning are all in screen terms.
|
|
17
17
|
*/
|
|
18
|
-
/** The next turn a press gives: a quarter clockwise, and four presses back to the start.
|
|
18
|
+
/** The next turn a press gives: a quarter clockwise, and four presses back to the start.
|
|
19
|
+
*
|
|
20
|
+
* @param turn - The number of quarter turns of the view.
|
|
21
|
+
* @returns The next turn a press gives: a quarter clockwise, and four presses back to the start.
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { nextTurn } from "@johnmorrisdotca/kumimoji";
|
|
25
|
+
*
|
|
26
|
+
* console.log(nextTurn(3));
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
19
29
|
export function nextTurn(turn) {
|
|
20
30
|
return ((turn + 1) % 4);
|
|
21
31
|
}
|
|
@@ -26,6 +36,17 @@ const negate = (n) => 0 - n;
|
|
|
26
36
|
* quarter clockwise sends a word running right to one running down, and one
|
|
27
37
|
* running down to one running left. It is linear, so it turns a step (a
|
|
28
38
|
* direction) as well as a square.
|
|
39
|
+
*
|
|
40
|
+
* @param row - The integer row coordinate, which may be negative.
|
|
41
|
+
* @param col - The integer column coordinate, which may be negative.
|
|
42
|
+
* @param turn - The number of quarter turns of the view.
|
|
43
|
+
* @returns Where square (row, col) of the grid is drawn with the table turned: a quarter clockwise sends a word running right to one running down, and one running down to one running left. It is linear, so it turns a step (a direction) as well as a square.
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { turnPlace } from "@johnmorrisdotca/kumimoji";
|
|
47
|
+
*
|
|
48
|
+
* console.log(turnPlace(1,2,1));
|
|
49
|
+
* ```
|
|
29
50
|
*/
|
|
30
51
|
export function turnPlace(row, col, turn) {
|
|
31
52
|
switch (turn) {
|
|
@@ -39,15 +60,44 @@ export function turnPlace(row, col, turn) {
|
|
|
39
60
|
return { row: negate(col), col: row };
|
|
40
61
|
}
|
|
41
62
|
}
|
|
42
|
-
/** The grid's square drawn at (row, col) of the turned table: `turnPlace` undone.
|
|
63
|
+
/** The grid's square drawn at (row, col) of the turned table: `turnPlace` undone.
|
|
64
|
+
*
|
|
65
|
+
* @param row - The integer row coordinate, which may be negative.
|
|
66
|
+
* @param col - The integer column coordinate, which may be negative.
|
|
67
|
+
* @param turn - The number of quarter turns of the view.
|
|
68
|
+
* @returns The grid's square drawn at (row, col) of the turned table: `turnPlace` undone.
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* import { unturnPlace } from "@johnmorrisdotca/kumimoji";
|
|
72
|
+
*
|
|
73
|
+
* console.log(unturnPlace(1,2,1));
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
43
76
|
export function unturnPlace(row, col, turn) {
|
|
44
77
|
return turnPlace(row, col, ((4 - turn) % 4));
|
|
45
78
|
}
|
|
46
|
-
/** The squares a turned table shows: the grid's area, turned.
|
|
79
|
+
/** The squares a turned table shows: the grid's area, turned.
|
|
80
|
+
*
|
|
81
|
+
* @param area - The occupied table bounds.
|
|
82
|
+
* @param turn - The number of quarter turns of the view.
|
|
83
|
+
* @returns The squares a turned table shows: the grid's area, turned.
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { turnArea } from "@johnmorrisdotca/kumimoji";
|
|
87
|
+
*
|
|
88
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
89
|
+
* console.log(turnArea(area,1));
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
47
92
|
export function turnArea(area, turn) {
|
|
48
93
|
const a = turnPlace(area.top, area.left, turn);
|
|
49
94
|
const b = turnPlace(area.top + area.rows - 1, area.left + area.cols - 1, turn);
|
|
50
|
-
return {
|
|
95
|
+
return {
|
|
96
|
+
top: Math.min(a.row, b.row),
|
|
97
|
+
left: Math.min(a.col, b.col),
|
|
98
|
+
rows: Math.abs(a.row - b.row) + 1,
|
|
99
|
+
cols: Math.abs(a.col - b.col) + 1,
|
|
100
|
+
};
|
|
51
101
|
}
|
|
52
102
|
/**
|
|
53
103
|
* A view the player zoomed or panned, turned a quarter clockwise with the
|
|
@@ -57,6 +107,18 @@ export function turnArea(area, turn) {
|
|
|
57
107
|
* On the screen a square's corner is `x + col * tile`; the turn takes a point
|
|
58
108
|
* (row v, col u) of the table to (row u, col 1 - v), which is a quarter turn
|
|
59
109
|
* about the middle of square (0, 0) — the same turn as `turnPlace`.
|
|
110
|
+
*
|
|
111
|
+
* @param view - The current tile size and pixel translation.
|
|
112
|
+
* @param width - The available viewport width in pixels.
|
|
113
|
+
* @param height - The available viewport height in pixels.
|
|
114
|
+
* @returns A view the player zoomed or panned, turned a quarter clockwise with the table about the middle of its box: the same zoom, and the spot of the table that was in the middle stays there. (A fitted view simply fits again.)
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* import { turnView } from "@johnmorrisdotca/kumimoji";
|
|
118
|
+
*
|
|
119
|
+
* const view = {tile:40,x:100,y:100};
|
|
120
|
+
* console.log(turnView(view,640,480));
|
|
121
|
+
* ```
|
|
60
122
|
*/
|
|
61
123
|
export function turnView(view, width, height) {
|
|
62
124
|
const px = width / 2;
|
|
@@ -76,6 +138,16 @@ const WAYS = [
|
|
|
76
138
|
* Which way typed letters run ON THE SCREEN. Typing lays a word across or
|
|
77
139
|
* down the grid, so that it reads as a word; with the table turned, that is
|
|
78
140
|
* another way on the screen, and the cursor's arrow points it.
|
|
141
|
+
*
|
|
142
|
+
* @param across - Whether to lay or type horizontally rather than vertically.
|
|
143
|
+
* @param turn - The number of quarter turns of the view.
|
|
144
|
+
* @returns Which way typed letters run ON THE SCREEN. Typing lays a word across or down the grid, so that it reads as a word; with the table turned, that is another way on the screen, and the cursor's arrow points it.
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* import { typingWay } from "@johnmorrisdotca/kumimoji";
|
|
148
|
+
*
|
|
149
|
+
* console.log(typingWay(true,1));
|
|
150
|
+
* ```
|
|
79
151
|
*/
|
|
80
152
|
export function typingWay(across, turn) {
|
|
81
153
|
const step = turnPlace(across ? 0 : 1, across ? 1 : 0, turn);
|
|
@@ -89,7 +161,18 @@ const ARROW_KEYS = {
|
|
|
89
161
|
ArrowLeft: { row: 0, col: -1 },
|
|
90
162
|
ArrowUp: { row: -1, col: 0 },
|
|
91
163
|
};
|
|
92
|
-
/** The step in the grid an arrow key means: the square that way on the screen, with the table turned. Null for any other key.
|
|
164
|
+
/** The step in the grid an arrow key means: the square that way on the screen, with the table turned. Null for any other key.
|
|
165
|
+
*
|
|
166
|
+
* @param key - The keyboard key identifier.
|
|
167
|
+
* @param turn - The number of quarter turns of the view.
|
|
168
|
+
* @returns The step in the grid an arrow key means: the square that way on the screen, with the table turned. null for any other key.
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* import { arrowStep } from "@johnmorrisdotca/kumimoji";
|
|
172
|
+
*
|
|
173
|
+
* console.log(arrowStep("ArrowRight",1));
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
93
176
|
export function arrowStep(key, turn) {
|
|
94
177
|
const step = ARROW_KEYS[key];
|
|
95
178
|
return step === undefined ? null : unturnPlace(step.row, step.col, turn);
|
package/dist/ui/board.d.ts
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import { type GridVerdict, type Tiles } from "../grid.ts";
|
|
2
|
-
/** How a tile on the table stands: part of a sound crossword, in a run that is not a word, or apart from the rest.
|
|
2
|
+
/** How a tile on the table stands: part of a sound crossword, in a run that is not a word, or apart from the rest.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import type { TileMark } from "@johnmorrisdotca/kumimoji/ui";
|
|
7
|
+
*
|
|
8
|
+
* const value: TileMark = "sound";
|
|
9
|
+
* console.log(value);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
3
12
|
export type TileMark = "sound" | "misspelt" | "apart";
|
|
4
|
-
/** One square of the board drawn.
|
|
13
|
+
/** One square of the board drawn.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import type { BoardSquare } from "@johnmorrisdotca/kumimoji/ui";
|
|
18
|
+
*
|
|
19
|
+
* const value: BoardSquare = {square:"0,0",row:0,col:0,tile:"c",glyph:"c",wild:false,mark:null};
|
|
20
|
+
* console.log(value);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
5
23
|
export type BoardSquare = {
|
|
6
24
|
/** Its key, `squareAt(row, col)`. */
|
|
7
25
|
square: string;
|
|
@@ -16,20 +34,57 @@ export type BoardSquare = {
|
|
|
16
34
|
/** How the tile stands; null for an empty square, or with no verdict. */
|
|
17
35
|
mark: TileMark | null;
|
|
18
36
|
};
|
|
19
|
-
/** The part of the table to draw: how many rows and columns, and every square, row by row.
|
|
37
|
+
/** The part of the table to draw: how many rows and columns, and every square, row by row.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import type { BoardModel } from "@johnmorrisdotca/kumimoji/ui";
|
|
42
|
+
* import { boardModel } from "@johnmorrisdotca/kumimoji/ui";
|
|
43
|
+
*
|
|
44
|
+
* const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
|
|
45
|
+
* const value: BoardModel = boardModel(tiles,null);
|
|
46
|
+
* console.log(value);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
20
49
|
export type BoardModel = {
|
|
21
50
|
rows: number;
|
|
22
51
|
cols: number;
|
|
23
52
|
squares: BoardSquare[];
|
|
24
53
|
};
|
|
25
|
-
/** How many empty squares are kept round the tiles on every side, so there is always room to build out.
|
|
54
|
+
/** How many empty squares are kept round the tiles on every side, so there is always room to build out.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { BOARD_MARGIN } from "@johnmorrisdotca/kumimoji/ui";
|
|
59
|
+
* console.log(BOARD_MARGIN);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
26
62
|
export declare const BOARD_MARGIN = 2;
|
|
27
|
-
/** The fewest squares a side, so an empty or small table is still a table.
|
|
63
|
+
/** The fewest squares a side, so an empty or small table is still a table.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { BOARD_LEAST } from "@johnmorrisdotca/kumimoji/ui";
|
|
68
|
+
* console.log(BOARD_LEAST);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
28
71
|
export declare const BOARD_LEAST = 7;
|
|
29
72
|
/**
|
|
30
73
|
* THE PART OF THE TABLE TO DRAW, for a grid and its verdict: the tiles and a
|
|
31
74
|
* margin round them, at least `BOARD_LEAST` a side, each square with its tile,
|
|
32
75
|
* what is printed on it, and how it stands. Row by row, left to right. The
|
|
33
76
|
* grid itself has no edges; this is only the window a board shows it through.
|
|
77
|
+
*
|
|
78
|
+
* @param tiles - The map from row,column square names to internal tile codes.
|
|
79
|
+
* @param verdict - The native word and connectivity verdict for this grid.
|
|
80
|
+
* @param glyphOf - The function that renders an internal tile code as a visible glyph.
|
|
81
|
+
* @returns THE PART OF THE TABLE TO DRAW, for a grid and its verdict: the tiles and a margin round them, at least `BOARD_LEAST` a side, each square with its tile, what is printed on it, and how it stands. Row by row, left to right. The grid itself has no edges; this is only the window a board shows it through.
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { boardModel } from "@johnmorrisdotca/kumimoji/ui";
|
|
85
|
+
*
|
|
86
|
+
* const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
|
|
87
|
+
* console.log(boardModel(tiles,null).squares.length);
|
|
88
|
+
* ```
|
|
34
89
|
*/
|
|
35
90
|
export declare function boardModel(tiles: Tiles, verdict: GridVerdict | null, glyphOf?: (tile: string) => string): BoardModel;
|
package/dist/ui/board.js
CHANGED
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
import { boundsOf, squareAt } from "../grid.js";
|
|
2
2
|
import { tileFace } from "../tileFace.js";
|
|
3
|
-
/** How many empty squares are kept round the tiles on every side, so there is always room to build out.
|
|
3
|
+
/** How many empty squares are kept round the tiles on every side, so there is always room to build out.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { BOARD_MARGIN } from "@johnmorrisdotca/kumimoji/ui";
|
|
8
|
+
* console.log(BOARD_MARGIN);
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
4
11
|
export const BOARD_MARGIN = 2;
|
|
5
|
-
/** The fewest squares a side, so an empty or small table is still a table.
|
|
12
|
+
/** The fewest squares a side, so an empty or small table is still a table.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { BOARD_LEAST } from "@johnmorrisdotca/kumimoji/ui";
|
|
17
|
+
* console.log(BOARD_LEAST);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
6
20
|
export const BOARD_LEAST = 7;
|
|
7
21
|
/**
|
|
8
22
|
* THE PART OF THE TABLE TO DRAW, for a grid and its verdict: the tiles and a
|
|
9
23
|
* margin round them, at least `BOARD_LEAST` a side, each square with its tile,
|
|
10
24
|
* what is printed on it, and how it stands. Row by row, left to right. The
|
|
11
25
|
* grid itself has no edges; this is only the window a board shows it through.
|
|
26
|
+
*
|
|
27
|
+
* @param tiles - The map from row,column square names to internal tile codes.
|
|
28
|
+
* @param verdict - The native word and connectivity verdict for this grid.
|
|
29
|
+
* @param glyphOf - The function that renders an internal tile code as a visible glyph.
|
|
30
|
+
* @returns THE PART OF THE TABLE TO DRAW, for a grid and its verdict: the tiles and a margin round them, at least `BOARD_LEAST` a side, each square with its tile, what is printed on it, and how it stands. Row by row, left to right. The grid itself has no edges; this is only the window a board shows it through.
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { boardModel } from "@johnmorrisdotca/kumimoji/ui";
|
|
34
|
+
*
|
|
35
|
+
* const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
|
|
36
|
+
* console.log(boardModel(tiles,null).squares.length);
|
|
37
|
+
* ```
|
|
12
38
|
*/
|
|
13
39
|
export function boardModel(tiles, verdict, glyphOf = (tile) => tileFace(tile).glyph) {
|
|
14
40
|
const bounds = boundsOf(tiles) ?? { top: 0, left: 0, bottom: 0, right: 0 };
|
|
@@ -29,8 +55,22 @@ export function boardModel(tiles, verdict, glyphOf = (tile) => tileFace(tile).gl
|
|
|
29
55
|
for (let col = left; col < left + cols; col += 1) {
|
|
30
56
|
const square = squareAt(row, col);
|
|
31
57
|
const tile = tiles.get(square) ?? null;
|
|
32
|
-
const mark = tile === null || verdict === null
|
|
33
|
-
|
|
58
|
+
const mark = tile === null || verdict === null
|
|
59
|
+
? null
|
|
60
|
+
: verdict.misspelt.has(square)
|
|
61
|
+
? "misspelt"
|
|
62
|
+
: verdict.apart.has(square)
|
|
63
|
+
? "apart"
|
|
64
|
+
: "sound";
|
|
65
|
+
squares.push({
|
|
66
|
+
square,
|
|
67
|
+
row,
|
|
68
|
+
col,
|
|
69
|
+
tile,
|
|
70
|
+
glyph: tile === null ? "" : glyphOf(tile),
|
|
71
|
+
wild: tile !== null && tileFace(tile).wild,
|
|
72
|
+
mark,
|
|
73
|
+
});
|
|
34
74
|
}
|
|
35
75
|
}
|
|
36
76
|
return { rows, cols, squares };
|