@johnmorrisdotca/houseki 0.4.0 → 0.4.2
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 +29 -1
- package/README.md +77 -95
- package/dist/colour-chains/challenge.d.ts +12 -1
- package/dist/colour-chains/challenge.js +12 -1
- package/dist/colour-chains/content-types.d.ts +112 -0
- package/dist/colour-chains/content.d.ts +140 -3
- package/dist/colour-chains/content.js +140 -3
- package/dist/colour-chains/engine.d.ts +85 -6
- package/dist/colour-chains/engine.js +85 -6
- package/dist/colour-chains/input.d.ts +97 -7
- package/dist/colour-chains/input.js +97 -7
- package/dist/colour-chains/persistence.d.ts +36 -3
- package/dist/colour-chains/persistence.js +36 -3
- package/dist/colour-chains/types.d.ts +291 -17
- package/dist/colour-chains/validation.d.ts +12 -1
- package/dist/colour-chains/validation.js +12 -1
- package/dist/falling-triplets/content-types.d.ts +69 -0
- package/dist/falling-triplets/content.d.ts +60 -3
- package/dist/falling-triplets/content.js +60 -3
- package/dist/falling-triplets/engine.d.ts +122 -10
- package/dist/falling-triplets/engine.js +122 -10
- package/dist/falling-triplets/input.d.ts +61 -5
- package/dist/falling-triplets/input.js +61 -5
- package/dist/falling-triplets/match.d.ts +26 -2
- package/dist/falling-triplets/match.js +26 -2
- package/dist/falling-triplets/random.d.ts +34 -3
- package/dist/falling-triplets/random.js +34 -3
- package/dist/falling-triplets/types.d.ts +227 -3
- package/dist/gem-swap/content.d.ts +116 -0
- package/dist/gem-swap/content.js +72 -0
- package/dist/gem-swap/engine.d.ts +124 -9
- package/dist/gem-swap/engine.js +124 -9
- package/dist/gem-swap/persistence.d.ts +60 -4
- package/dist/gem-swap/persistence.js +65 -7
- package/dist/gem-swap/practice.js +2 -2
- package/dist/gem-swap/types.d.ts +336 -3
- package/dist/magnetic-blocks/content-types.d.ts +56 -0
- package/dist/magnetic-blocks/content.d.ts +91 -5
- package/dist/magnetic-blocks/content.js +91 -5
- package/dist/magnetic-blocks/engine.d.ts +63 -5
- package/dist/magnetic-blocks/engine.js +63 -5
- package/dist/magnetic-blocks/persistence.d.ts +36 -3
- package/dist/magnetic-blocks/persistence.js +36 -3
- package/dist/magnetic-blocks/physics.d.ts +176 -6
- package/dist/magnetic-blocks/physics.js +176 -6
- package/dist/magnetic-blocks/types.d.ts +185 -1
- package/dist/magnetic-blocks/validation.d.ts +12 -0
- package/dist/magnetic-blocks/validation.js +12 -0
- package/dist/nature/attraction.d.ts +24 -2
- package/dist/nature/attraction.js +24 -2
- package/dist/nature/environment.d.ts +200 -7
- package/dist/nature/environment.js +88 -7
- package/dist/nature/marking.d.ts +13 -1
- package/dist/nature/marking.js +13 -1
- package/dist/nature/rebound.d.ts +30 -2
- package/dist/nature/rebound.js +30 -2
- package/dist/nature/state.d.ts +11 -0
- package/dist/nature/state.js +11 -0
- package/dist/nature/types.d.ts +194 -1
- package/dist/nature/validation.d.ts +12 -0
- package/dist/nature/validation.js +12 -0
- package/dist/stone-collapse/content-types.d.ts +69 -0
- package/dist/stone-collapse/content.d.ts +60 -3
- package/dist/stone-collapse/content.js +60 -3
- package/dist/stone-collapse/engine.d.ts +99 -8
- package/dist/stone-collapse/engine.js +99 -8
- package/dist/stone-collapse/persistence.d.ts +36 -3
- package/dist/stone-collapse/persistence.js +36 -3
- package/dist/stone-collapse/types.d.ts +220 -3
- package/dist/stone-collapse/validation.d.ts +12 -1
- package/dist/stone-collapse/validation.js +12 -1
- package/package.json +34 -26
package/dist/gem-swap/types.d.ts
CHANGED
|
@@ -1,30 +1,174 @@
|
|
|
1
|
-
/** A colour used by a normal gem.
|
|
1
|
+
/** A colour used by a normal gem.
|
|
2
|
+
*
|
|
3
|
+
* @example
|
|
4
|
+
* ```ts
|
|
5
|
+
* import type { GemColour } from "@johnmorrisdotca/houseki/gem-swap";
|
|
6
|
+
*
|
|
7
|
+
* const value: GemColour = "red";
|
|
8
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
2
11
|
export type GemColour = 'red' | 'blue' | 'green' | 'gold' | 'purple' | 'teal';
|
|
12
|
+
/** A Gem Swap beam, bomb or colour-burst special retained at its chosen anchor.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import type { SpecialKind } from "@johnmorrisdotca/houseki/gem-swap";
|
|
17
|
+
*
|
|
18
|
+
* const value: SpecialKind = "row-beam";
|
|
19
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
3
22
|
export type SpecialKind = 'row-beam' | 'column-beam' | 'bomb' | 'colour-burst';
|
|
23
|
+
/** A Gem Swap stored tool or advanced Black Hole selection.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import type { ToolKind } from "@johnmorrisdotca/houseki/gem-swap";
|
|
28
|
+
*
|
|
29
|
+
* const value: ToolKind = "bomb";
|
|
30
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
4
33
|
export type ToolKind = 'bomb' | 'row-clear' | 'colour-clear' | 'black-hole';
|
|
34
|
+
/** A Gem Swap stored tool excluding the separately charged Black Hole.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* import type { OrdinaryToolKind } from "@johnmorrisdotca/houseki/gem-swap";
|
|
39
|
+
*
|
|
40
|
+
* const value: OrdinaryToolKind = "bomb";
|
|
41
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
5
44
|
export type OrdinaryToolKind = Exclude<ToolKind, 'black-hole'>;
|
|
45
|
+
/** The native remaining counts of stored tools.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { createGame } from "@johnmorrisdotca/houseki/gem-swap";
|
|
50
|
+
* import type { ToolInventory } from "@johnmorrisdotca/houseki/gem-swap";
|
|
51
|
+
*
|
|
52
|
+
* const state=createGame({seed:"docs"});
|
|
53
|
+
* const value: ToolInventory = state.inventory;
|
|
54
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
6
57
|
export type ToolInventory = Readonly<Record<OrdinaryToolKind, number>>;
|
|
58
|
+
/** A Gem Swap portal’s cell, remaining capacity, move lifetime and consumed stable ids.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* import type { BlackHolePortal } from "@johnmorrisdotca/houseki/gem-swap";
|
|
63
|
+
*
|
|
64
|
+
* const value: BlackHolePortal = {cell:0,capacityRemaining:2,movesRemaining:2,consumedIds:[]};
|
|
65
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
7
68
|
export interface BlackHolePortal {
|
|
8
69
|
readonly cell: number;
|
|
9
70
|
readonly capacityRemaining: number;
|
|
10
71
|
readonly movesRemaining: number;
|
|
11
72
|
readonly consumedIds: readonly number[];
|
|
12
73
|
}
|
|
13
|
-
/** A gem has a stable identity and stored colour until it is cleared. Missing kind means normal.
|
|
74
|
+
/** A gem has a stable identity and stored colour until it is cleared. Missing kind means normal.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import type { Gem } from "@johnmorrisdotca/houseki/gem-swap";
|
|
79
|
+
*
|
|
80
|
+
* const value: Gem = {id:1,colour:"red"};
|
|
81
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
14
84
|
export interface Gem {
|
|
15
85
|
readonly id: number;
|
|
16
86
|
readonly colour: GemColour;
|
|
17
87
|
readonly kind?: SpecialKind;
|
|
18
88
|
}
|
|
89
|
+
/** The native Gem Swap cell and special kind planned for the end of a clear wave.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* import type { PlannedSpecial } from "@johnmorrisdotca/houseki/gem-swap";
|
|
94
|
+
*
|
|
95
|
+
* const value: PlannedSpecial = {cell:0,kind:"row-beam"};
|
|
96
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
19
99
|
export interface PlannedSpecial {
|
|
20
100
|
readonly cell: number;
|
|
21
101
|
readonly kind: SpecialKind;
|
|
22
102
|
}
|
|
103
|
+
/** A named native board geometry; custom dimensions remain a separate option.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* import type { BoardPreset } from "@johnmorrisdotca/houseki/gem-swap";
|
|
108
|
+
*
|
|
109
|
+
* const value: BoardPreset = "compact";
|
|
110
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
23
113
|
export type BoardPreset = 'compact' | 'standard' | 'wide' | 'tall' | 'extraWide' | 'deep' | 'large';
|
|
114
|
+
/** A native shaped active-cell layout applied to the row-major board.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* import type { BoardShape } from "@johnmorrisdotca/houseki/gem-swap";
|
|
119
|
+
*
|
|
120
|
+
* const value: BoardShape = "heart";
|
|
121
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
24
124
|
export type BoardShape = 'heart' | 'star' | 'hexagon';
|
|
125
|
+
/** The native ready, resolution and ending phases.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* import { createGame } from "@johnmorrisdotca/houseki/gem-swap";
|
|
130
|
+
* import type { GamePhase } from "@johnmorrisdotca/houseki/gem-swap";
|
|
131
|
+
*
|
|
132
|
+
* const state=createGame({seed:"docs"});
|
|
133
|
+
* const value: GamePhase = state.phase;
|
|
134
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
25
137
|
export type GamePhase = 'ready' | 'clear-mark' | 'clear-remove' | 'gravity' | 'refill' | 'finished';
|
|
138
|
+
/** The native free, timed, daily or authored-challenge game mode.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* import type { GameMode } from "@johnmorrisdotca/houseki/gem-swap";
|
|
143
|
+
*
|
|
144
|
+
* const value: GameMode = "relaxed";
|
|
145
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
26
148
|
export type GameMode = 'relaxed' | 'arcade' | 'daily' | 'challenge';
|
|
149
|
+
/** The terminal outcome; null means the run has no terminal outcome yet.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* import { createGame } from "@johnmorrisdotca/houseki/gem-swap";
|
|
154
|
+
* import type { GameOutcome } from "@johnmorrisdotca/houseki/gem-swap";
|
|
155
|
+
*
|
|
156
|
+
* const state=createGame({seed:"docs"});
|
|
157
|
+
* const value: GameOutcome = state.outcome;
|
|
158
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
27
161
|
export type GameOutcome = 'won' | 'lost' | 'finished' | null;
|
|
162
|
+
/** The native authored goal; its discriminant selects the required collection or clearing condition.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* import type { Goal } from "@johnmorrisdotca/houseki/gem-swap";
|
|
167
|
+
*
|
|
168
|
+
* const value: Goal = {kind:"score",target:100};
|
|
169
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
28
172
|
export type Goal = {
|
|
29
173
|
readonly kind: 'score';
|
|
30
174
|
readonly target: number;
|
|
@@ -38,15 +182,45 @@ export type Goal = {
|
|
|
38
182
|
} | {
|
|
39
183
|
readonly kind: 'seals';
|
|
40
184
|
};
|
|
185
|
+
/** A Gem Swap row-major seal cell and its remaining layers.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* import type { Seal } from "@johnmorrisdotca/houseki/gem-swap";
|
|
190
|
+
*
|
|
191
|
+
* const value: Seal = {cell:0,layers:1};
|
|
192
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
41
195
|
export interface Seal {
|
|
42
196
|
readonly cell: number;
|
|
43
197
|
readonly layers: number;
|
|
44
198
|
}
|
|
199
|
+
/** Gem Swap authored goals, optional move budget and seal layout.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* import type { ChallengeRules } from "@johnmorrisdotca/houseki/gem-swap";
|
|
204
|
+
*
|
|
205
|
+
* const value: ChallengeRules = {goals:[{kind:"score",target:100}],moveLimit:5};
|
|
206
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
45
209
|
export interface ChallengeRules {
|
|
46
210
|
readonly goals: readonly Goal[];
|
|
47
211
|
readonly moveLimit?: number;
|
|
48
212
|
readonly seals?: readonly Seal[];
|
|
49
213
|
}
|
|
214
|
+
/** One native Gem Swap action, fixed-tick advance or elapsed-time replay operation.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* import type { ReplayOperation } from "@johnmorrisdotca/houseki/gem-swap";
|
|
219
|
+
*
|
|
220
|
+
* const value: ReplayOperation = {kind:"ticks",count:1};
|
|
221
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
50
224
|
export type ReplayOperation = {
|
|
51
225
|
readonly kind: 'action';
|
|
52
226
|
readonly action: Action;
|
|
@@ -57,6 +231,18 @@ export type ReplayOperation = {
|
|
|
57
231
|
readonly kind: 'time';
|
|
58
232
|
readonly milliseconds: number;
|
|
59
233
|
};
|
|
234
|
+
/** Validated settings fixed at native game creation.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```ts
|
|
238
|
+
* import { createGame } from "@johnmorrisdotca/houseki/gem-swap";
|
|
239
|
+
* import type { Settings } from "@johnmorrisdotca/houseki/gem-swap";
|
|
240
|
+
*
|
|
241
|
+
* const state=createGame({seed:"docs"});
|
|
242
|
+
* const value: Settings = state.settings;
|
|
243
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
60
246
|
export interface Settings {
|
|
61
247
|
readonly width: number;
|
|
62
248
|
readonly height: number;
|
|
@@ -67,6 +253,18 @@ export interface Settings {
|
|
|
67
253
|
readonly shape?: BoardShape;
|
|
68
254
|
readonly mask: readonly boolean[];
|
|
69
255
|
}
|
|
256
|
+
/** The immutable authoritative native game state, including its board, random state and recording.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* import { createGame } from "@johnmorrisdotca/houseki/gem-swap";
|
|
261
|
+
* import type { GameState } from "@johnmorrisdotca/houseki/gem-swap";
|
|
262
|
+
*
|
|
263
|
+
* const state=createGame({seed:"docs"});
|
|
264
|
+
* const value: GameState = state;
|
|
265
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
70
268
|
export interface GameState {
|
|
71
269
|
readonly game: 'gem-swap';
|
|
72
270
|
readonly rules: 'swap-1';
|
|
@@ -112,46 +310,169 @@ export interface GameState {
|
|
|
112
310
|
readonly blackHoleContactPending: boolean;
|
|
113
311
|
readonly pendingBlackHole: boolean;
|
|
114
312
|
}
|
|
115
|
-
/** Swaps two row-major cell addresses.
|
|
313
|
+
/** Swaps two row-major cell addresses.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```ts
|
|
317
|
+
* import type { SwapAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
318
|
+
*
|
|
319
|
+
* const value: SwapAction = {kind:"swap",from:0,to:1};
|
|
320
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
116
323
|
export interface SwapAction {
|
|
117
324
|
readonly kind: 'swap';
|
|
118
325
|
readonly from: number;
|
|
119
326
|
readonly to: number;
|
|
120
327
|
}
|
|
328
|
+
/** Selects a stored Gem Swap tool without committing its target.
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```ts
|
|
332
|
+
* import type { SelectToolAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
333
|
+
*
|
|
334
|
+
* const value: SelectToolAction = {kind:"select-tool",tool:"bomb"};
|
|
335
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
121
338
|
export interface SelectToolAction {
|
|
122
339
|
readonly kind: 'select-tool';
|
|
123
340
|
readonly tool: ToolKind;
|
|
124
341
|
}
|
|
342
|
+
/** Previews a selected Gem Swap tool on one row-major cell.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* import type { TargetToolAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
347
|
+
*
|
|
348
|
+
* const value: TargetToolAction = {kind:"target-tool",cell:0};
|
|
349
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
125
352
|
export interface TargetToolAction {
|
|
126
353
|
readonly kind: 'target-tool';
|
|
127
354
|
readonly cell: number;
|
|
128
355
|
}
|
|
356
|
+
/** Commits the currently selected Gem Swap tool and target.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```ts
|
|
360
|
+
* import type { ConfirmToolAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
361
|
+
*
|
|
362
|
+
* const value: ConfirmToolAction = {kind:"confirm-tool"};
|
|
363
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
129
366
|
export interface ConfirmToolAction {
|
|
130
367
|
readonly kind: 'confirm-tool';
|
|
131
368
|
}
|
|
369
|
+
/** Clears the current Gem Swap tool preview.
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* ```ts
|
|
373
|
+
* import type { CancelToolAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
374
|
+
*
|
|
375
|
+
* const value: CancelToolAction = {kind:"cancel-tool"};
|
|
376
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
132
379
|
export interface CancelToolAction {
|
|
133
380
|
readonly kind: 'cancel-tool';
|
|
134
381
|
}
|
|
382
|
+
/** Requests restoration of the prior Gem Swap move.
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```ts
|
|
386
|
+
* import type { UndoAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
387
|
+
*
|
|
388
|
+
* const value: UndoAction = {kind:"undo"};
|
|
389
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
135
392
|
export interface UndoAction {
|
|
136
393
|
readonly kind: 'undo';
|
|
137
394
|
}
|
|
395
|
+
/** Requests a native Gem Swap hint and marks assisted play.
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```ts
|
|
399
|
+
* import type { HintAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
400
|
+
*
|
|
401
|
+
* const value: HintAction = {kind:"hint"};
|
|
402
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
138
405
|
export interface HintAction {
|
|
139
406
|
readonly kind: 'hint';
|
|
140
407
|
}
|
|
408
|
+
/** Requests a native Gem Swap recovery shuffle.
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* ```ts
|
|
412
|
+
* import type { ReshuffleAction } from "@johnmorrisdotca/houseki/gem-swap";
|
|
413
|
+
*
|
|
414
|
+
* const value: ReshuffleAction = {kind:"reshuffle"};
|
|
415
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
141
418
|
export interface ReshuffleAction {
|
|
142
419
|
readonly kind: 'reshuffle';
|
|
143
420
|
}
|
|
421
|
+
/** A native player action accepted or rejected according to the current phase and rules.
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* ```ts
|
|
425
|
+
* import type { Action } from "@johnmorrisdotca/houseki/gem-swap";
|
|
426
|
+
*
|
|
427
|
+
* const action: Action={kind:"hint"};
|
|
428
|
+
* const value: Action = action;
|
|
429
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
144
432
|
export type Action = SwapAction | SelectToolAction | TargetToolAction | ConfirmToolAction | CancelToolAction | UndoAction | HintAction | ReshuffleAction;
|
|
433
|
+
/** An event emitted by one native transition; type selects the event’s additional fields.
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```ts
|
|
437
|
+
* import type { GameEvent } from "@johnmorrisdotca/houseki/gem-swap";
|
|
438
|
+
*
|
|
439
|
+
* const value: GameEvent = {type:"host-example"};
|
|
440
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
441
|
+
* ```
|
|
442
|
+
*/
|
|
145
443
|
export interface GameEvent {
|
|
146
444
|
readonly type: string;
|
|
147
445
|
readonly [key: string]: unknown;
|
|
148
446
|
}
|
|
447
|
+
/** The resulting native state, emitted events and acceptance decision; rejected actions preserve the input.
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* ```ts
|
|
451
|
+
* import { applyAction, createGame } from "@johnmorrisdotca/houseki/gem-swap";
|
|
452
|
+
* import type { Action, Transition } from "@johnmorrisdotca/houseki/gem-swap";
|
|
453
|
+
*
|
|
454
|
+
* const state=createGame({seed:"docs"});
|
|
455
|
+
* const action: Action={kind:"hint"};
|
|
456
|
+
* const value: Transition = applyAction(state,action);
|
|
457
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
149
460
|
export interface Transition {
|
|
150
461
|
readonly state: GameState;
|
|
151
462
|
readonly events: readonly GameEvent[];
|
|
152
463
|
readonly accepted: boolean;
|
|
153
464
|
readonly reason?: string;
|
|
154
465
|
}
|
|
466
|
+
/** Creation settings for this native engine; dimensions, mode, seed and optional mechanics are validated together.
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* ```ts
|
|
470
|
+
* import type { CreateOptions } from "@johnmorrisdotca/houseki/gem-swap";
|
|
471
|
+
*
|
|
472
|
+
* const value: CreateOptions = {seed:"docs"};
|
|
473
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
474
|
+
* ```
|
|
475
|
+
*/
|
|
155
476
|
export interface CreateOptions {
|
|
156
477
|
readonly preset?: BoardPreset;
|
|
157
478
|
readonly width?: number;
|
|
@@ -169,6 +490,18 @@ export interface CreateOptions {
|
|
|
169
490
|
/** Challenge-only finite goals and optional legal-swap budget. */
|
|
170
491
|
readonly challenge?: ChallengeRules;
|
|
171
492
|
}
|
|
493
|
+
/** A compact native status derived from the authoritative state for a host’s labels.
|
|
494
|
+
*
|
|
495
|
+
* @example
|
|
496
|
+
* ```ts
|
|
497
|
+
* import { createGame, statusOf } from "@johnmorrisdotca/houseki/gem-swap";
|
|
498
|
+
* import type { GameStatus } from "@johnmorrisdotca/houseki/gem-swap";
|
|
499
|
+
*
|
|
500
|
+
* const state=createGame({seed:"docs"});
|
|
501
|
+
* const value: GameStatus = statusOf(state);
|
|
502
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
503
|
+
* ```
|
|
504
|
+
*/
|
|
172
505
|
export interface GameStatus {
|
|
173
506
|
readonly phase: GamePhase;
|
|
174
507
|
readonly score: number;
|
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
import type { Action, Colour, CreateOptions, Floor, GameState, Gem } from './types.js';
|
|
2
|
+
/** One authored text in English and Japanese.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import type { LocalizedText } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
7
|
+
*
|
|
8
|
+
* const value: LocalizedText = {en:"A small puzzle",ja:"小さいパズル"};
|
|
9
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
2
12
|
export interface LocalizedText {
|
|
3
13
|
readonly en: string;
|
|
4
14
|
readonly ja: string;
|
|
5
15
|
}
|
|
16
|
+
/** The bounded engine measurements used to grade this campaign; they do not claim human difficulty.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { levelManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
21
|
+
* import type { MagneticDifficultyMetrics } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
22
|
+
*
|
|
23
|
+
* const level=levelManifest[0];
|
|
24
|
+
* const value: MagneticDifficultyMetrics = level.metrics;
|
|
25
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
6
28
|
export interface MagneticDifficultyMetrics {
|
|
7
29
|
readonly legalPlacementChoices: number;
|
|
8
30
|
readonly setupPlacementChoices: number;
|
|
@@ -39,6 +61,18 @@ export interface MagneticDifficultyMetrics {
|
|
|
39
61
|
};
|
|
40
62
|
}
|
|
41
63
|
export type MagneticDifficultyBand = 'entry' | 'easy' | 'intermediate' | 'hard' | 'expert';
|
|
64
|
+
/** One authored native challenge with its stable id, setup, winning witness, measurements and review status.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { levelManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
69
|
+
* import type { MagneticCampaignLevel } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
70
|
+
*
|
|
71
|
+
* const level=levelManifest[0];
|
|
72
|
+
* const value: MagneticCampaignLevel = level;
|
|
73
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
42
76
|
export interface MagneticCampaignLevel {
|
|
43
77
|
readonly id: string;
|
|
44
78
|
readonly number: number;
|
|
@@ -67,6 +101,17 @@ export interface MagneticCampaignLevel {
|
|
|
67
101
|
readonly disabledImpactResult: 'won';
|
|
68
102
|
};
|
|
69
103
|
}
|
|
104
|
+
/** The ordered native campaign, its generation/grading revisions, checksum and measured levels.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* import type { MagneticCampaignManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
109
|
+
* import { campaignManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
110
|
+
*
|
|
111
|
+
* const value: MagneticCampaignManifest = campaignManifest;
|
|
112
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
70
115
|
export interface MagneticCampaignManifest {
|
|
71
116
|
readonly count: number;
|
|
72
117
|
readonly currentCount?: number;
|
|
@@ -86,6 +131,17 @@ export interface MagneticCampaignManifest {
|
|
|
86
131
|
readonly last: number;
|
|
87
132
|
}[];
|
|
88
133
|
}
|
|
134
|
+
/** One bilingual native lesson with its authored setup, teaching steps and winning witness.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* import type { MagneticLesson } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
139
|
+
* import { lessonManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
140
|
+
*
|
|
141
|
+
* const value: MagneticLesson = lessonManifest[0];
|
|
142
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
89
145
|
export interface MagneticLesson {
|
|
90
146
|
readonly id: string;
|
|
91
147
|
readonly title: LocalizedText;
|
|
@@ -1,16 +1,102 @@
|
|
|
1
1
|
import type { MagneticCampaignLevel, MagneticCampaignManifest, MagneticLesson } from './content-types.js';
|
|
2
2
|
import type { GameState } from './types.js';
|
|
3
|
+
/** The frozen native campaign manifest with its ordering, revisions, checksum and measured levels.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { campaignManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
8
|
+
*
|
|
9
|
+
* console.log(campaignManifest.count);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
3
12
|
export declare const campaignManifest: MagneticCampaignManifest;
|
|
13
|
+
/** The frozen ordered native levels; array indices start at zero and display numbers start at one.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { levelManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
18
|
+
*
|
|
19
|
+
* console.log(levelManifest.length);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
4
22
|
export declare const levelManifest: readonly MagneticCampaignLevel[];
|
|
5
|
-
/** Alias kept alongside other Houseki campaign lesson APIs.
|
|
23
|
+
/** Alias kept alongside other Houseki campaign lesson APIs.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
28
|
+
*
|
|
29
|
+
* console.log(tutorialManifest.length);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
6
32
|
export declare const tutorialManifest: readonly MagneticLesson[];
|
|
33
|
+
/** The frozen native bilingual lessons and their authored teaching steps.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { lessonManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
38
|
+
*
|
|
39
|
+
* console.log(lessonManifest.length);
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
7
42
|
export declare const lessonManifest: readonly MagneticLesson[];
|
|
8
|
-
/** Finds a Magnetic Blocks campaign level by stable ID or one-based display number.
|
|
43
|
+
/** Finds a Magnetic Blocks campaign level by stable ID or one-based display number.
|
|
44
|
+
*
|
|
45
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
46
|
+
* @returns Finds a Magnetic Blocks campaign level by stable ID or one-based display number. Returns undefined when the id or display number is absent.
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { getLevel } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
50
|
+
*
|
|
51
|
+
* console.log(getLevel(1)?.id);
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
9
54
|
export declare function getLevel(id: string | number): MagneticCampaignLevel | undefined;
|
|
10
|
-
/** Creates a fresh game with the authored rules, board, queue, and finite move budget.
|
|
55
|
+
/** Creates a fresh game with the authored rules, board, queue, and finite move budget.
|
|
56
|
+
*
|
|
57
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
58
|
+
* @returns Creates a fresh game with the authored rules, board, queue, and finite move budget.
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { createLevel } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
62
|
+
*
|
|
63
|
+
* console.log(createLevel(1).phase);
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
11
66
|
export declare function createLevel(id: string | number): GameState;
|
|
12
|
-
/** Finds one of the three bilingual rules lessons by stable ID.
|
|
67
|
+
/** Finds one of the three bilingual rules lessons by stable ID.
|
|
68
|
+
*
|
|
69
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
70
|
+
* @returns Finds one of the three bilingual rules lessons by stable ID. Returns undefined when the id or display number is absent.
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { getLesson, lessonManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
74
|
+
*
|
|
75
|
+
* console.log(getLesson(lessonManifest[0].id)?.id);
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
13
78
|
export declare function getLesson(id: string): MagneticLesson | undefined;
|
|
79
|
+
/** Find a magnetic-block lesson by stable id; returns undefined when no lesson has that id.
|
|
80
|
+
*
|
|
81
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
82
|
+
* @returns Find a magnetic-block lesson by stable id; returns undefined when no lesson has that id. Returns undefined when the id or display number is absent.
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* import { getTutorial, lessonManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
86
|
+
*
|
|
87
|
+
* console.log(getTutorial(lessonManifest[0].id)?.id);
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
14
90
|
export declare const getTutorial: typeof getLesson;
|
|
15
|
-
/** Creates a fresh lesson game with its authored setup and queue.
|
|
91
|
+
/** Creates a fresh lesson game with its authored setup and queue.
|
|
92
|
+
*
|
|
93
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
94
|
+
* @returns Creates a fresh lesson game with its authored setup and queue.
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* import { createLesson, lessonManifest } from "@johnmorrisdotca/houseki/magnetic-blocks";
|
|
98
|
+
*
|
|
99
|
+
* console.log(createLesson(lessonManifest[0].id).phase);
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
16
102
|
export declare function createLesson(id: string): GameState;
|