@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
@@ -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, b: 3, c: 3, d: 6, e: 18, f: 3, g: 4, h: 3, i: 12, j: 2, k: 2, l: 5, m: 3,
19
- n: 8, o: 11, p: 3, q: 2, r: 9, s: 6, t: 9, u: 6, v: 3, w: 3, x: 2, y: 3, z: 2,
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, い: 11, う: 12, え: 1, お: 2, か: 7, き: 6, く: 6, け: 3, こ: 4,
37
- さ: 3, し: 10, す: 2, せ: 3, そ: 2, た: 4, ち: 3, つ: 6, て: 2, と: 3,
38
- な: 1, に: 1, ぬ: 1, ね: 1, の: 1, は: 2, ひ: 2, ふ: 2, へ: 1, ほ: 1,
39
- ま: 2, み: 1, む: 1, め: 1, も: 1, や: 2, ゆ: 4, よ: 6, ら: 1, り: 3,
40
- る: 3, れ: 1, ろ: 1, わ: 1, ん: 11,
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: 30000 };
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 { top: Math.min(a.row, b.row), left: Math.min(a.col, b.col), rows: Math.abs(a.row - b.row) + 1, cols: Math.abs(a.col - b.col) + 1 };
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);
@@ -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 ? null : verdict.misspelt.has(square) ? "misspelt" : verdict.apart.has(square) ? "apart" : "sound";
33
- squares.push({ square, row, col, tile, glyph: tile === null ? "" : glyphOf(tile), wild: tile !== null && tileFace(tile).wild, mark });
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 };