@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
|
@@ -1,22 +1,78 @@
|
|
|
1
1
|
import type { NaturePieceCell, PowerDropPreview } from '../nature/types.js';
|
|
2
|
-
/** A gem colour used by Colour Chains.
|
|
2
|
+
/** A gem colour used by Colour Chains.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import type { Colour } from "@johnmorrisdotca/houseki/colour-chains";
|
|
7
|
+
*
|
|
8
|
+
* const value: Colour = "red";
|
|
9
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
3
12
|
export type Colour = 'red' | 'blue' | 'green' | 'gold' | 'purple' | 'teal';
|
|
4
|
-
/** A settled or active stone with a stable run-local identity.
|
|
13
|
+
/** A settled or active stone with a stable run-local identity.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import type { Gem } from "@johnmorrisdotca/houseki/colour-chains";
|
|
18
|
+
*
|
|
19
|
+
* const value: Gem = {id:1,colour:"red"};
|
|
20
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
5
23
|
export interface Gem {
|
|
6
24
|
readonly id: number;
|
|
7
25
|
readonly colour: Colour;
|
|
8
26
|
readonly magnetic?: true;
|
|
9
27
|
}
|
|
10
|
-
/** Authored challenge layouts can include explicit Shizen-marked stones.
|
|
28
|
+
/** Authored challenge layouts can include explicit Shizen-marked stones.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import type { ChallengeGem } from "@johnmorrisdotca/houseki/colour-chains";
|
|
33
|
+
*
|
|
34
|
+
* const value: ChallengeGem = {id:1,colour:"red",magnetic:true};
|
|
35
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
11
38
|
export type ChallengeGem = Gem;
|
|
12
|
-
/** The pivot-to-satellite direction, in clockwise order.
|
|
39
|
+
/** The pivot-to-satellite direction, in clockwise order.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import type { Orientation } from "@johnmorrisdotca/houseki/colour-chains";
|
|
44
|
+
*
|
|
45
|
+
* const value: Orientation = "up";
|
|
46
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
13
49
|
export type Orientation = 'up' | 'right' | 'down' | 'left';
|
|
14
|
-
/** A visible or hidden board coordinate.
|
|
50
|
+
/** A visible or hidden board coordinate.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import type { Cell } from "@johnmorrisdotca/houseki/colour-chains";
|
|
55
|
+
*
|
|
56
|
+
* const value: Cell = {x:0,y:0};
|
|
57
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
15
60
|
export interface Cell {
|
|
16
61
|
readonly x: number;
|
|
17
62
|
readonly y: number;
|
|
18
63
|
}
|
|
19
|
-
/** The active rigid pair. The pivot always retains its own gem identity.
|
|
64
|
+
/** The active rigid pair. The pivot always retains its own gem identity.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { createGame } from "@johnmorrisdotca/houseki/colour-chains";
|
|
69
|
+
* import type { Pair } from "@johnmorrisdotca/houseki/colour-chains";
|
|
70
|
+
*
|
|
71
|
+
* const state=createGame({seed:"docs"});
|
|
72
|
+
* const value: Pair = state.active!;
|
|
73
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
20
76
|
export interface Pair {
|
|
21
77
|
readonly pivot: Cell;
|
|
22
78
|
readonly orientation: Orientation;
|
|
@@ -27,10 +83,49 @@ export interface Pair {
|
|
|
27
83
|
readonly resetCount: number;
|
|
28
84
|
readonly groundedStarted: boolean;
|
|
29
85
|
}
|
|
30
|
-
/** Supported well presets.
|
|
86
|
+
/** Supported well presets.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* import type { Preset } from "@johnmorrisdotca/houseki/colour-chains";
|
|
91
|
+
*
|
|
92
|
+
* const value: Preset = "standard";
|
|
93
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
31
96
|
export type Preset = 'narrow' | 'standard' | 'wide' | 'tall' | 'extraWide' | 'deep' | 'large';
|
|
97
|
+
/** The native game mode; authored challenges have fixed setup and queue rules.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import type { Mode } from "@johnmorrisdotca/houseki/colour-chains";
|
|
102
|
+
*
|
|
103
|
+
* const value: Mode = "relaxed";
|
|
104
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
32
107
|
export type Mode = 'relaxed' | 'arcade' | 'daily' | 'challenge';
|
|
108
|
+
/** The native frequent or rare weather schedule for Colour Chains.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* import type { WeatherSchedule } from "@johnmorrisdotca/houseki/colour-chains";
|
|
113
|
+
*
|
|
114
|
+
* const value: WeatherSchedule = "frequent";
|
|
115
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
33
118
|
export type WeatherSchedule = 'frequent' | 'rare';
|
|
119
|
+
/** Creation settings for this native engine; dimensions, mode, seed and optional mechanics are validated together.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* import type { CreateOptions } from "@johnmorrisdotca/houseki/colour-chains";
|
|
124
|
+
*
|
|
125
|
+
* const value: CreateOptions = {seed:"docs"};
|
|
126
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
34
129
|
export interface CreateOptions {
|
|
35
130
|
readonly mode?: Exclude<Mode, 'challenge'>;
|
|
36
131
|
readonly seed?: string;
|
|
@@ -43,7 +138,18 @@ export interface CreateOptions {
|
|
|
43
138
|
readonly nature?: boolean;
|
|
44
139
|
readonly weather?: WeatherSchedule;
|
|
45
140
|
}
|
|
46
|
-
/** Run settings fixed at game creation.
|
|
141
|
+
/** Run settings fixed at game creation.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* import { createGame } from "@johnmorrisdotca/houseki/colour-chains";
|
|
146
|
+
* import type { Settings } from "@johnmorrisdotca/houseki/colour-chains";
|
|
147
|
+
*
|
|
148
|
+
* const state=createGame({seed:"docs"});
|
|
149
|
+
* const value: Settings = state.settings;
|
|
150
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
47
153
|
export interface Settings {
|
|
48
154
|
readonly mode: Mode;
|
|
49
155
|
readonly width: number;
|
|
@@ -61,7 +167,16 @@ export interface Settings {
|
|
|
61
167
|
readonly magneticQueue?: readonly (readonly [boolean, boolean])[];
|
|
62
168
|
readonly witness?: readonly WitnessStep[];
|
|
63
169
|
}
|
|
64
|
-
/** Challenge objective; target IDs refer to the visible starting board.
|
|
170
|
+
/** Challenge objective; target IDs refer to the visible starting board.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* import type { ChallengeGoal } from "@johnmorrisdotca/houseki/colour-chains";
|
|
175
|
+
*
|
|
176
|
+
* const value: ChallengeGoal = {kind:"empty-board"};
|
|
177
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
65
180
|
export type ChallengeGoal = {
|
|
66
181
|
readonly kind: 'clear-targets';
|
|
67
182
|
readonly targetIds: readonly number[];
|
|
@@ -71,10 +186,32 @@ export type ChallengeGoal = {
|
|
|
71
186
|
} | {
|
|
72
187
|
readonly kind: 'empty-board';
|
|
73
188
|
};
|
|
189
|
+
/** One witnessed Colour Chains pair placement using pivot column and orientation.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* import type { WitnessStep } from "@johnmorrisdotca/houseki/colour-chains";
|
|
194
|
+
*
|
|
195
|
+
* const value: WitnessStep = {pivotX:0,orientation:"up"};
|
|
196
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
74
199
|
export interface WitnessStep {
|
|
75
200
|
readonly pivotX: number;
|
|
76
201
|
readonly orientation: Orientation;
|
|
77
202
|
}
|
|
203
|
+
/** Authored challenge inputs including the starting board, finite goal and supplied witness.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* import { createGame } from "@johnmorrisdotca/houseki/colour-chains";
|
|
208
|
+
* import type { ChallengeOptions } from "@johnmorrisdotca/houseki/colour-chains";
|
|
209
|
+
*
|
|
210
|
+
* const state=createGame({seed:"docs"});
|
|
211
|
+
* const value: ChallengeOptions = {id:"docs",board:state.board,queue:[["red","green"]],goal:{kind:"empty-board"}};
|
|
212
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
78
215
|
export interface ChallengeOptions {
|
|
79
216
|
readonly id: string;
|
|
80
217
|
readonly width?: number;
|
|
@@ -89,15 +226,46 @@ export interface ChallengeOptions {
|
|
|
89
226
|
readonly goal: ChallengeGoal;
|
|
90
227
|
readonly witness?: readonly WitnessStep[];
|
|
91
228
|
}
|
|
92
|
-
/** Observable game phases.
|
|
229
|
+
/** Observable game phases.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* import { createGame } from "@johnmorrisdotca/houseki/colour-chains";
|
|
234
|
+
* import type { Phase } from "@johnmorrisdotca/houseki/colour-chains";
|
|
235
|
+
*
|
|
236
|
+
* const state=createGame({seed:"docs"});
|
|
237
|
+
* const value: Phase = state.phase;
|
|
238
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
93
241
|
export type Phase = 'falling' | 'clear-mark' | 'clear-remove' | 'gravity' | 'paused' | 'won' | 'lost' | 'finished';
|
|
94
|
-
/** A scored simultaneous match wave.
|
|
242
|
+
/** A scored simultaneous match wave.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* import type { Wave } from "@johnmorrisdotca/houseki/colour-chains";
|
|
247
|
+
*
|
|
248
|
+
* const value: Wave = {chain:1,cells:[],points:0,ids:[]};
|
|
249
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
95
252
|
export interface Wave {
|
|
96
253
|
readonly chain: number;
|
|
97
254
|
readonly cells: readonly number[];
|
|
98
255
|
readonly ids: readonly number[];
|
|
99
256
|
readonly points: number;
|
|
100
257
|
}
|
|
258
|
+
/** One native Colour Chains player command, including pause and hint commands.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* import type { Action, PlayAction } from "@johnmorrisdotca/houseki/colour-chains";
|
|
263
|
+
*
|
|
264
|
+
* const action: Action={kind:"left"};
|
|
265
|
+
* const value: PlayAction = action;
|
|
266
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
101
269
|
export type PlayAction = {
|
|
102
270
|
readonly kind: 'left';
|
|
103
271
|
} | {
|
|
@@ -119,8 +287,39 @@ export type PlayAction = {
|
|
|
119
287
|
} | {
|
|
120
288
|
readonly kind: 'hint';
|
|
121
289
|
};
|
|
290
|
+
/** A native player action accepted or rejected according to the current phase and rules.
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* ```ts
|
|
294
|
+
* import type { Action } from "@johnmorrisdotca/houseki/colour-chains";
|
|
295
|
+
*
|
|
296
|
+
* const action: Action={kind:"left"};
|
|
297
|
+
* const value: Action = action;
|
|
298
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
122
301
|
export type Action = PlayAction;
|
|
302
|
+
/** A lateral or soft-drop control which the input scheduler can repeat.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```ts
|
|
306
|
+
* import type { HeldControl } from "@johnmorrisdotca/houseki/colour-chains";
|
|
307
|
+
*
|
|
308
|
+
* const value: HeldControl = "left";
|
|
309
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
123
312
|
export type HeldControl = 'left' | 'right' | 'soft-drop';
|
|
313
|
+
/** A native held-control change or one-shot edge command for Colour Chains.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```ts
|
|
317
|
+
* import type { InputCommand } from "@johnmorrisdotca/houseki/colour-chains";
|
|
318
|
+
*
|
|
319
|
+
* const value: InputCommand = {kind:"hold",control:"left",pressed:true};
|
|
320
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
124
323
|
export type InputCommand = {
|
|
125
324
|
readonly kind: 'hold';
|
|
126
325
|
readonly control: HeldControl;
|
|
@@ -131,12 +330,34 @@ export type InputCommand = {
|
|
|
131
330
|
kind: 'rotate-clockwise' | 'rotate-anticlockwise' | 'hard-drop' | 'place' | 'pause' | 'resume';
|
|
132
331
|
}>;
|
|
133
332
|
};
|
|
333
|
+
/** A native action recording with the logical position needed for deterministic replay.
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```ts
|
|
337
|
+
* import type { Action, RecordedAction } from "@johnmorrisdotca/houseki/colour-chains";
|
|
338
|
+
*
|
|
339
|
+
* const action: Action={kind:"left"};
|
|
340
|
+
* const value: RecordedAction = {tick:0,ordinal:0,action};
|
|
341
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
134
344
|
export interface RecordedAction {
|
|
135
345
|
readonly tick: number;
|
|
136
346
|
readonly ordinal: number;
|
|
137
347
|
readonly action: PlayAction;
|
|
138
348
|
}
|
|
139
|
-
/** An immutable Colour Chains rules state. Board rows include the three hidden rows above the well.
|
|
349
|
+
/** An immutable Colour Chains rules state. Board rows include the three hidden rows above the well.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```ts
|
|
353
|
+
* import { createGame } from "@johnmorrisdotca/houseki/colour-chains";
|
|
354
|
+
* import type { GameState } from "@johnmorrisdotca/houseki/colour-chains";
|
|
355
|
+
*
|
|
356
|
+
* const state=createGame({seed:"docs"});
|
|
357
|
+
* const value: GameState = state;
|
|
358
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
140
361
|
export interface GameState {
|
|
141
362
|
readonly game: 'colour-chains';
|
|
142
363
|
readonly rules: 'chains-1';
|
|
@@ -169,19 +390,51 @@ export interface GameState {
|
|
|
169
390
|
readonly recording: readonly RecordedAction[];
|
|
170
391
|
readonly reason?: string;
|
|
171
392
|
}
|
|
172
|
-
/** A deterministic transition; rejected actions retain the exact input state.
|
|
393
|
+
/** A deterministic transition; rejected actions retain the exact input state.
|
|
394
|
+
*
|
|
395
|
+
* @example
|
|
396
|
+
* ```ts
|
|
397
|
+
* import { applyAction, createGame } from "@johnmorrisdotca/houseki/colour-chains";
|
|
398
|
+
* import type { Action, Transition } from "@johnmorrisdotca/houseki/colour-chains";
|
|
399
|
+
*
|
|
400
|
+
* const state=createGame({seed:"docs"});
|
|
401
|
+
* const action: Action={kind:"left"};
|
|
402
|
+
* const value: Transition = applyAction(state,action);
|
|
403
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
404
|
+
* ```
|
|
405
|
+
*/
|
|
173
406
|
export interface Transition {
|
|
174
407
|
readonly state: GameState;
|
|
175
408
|
readonly events: readonly GameEvent[];
|
|
176
409
|
readonly accepted: boolean;
|
|
177
410
|
readonly reason?: string;
|
|
178
411
|
}
|
|
179
|
-
/** A domain event emitted by one transition.
|
|
412
|
+
/** A domain event emitted by one transition.
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```ts
|
|
416
|
+
* import type { GameEvent } from "@johnmorrisdotca/houseki/colour-chains";
|
|
417
|
+
*
|
|
418
|
+
* const value: GameEvent = {type:"host-example"};
|
|
419
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
180
422
|
export interface GameEvent {
|
|
181
423
|
readonly type: string;
|
|
182
424
|
readonly [key: string]: unknown;
|
|
183
425
|
}
|
|
184
|
-
/** Compact player status derived from the current state.
|
|
426
|
+
/** Compact player status derived from the current state.
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* ```ts
|
|
430
|
+
* import { createGame, statusOf } from "@johnmorrisdotca/houseki/colour-chains";
|
|
431
|
+
* import type { GameStatus } from "@johnmorrisdotca/houseki/colour-chains";
|
|
432
|
+
*
|
|
433
|
+
* const state=createGame({seed:"docs"});
|
|
434
|
+
* const value: GameStatus = statusOf(state);
|
|
435
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
185
438
|
export interface GameStatus {
|
|
186
439
|
readonly mode: Mode;
|
|
187
440
|
readonly phase: Phase;
|
|
@@ -192,9 +445,30 @@ export interface GameStatus {
|
|
|
192
445
|
readonly assisted: boolean;
|
|
193
446
|
readonly reason?: string;
|
|
194
447
|
}
|
|
195
|
-
/** Destination cells for the two independently settled ghost stones.
|
|
448
|
+
/** Destination cells for the two independently settled ghost stones.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```ts
|
|
452
|
+
* import { createGame, landingCells } from "@johnmorrisdotca/houseki/colour-chains";
|
|
453
|
+
* import type { Landing } from "@johnmorrisdotca/houseki/colour-chains";
|
|
454
|
+
*
|
|
455
|
+
* const state=createGame({seed:"docs"});
|
|
456
|
+
* const value: Landing = landingCells(state)!;
|
|
457
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
196
460
|
export type Landing = readonly [Cell, Cell];
|
|
197
|
-
/** The Shizen hard-drop preview: the one-step rebound and where the pair locks (`finalCells`), and where each stone of the pair comes to rest once the committed drop's gravity has run (`settledCells`).
|
|
461
|
+
/** The Shizen hard-drop preview: the one-step rebound and where the pair locks (`finalCells`), and where each stone of the pair comes to rest once the committed drop's gravity has run (`settledCells`).
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```ts
|
|
465
|
+
* import type { ChainsPowerDropPreview } from "@johnmorrisdotca/houseki/colour-chains";
|
|
466
|
+
* import { createGame, powerDropPreview } from "@johnmorrisdotca/houseki/colour-chains";
|
|
467
|
+
*
|
|
468
|
+
* const value: ChainsPowerDropPreview = powerDropPreview(createGame({seed:"docs",nature:true}))!;
|
|
469
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
198
472
|
export interface ChainsPowerDropPreview extends PowerDropPreview {
|
|
199
473
|
readonly settledCells: readonly NaturePieceCell[];
|
|
200
474
|
}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import type { ChallengeGoal, Colour, CreateOptions, Mode, Preset, Settings } from './types.js';
|
|
2
2
|
declare const PRESETS: Readonly<Record<Preset, readonly [number, number]>>;
|
|
3
3
|
declare const COLOURS: readonly Colour[];
|
|
4
|
-
/** Typed setup and authored challenge error.
|
|
4
|
+
/** Typed setup and authored challenge error.
|
|
5
|
+
*
|
|
6
|
+
* @param code - The native stable error code used by callers to distinguish setup or replay failures.
|
|
7
|
+
* @param message - The human-readable diagnostic accompanying the native code.
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { StoneChainsOptionsError } from "@johnmorrisdotca/houseki/colour-chains";
|
|
11
|
+
*
|
|
12
|
+
* const error=new StoneChainsOptionsError("docs-example","Invalid example setup");
|
|
13
|
+
* console.log(error.name,error.code,error.message);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
5
16
|
export declare class StoneChainsOptionsError extends RangeError {
|
|
6
17
|
readonly code: string;
|
|
7
18
|
constructor(code: string, message: string);
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
const PRESETS = { narrow: [5, 12], standard: [6, 12], wide: [8, 12], tall: [6, 16], extraWide: [12, 12], deep: [8, 32], large: [12, 32] };
|
|
2
2
|
const COLOURS = ['red', 'blue', 'green', 'gold', 'purple', 'teal'];
|
|
3
|
-
/** Typed setup and authored challenge error.
|
|
3
|
+
/** Typed setup and authored challenge error.
|
|
4
|
+
*
|
|
5
|
+
* @param code - The native stable error code used by callers to distinguish setup or replay failures.
|
|
6
|
+
* @param message - The human-readable diagnostic accompanying the native code.
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { StoneChainsOptionsError } from "@johnmorrisdotca/houseki/colour-chains";
|
|
10
|
+
*
|
|
11
|
+
* const error=new StoneChainsOptionsError("docs-example","Invalid example setup");
|
|
12
|
+
* console.log(error.name,error.code,error.message);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
4
15
|
export class StoneChainsOptionsError extends RangeError {
|
|
5
16
|
code;
|
|
6
17
|
constructor(code, message) { super(message); this.name = 'StoneChainsOptionsError'; this.code = code; }
|
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
import type { ChallengeGoal, ChallengeHint, Colour, Gem, Triplet } from './types.js';
|
|
2
|
+
/** One authored text in English and Japanese.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import type { LocalizedText } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
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/falling-triplets";
|
|
21
|
+
* import type { DifficultyMetrics } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
22
|
+
*
|
|
23
|
+
* const level=levelManifest[0];
|
|
24
|
+
* const value: DifficultyMetrics = level.rawMetrics;
|
|
25
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
6
28
|
export interface DifficultyMetrics {
|
|
7
29
|
readonly seededGoalSuccesses: number;
|
|
8
30
|
readonly seededGoalSamples: number;
|
|
@@ -17,6 +39,18 @@ export interface DifficultyMetrics {
|
|
|
17
39
|
readonly witnessPlanningLength: number;
|
|
18
40
|
readonly payoffDirections: number;
|
|
19
41
|
}
|
|
42
|
+
/** One authored native challenge with its stable id, setup, winning witness, measurements and review status.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { levelManifest } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
47
|
+
* import type { CampaignLevel } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
48
|
+
*
|
|
49
|
+
* const level=levelManifest[0];
|
|
50
|
+
* const value: CampaignLevel = level;
|
|
51
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
20
54
|
export interface CampaignLevel {
|
|
21
55
|
readonly id: string;
|
|
22
56
|
readonly seed: string;
|
|
@@ -39,6 +73,17 @@ export interface CampaignLevel {
|
|
|
39
73
|
readonly proofStatus: 'engine-witness-verified';
|
|
40
74
|
readonly reviewStatus: 'human-review-pending' | 'human-reviewed';
|
|
41
75
|
}
|
|
76
|
+
/** The ordered native campaign, its generation/grading revisions, checksum and measured levels.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* import type { CampaignManifest } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
81
|
+
* import { campaignManifest } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
82
|
+
*
|
|
83
|
+
* const value: CampaignManifest = campaignManifest;
|
|
84
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
42
87
|
export interface CampaignManifest {
|
|
43
88
|
readonly count: number;
|
|
44
89
|
readonly candidatePoolCount: number;
|
|
@@ -52,10 +97,34 @@ export interface CampaignManifest {
|
|
|
52
97
|
readonly checksum: string;
|
|
53
98
|
readonly levels: readonly CampaignLevel[];
|
|
54
99
|
}
|
|
100
|
+
/** One bilingual native lesson instruction and the corresponding action or tick step.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
105
|
+
* import type { TutorialStep } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
106
|
+
*
|
|
107
|
+
* const lesson=tutorialManifest[0];
|
|
108
|
+
* const value: TutorialStep = lesson.steps[0];
|
|
109
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
55
112
|
export interface TutorialStep {
|
|
56
113
|
readonly instruction: LocalizedText;
|
|
57
114
|
readonly action: string;
|
|
58
115
|
}
|
|
116
|
+
/** One bilingual native lesson with its authored setup, teaching steps and winning witness.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
121
|
+
* import type { TutorialDefinition } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
122
|
+
*
|
|
123
|
+
* const lesson=tutorialManifest[0];
|
|
124
|
+
* const value: TutorialDefinition = lesson;
|
|
125
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
59
128
|
export interface TutorialDefinition {
|
|
60
129
|
readonly id: string;
|
|
61
130
|
readonly title: LocalizedText;
|
|
@@ -1,11 +1,68 @@
|
|
|
1
1
|
import type { CampaignLevel, CampaignManifest, TutorialDefinition } 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/falling-triplets";
|
|
8
|
+
*
|
|
9
|
+
* console.log(campaignManifest.count);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
3
12
|
export declare const campaignManifest: CampaignManifest;
|
|
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/falling-triplets";
|
|
18
|
+
*
|
|
19
|
+
* console.log(levelManifest.length);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
4
22
|
export declare const levelManifest: readonly CampaignLevel[];
|
|
23
|
+
/** The frozen native bilingual lessons and their authored teaching steps.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
28
|
+
*
|
|
29
|
+
* console.log(tutorialManifest.length);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
5
32
|
export declare const tutorialManifest: readonly TutorialDefinition[];
|
|
6
|
-
/** Find a level by stable content ID or its current one-based display number.
|
|
33
|
+
/** Find a level by stable content ID or its current one-based display number.
|
|
34
|
+
*
|
|
35
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
36
|
+
* @returns Find a level by stable content ID or its current one-based display number. Returns undefined when the id or display number is absent.
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { getLevel } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
40
|
+
*
|
|
41
|
+
* console.log(getLevel(1)?.id);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
7
44
|
export declare function getLevel(id: string | number): CampaignLevel | undefined;
|
|
8
|
-
/** Construct a fresh validated challenge state for a stable level ID or display number.
|
|
45
|
+
/** Construct a fresh validated challenge state for a stable level ID or display number.
|
|
46
|
+
*
|
|
47
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
48
|
+
* @returns Construct a fresh validated challenge state for a stable level ID or display number.
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { createLevel } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
52
|
+
*
|
|
53
|
+
* console.log(createLevel(1).phase);
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
9
56
|
export declare function createLevel(id: string | number): GameState;
|
|
10
|
-
/** Find a lesson by its persistent ID.
|
|
57
|
+
/** Find a lesson by its persistent ID.
|
|
58
|
+
*
|
|
59
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
60
|
+
* @returns Find a lesson by its persistent ID. Returns undefined when the id or display number is absent.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { getTutorial, tutorialManifest } from "@johnmorrisdotca/houseki/falling-triplets";
|
|
64
|
+
*
|
|
65
|
+
* console.log(getTutorial(tutorialManifest[0].id)?.id);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
11
68
|
export declare function getTutorial(id: string): TutorialDefinition | undefined;
|