@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/nature/types.d.ts
CHANGED
|
@@ -1,7 +1,46 @@
|
|
|
1
|
+
/** The native left or right direction used for rebound decisions.
|
|
2
|
+
*
|
|
3
|
+
* @example
|
|
4
|
+
* ```ts
|
|
5
|
+
* import type { HorizontalDirection } from "@johnmorrisdotca/houseki/nature";
|
|
6
|
+
*
|
|
7
|
+
* const value: HorizontalDirection = "left";
|
|
8
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
1
11
|
export type HorizontalDirection = 'left' | 'right';
|
|
12
|
+
/** Whether rebound prefers recent input/alternation or the seeded random source.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import type { ReboundDirectionMode } from "@johnmorrisdotca/houseki/nature";
|
|
17
|
+
*
|
|
18
|
+
* const value: ReboundDirectionMode = "seeded";
|
|
19
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
2
22
|
export type ReboundDirectionMode = 'input-or-alternate' | 'seeded';
|
|
23
|
+
/** A counterclockwise, unchanged or clockwise quarter-turn chosen by the host.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import type { QuarterTurn } from "@johnmorrisdotca/houseki/nature";
|
|
28
|
+
*
|
|
29
|
+
* const value: QuarterTurn = 0;
|
|
30
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
3
33
|
export type QuarterTurn = -1 | 0 | 1;
|
|
4
|
-
/** Stable board occupant. Obstacles collide and block attraction but cannot move or attract.
|
|
34
|
+
/** Stable board occupant. Obstacles collide and block attraction but cannot move or attract.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* import type { NatureEntity } from "@johnmorrisdotca/houseki/nature";
|
|
39
|
+
*
|
|
40
|
+
* const value: NatureEntity = {id:1,kind:"stone",colour:"red"};
|
|
41
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
5
44
|
export interface NatureEntity {
|
|
6
45
|
readonly id: number;
|
|
7
46
|
readonly kind: 'stone' | 'obstacle';
|
|
@@ -9,16 +48,48 @@ export interface NatureEntity {
|
|
|
9
48
|
readonly magnetic?: boolean;
|
|
10
49
|
readonly anchored?: boolean;
|
|
11
50
|
}
|
|
51
|
+
/** A falling native stone with its cell coordinates and stable id.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import type { NaturePieceCell } from "@johnmorrisdotca/houseki/nature";
|
|
56
|
+
*
|
|
57
|
+
* const value: NaturePieceCell = {id:1,kind:"stone",colour:"red",x:1,y:0};
|
|
58
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
12
61
|
export interface NaturePieceCell extends NatureEntity {
|
|
13
62
|
readonly kind: 'stone';
|
|
14
63
|
readonly x: number;
|
|
15
64
|
readonly y: number;
|
|
16
65
|
}
|
|
66
|
+
/** The fixed native magnetic and rebound rule switches.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import { createNatureState } from "@johnmorrisdotca/houseki/nature";
|
|
71
|
+
* import type { NatureRules } from "@johnmorrisdotca/houseki/nature";
|
|
72
|
+
*
|
|
73
|
+
* const state=createNatureState({width:4,height:4,seed:"docs"});
|
|
74
|
+
* const value: NatureRules = state.rules;
|
|
75
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
17
78
|
export interface NatureRules {
|
|
18
79
|
readonly magneticEnabled: boolean;
|
|
19
80
|
readonly reboundEnabled: boolean;
|
|
20
81
|
readonly reboundDirectionMode: ReboundDirectionMode;
|
|
21
82
|
}
|
|
83
|
+
/** The native grid dimensions, passability mask, occupants, seed and magnetic/rebound settings.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* import type { NatureOptions } from "@johnmorrisdotca/houseki/nature";
|
|
88
|
+
*
|
|
89
|
+
* const value: NatureOptions = {width:4,height:4,seed:"docs"};
|
|
90
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
22
93
|
export interface NatureOptions {
|
|
23
94
|
readonly width: number;
|
|
24
95
|
readonly height: number;
|
|
@@ -31,6 +102,18 @@ export interface NatureOptions {
|
|
|
31
102
|
readonly reboundEnabled?: boolean;
|
|
32
103
|
readonly reboundDirectionMode?: ReboundDirectionMode;
|
|
33
104
|
}
|
|
105
|
+
/** The immutable native environment state with stable ids, seeded random state and placement count.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* import { createNatureState } from "@johnmorrisdotca/houseki/nature";
|
|
110
|
+
* import type { NatureState } from "@johnmorrisdotca/houseki/nature";
|
|
111
|
+
*
|
|
112
|
+
* const state=createNatureState({width:4,height:4,seed:"docs"});
|
|
113
|
+
* const value: NatureState = state;
|
|
114
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
34
117
|
export interface NatureState {
|
|
35
118
|
readonly width: number;
|
|
36
119
|
readonly height: number;
|
|
@@ -42,6 +125,16 @@ export interface NatureState {
|
|
|
42
125
|
readonly committedPlacements: number;
|
|
43
126
|
readonly rules: NatureRules;
|
|
44
127
|
}
|
|
128
|
+
/** One native stable-id move between two board coordinates.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* import type { NatureMove } from "@johnmorrisdotca/houseki/nature";
|
|
133
|
+
*
|
|
134
|
+
* const value: NatureMove = {id:1,from:{x:0,y:0},to:{x:0,y:1}};
|
|
135
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
45
138
|
export interface NatureMove {
|
|
46
139
|
readonly id: number;
|
|
47
140
|
readonly from: {
|
|
@@ -53,6 +146,16 @@ export interface NatureMove {
|
|
|
53
146
|
readonly y: number;
|
|
54
147
|
};
|
|
55
148
|
}
|
|
149
|
+
/** A pure attraction decision including the paired ids, axis, gap, midpoint and moves.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* import type { AttractionPairPreview } from "@johnmorrisdotca/houseki/nature";
|
|
154
|
+
*
|
|
155
|
+
* const value: AttractionPairPreview = {ids:[1,2],axis:"horizontal",emptyGap:1,midpoint:{x:1,y:1},moves:[]};
|
|
156
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
56
159
|
export interface AttractionPairPreview {
|
|
57
160
|
readonly ids: readonly [number, number];
|
|
58
161
|
readonly axis: 'horizontal' | 'vertical';
|
|
@@ -64,11 +167,34 @@ export interface AttractionPairPreview {
|
|
|
64
167
|
readonly anchoredId?: number;
|
|
65
168
|
readonly moves: readonly NatureMove[];
|
|
66
169
|
}
|
|
170
|
+
/** A pure magnetic-pulse result; no input state or random source is consumed.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* import { createNatureState, previewMagneticPulse } from "@johnmorrisdotca/houseki/nature";
|
|
175
|
+
* import type { MagneticPreview } from "@johnmorrisdotca/houseki/nature";
|
|
176
|
+
*
|
|
177
|
+
* const state=createNatureState({width:4,height:4,seed:"docs"});
|
|
178
|
+
* const value: MagneticPreview = previewMagneticPulse(state);
|
|
179
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
67
182
|
export interface MagneticPreview {
|
|
68
183
|
readonly pairs: readonly AttractionPairPreview[];
|
|
69
184
|
readonly moves: readonly NatureMove[];
|
|
70
185
|
readonly cells: readonly (NatureEntity | null)[];
|
|
71
186
|
}
|
|
187
|
+
/** The native piece cells, pivot id and host-selected power/rebound options.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* import type { PowerDropRequest } from "@johnmorrisdotca/houseki/nature";
|
|
192
|
+
*
|
|
193
|
+
* const request:PowerDropRequest={piece:[{id:1,kind:"stone",colour:"red",x:1,y:0}],pivotId:1,power:true};
|
|
194
|
+
* const value: PowerDropRequest = request;
|
|
195
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
72
198
|
export interface PowerDropRequest {
|
|
73
199
|
readonly piece: readonly NaturePieceCell[];
|
|
74
200
|
readonly pivotId: number;
|
|
@@ -77,11 +203,34 @@ export interface PowerDropRequest {
|
|
|
77
203
|
/** A caller-selected quarter-turn applied with the one-cell rebound. */
|
|
78
204
|
readonly quarterTurn?: QuarterTurn;
|
|
79
205
|
}
|
|
206
|
+
/** One tested rebound direction and quarter-turn with its collision-validity result.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* import type { ReboundAttemptPreview } from "@johnmorrisdotca/houseki/nature";
|
|
211
|
+
*
|
|
212
|
+
* const value: ReboundAttemptPreview = {direction:"left",quarterTurn:0,valid:true};
|
|
213
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
80
216
|
export interface ReboundAttemptPreview {
|
|
81
217
|
readonly direction: HorizontalDirection;
|
|
82
218
|
readonly quarterTurn: QuarterTurn;
|
|
83
219
|
readonly valid: boolean;
|
|
84
220
|
}
|
|
221
|
+
/** The pure normal landing, rebound attempts and final lock cells with resulting random state.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* import { createNatureState, previewPowerDrop } from "@johnmorrisdotca/houseki/nature";
|
|
226
|
+
* import type { PowerDropPreview, PowerDropRequest } from "@johnmorrisdotca/houseki/nature";
|
|
227
|
+
*
|
|
228
|
+
* const state=createNatureState({width:4,height:4,seed:"docs"});
|
|
229
|
+
* const request:PowerDropRequest={piece:[{id:1,kind:"stone",colour:"red",x:1,y:0}],pivotId:1,power:true};
|
|
230
|
+
* const value: PowerDropPreview = previewPowerDrop(state,request);
|
|
231
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
85
234
|
export interface PowerDropPreview {
|
|
86
235
|
readonly normalLanding: readonly NaturePieceCell[];
|
|
87
236
|
readonly attempts: readonly ReboundAttemptPreview[];
|
|
@@ -92,6 +241,18 @@ export interface PowerDropPreview {
|
|
|
92
241
|
readonly moves: readonly NatureMove[];
|
|
93
242
|
readonly randomStateAfter: number;
|
|
94
243
|
}
|
|
244
|
+
/** An emitted native magnetic marking, attraction or power-drop event.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* import { createNatureState } from "@johnmorrisdotca/houseki/nature";
|
|
249
|
+
* import type { NatureEvent } from "@johnmorrisdotca/houseki/nature";
|
|
250
|
+
*
|
|
251
|
+
* const state=createNatureState({width:4,height:4,seed:"docs"});
|
|
252
|
+
* const value: NatureEvent = {type:"magnetic-stones-marked",ids:[],randomState:state.randomState};
|
|
253
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
95
256
|
export type NatureEvent = {
|
|
96
257
|
readonly type: 'magnetic-pulse';
|
|
97
258
|
readonly pairs: readonly AttractionPairPreview[];
|
|
@@ -109,6 +270,18 @@ export type NatureEvent = {
|
|
|
109
270
|
readonly moves: readonly NatureMove[];
|
|
110
271
|
readonly ids: readonly number[];
|
|
111
272
|
};
|
|
273
|
+
/** The native environment result, emitted events and optional pure preview.
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* ```ts
|
|
277
|
+
* import { applyMagneticPulse, createNatureState } from "@johnmorrisdotca/houseki/nature";
|
|
278
|
+
* import type { NatureTransition } from "@johnmorrisdotca/houseki/nature";
|
|
279
|
+
*
|
|
280
|
+
* const state=createNatureState({width:4,height:4,seed:"docs"});
|
|
281
|
+
* const value: NatureTransition = applyMagneticPulse(state);
|
|
282
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
112
285
|
export interface NatureTransition {
|
|
113
286
|
readonly state: NatureState;
|
|
114
287
|
readonly accepted: boolean;
|
|
@@ -116,9 +289,29 @@ export interface NatureTransition {
|
|
|
116
289
|
readonly events: readonly NatureEvent[];
|
|
117
290
|
readonly preview?: MagneticPreview | PowerDropPreview;
|
|
118
291
|
}
|
|
292
|
+
/** The probability and optional count/anchor bounds used to mark magnetic stones.
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* ```ts
|
|
296
|
+
* import type { MarkingOptions } from "@johnmorrisdotca/houseki/nature";
|
|
297
|
+
*
|
|
298
|
+
* const value: MarkingOptions = {probability:0.25,maximum:2};
|
|
299
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
119
302
|
export interface MarkingOptions {
|
|
120
303
|
readonly probability: number;
|
|
121
304
|
readonly maximum?: number;
|
|
122
305
|
readonly anchoredProbability?: number;
|
|
123
306
|
}
|
|
307
|
+
/** Stable native validation codes for grid, cell, marking and power-drop failures.
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```ts
|
|
311
|
+
* import type { NatureErrorCode } from "@johnmorrisdotca/houseki/nature";
|
|
312
|
+
*
|
|
313
|
+
* const value: NatureErrorCode = "invalid-grid-size";
|
|
314
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
124
317
|
export type NatureErrorCode = 'invalid-nature-options' | 'invalid-grid-size' | 'invalid-seed' | 'invalid-mask' | 'invalid-cell' | 'duplicate-id' | 'invalid-marking-options' | 'invalid-power-drop' | 'piece-collision' | 'invalid-piece-position';
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import type { MarkingOptions, NatureEntity, NatureErrorCode, NatureOptions, NatureState, PowerDropRequest } from './types.js';
|
|
2
|
+
/** A typed native grid, cell, marking or power-drop validation error.
|
|
3
|
+
*
|
|
4
|
+
* @param code - The native stable error code used by callers to distinguish setup or replay failures.
|
|
5
|
+
* @param message - The human-readable diagnostic accompanying the native code.
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { NatureOptionsError } from "@johnmorrisdotca/houseki/nature";
|
|
9
|
+
*
|
|
10
|
+
* const error=new NatureOptionsError("invalid-grid-size","Invalid example setup");
|
|
11
|
+
* console.log(error.name,error.code,error.message);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
2
14
|
export declare class NatureOptionsError extends RangeError {
|
|
3
15
|
readonly code: NatureErrorCode;
|
|
4
16
|
constructor(code: NatureErrorCode, message: string);
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/** A typed native grid, cell, marking or power-drop validation error.
|
|
2
|
+
*
|
|
3
|
+
* @param code - The native stable error code used by callers to distinguish setup or replay failures.
|
|
4
|
+
* @param message - The human-readable diagnostic accompanying the native code.
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { NatureOptionsError } from "@johnmorrisdotca/houseki/nature";
|
|
8
|
+
*
|
|
9
|
+
* const error=new NatureOptionsError("invalid-grid-size","Invalid example setup");
|
|
10
|
+
* console.log(error.name,error.code,error.message);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
1
13
|
export class NatureOptionsError extends RangeError {
|
|
2
14
|
code;
|
|
3
15
|
constructor(code, message) { super(message); this.name = 'NatureOptionsError'; this.code = code; }
|
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
import type { ChallengeGoal, Stone, StoneColour } from './types.js';
|
|
2
|
+
/** One authored text in English and Japanese.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import type { LocalizedText } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
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/stone-collapse";
|
|
21
|
+
* import type { CollapseDifficultyMetrics } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
22
|
+
*
|
|
23
|
+
* const level=levelManifest[0];
|
|
24
|
+
* const value: CollapseDifficultyMetrics = level.rawMetrics;
|
|
25
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
6
28
|
export interface CollapseDifficultyMetrics {
|
|
7
29
|
readonly seededPlayoutSamples: number;
|
|
8
30
|
readonly seededPlayoutSuccesses: number;
|
|
@@ -15,6 +37,18 @@ export interface CollapseDifficultyMetrics {
|
|
|
15
37
|
readonly witnessMoves: number;
|
|
16
38
|
readonly moveBudgetSlack: number;
|
|
17
39
|
}
|
|
40
|
+
/** One authored native challenge with its stable id, setup, winning witness, measurements and review status.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { levelManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
45
|
+
* import type { CollapseCampaignLevel } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
46
|
+
*
|
|
47
|
+
* const level=levelManifest[0];
|
|
48
|
+
* const value: CollapseCampaignLevel = level;
|
|
49
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
18
52
|
export interface CollapseCampaignLevel {
|
|
19
53
|
readonly id: string;
|
|
20
54
|
readonly number: number;
|
|
@@ -37,6 +71,17 @@ export interface CollapseCampaignLevel {
|
|
|
37
71
|
readonly proofStatus: 'engine-witness-verified';
|
|
38
72
|
readonly reviewStatus: 'human-review-pending';
|
|
39
73
|
}
|
|
74
|
+
/** The ordered native campaign, its generation/grading revisions, checksum and measured levels.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import type { CollapseCampaignManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
79
|
+
* import { campaignManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
80
|
+
*
|
|
81
|
+
* const value: CollapseCampaignManifest = campaignManifest;
|
|
82
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
40
85
|
export interface CollapseCampaignManifest {
|
|
41
86
|
readonly count: number;
|
|
42
87
|
readonly candidatePoolCount: number;
|
|
@@ -50,10 +95,34 @@ export interface CollapseCampaignManifest {
|
|
|
50
95
|
readonly checksum: string;
|
|
51
96
|
readonly levels: readonly CollapseCampaignLevel[];
|
|
52
97
|
}
|
|
98
|
+
/** One bilingual native lesson instruction and the corresponding action or tick step.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
103
|
+
* import type { CollapseTutorialStep } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
104
|
+
*
|
|
105
|
+
* const lesson=tutorialManifest[0];
|
|
106
|
+
* const value: CollapseTutorialStep = lesson.steps[0];
|
|
107
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
53
110
|
export interface CollapseTutorialStep {
|
|
54
111
|
readonly instruction: LocalizedText;
|
|
55
112
|
readonly action: string;
|
|
56
113
|
}
|
|
114
|
+
/** One bilingual native lesson with its authored setup, teaching steps and winning witness.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
119
|
+
* import type { CollapseTutorialDefinition } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
120
|
+
*
|
|
121
|
+
* const lesson=tutorialManifest[0];
|
|
122
|
+
* const value: CollapseTutorialDefinition = lesson;
|
|
123
|
+
* console.log(value == null ? value : typeof value === "object" ? Object.keys(value).slice(0,6) : value);
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
57
126
|
export interface CollapseTutorialDefinition {
|
|
58
127
|
readonly id: string;
|
|
59
128
|
readonly title: LocalizedText;
|
|
@@ -1,11 +1,68 @@
|
|
|
1
1
|
import type { CollapseCampaignLevel, CollapseCampaignManifest, CollapseTutorialDefinition } 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/stone-collapse";
|
|
8
|
+
*
|
|
9
|
+
* console.log(campaignManifest.count);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
3
12
|
export declare const campaignManifest: CollapseCampaignManifest;
|
|
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/stone-collapse";
|
|
18
|
+
*
|
|
19
|
+
* console.log(levelManifest.length);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
4
22
|
export declare const levelManifest: readonly CollapseCampaignLevel[];
|
|
23
|
+
/** The frozen native bilingual lessons and their authored teaching steps.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
28
|
+
*
|
|
29
|
+
* console.log(tutorialManifest.length);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
5
32
|
export declare const tutorialManifest: readonly CollapseTutorialDefinition[];
|
|
6
|
-
/** Find a challenge by its persistent content ID or current one-based display number.
|
|
33
|
+
/** Find a challenge by its persistent content ID or 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 challenge by its persistent content ID or 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/stone-collapse";
|
|
40
|
+
*
|
|
41
|
+
* console.log(getLevel(1)?.id);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
7
44
|
export declare function getLevel(id: string | number): CollapseCampaignLevel | undefined;
|
|
8
|
-
/** Construct a fresh engine-validated challenge from a content ID or display number.
|
|
45
|
+
/** Construct a fresh engine-validated challenge from a content 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 engine-validated challenge from a content ID or display number.
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { createLevel } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
52
|
+
*
|
|
53
|
+
* console.log(createLevel(1).phase);
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
9
56
|
export declare function createLevel(id: string | number): GameState;
|
|
10
|
-
/** Find a persistent interactive lesson by its stable ID.
|
|
57
|
+
/** Find a persistent interactive lesson by its stable ID.
|
|
58
|
+
*
|
|
59
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
60
|
+
* @returns Find a persistent interactive lesson by its stable ID. Returns undefined when the id or display number is absent.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { getTutorial, tutorialManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
64
|
+
*
|
|
65
|
+
* console.log(getTutorial(tutorialManifest[0].id)?.id);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
11
68
|
export declare function getTutorial(id: string): CollapseTutorialDefinition | undefined;
|
|
@@ -8,21 +8,78 @@ function deepFreeze(value) {
|
|
|
8
8
|
}
|
|
9
9
|
return value;
|
|
10
10
|
}
|
|
11
|
+
/** The frozen native campaign manifest with its ordering, revisions, checksum and measured levels.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { campaignManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
16
|
+
*
|
|
17
|
+
* console.log(campaignManifest.count);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
11
20
|
export const campaignManifest = deepFreeze(contentData.campaign);
|
|
21
|
+
/** The frozen ordered native levels; array indices start at zero and display numbers start at one.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { levelManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
26
|
+
*
|
|
27
|
+
* console.log(levelManifest.length);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
12
30
|
export const levelManifest = campaignManifest.levels;
|
|
31
|
+
/** The frozen native bilingual lessons and their authored teaching steps.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { tutorialManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
36
|
+
*
|
|
37
|
+
* console.log(tutorialManifest.length);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
13
40
|
export const tutorialManifest = deepFreeze(contentData.tutorials);
|
|
14
|
-
/** Find a challenge by its persistent content ID or current one-based display number.
|
|
41
|
+
/** Find a challenge by its persistent content ID or current one-based display number.
|
|
42
|
+
*
|
|
43
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
44
|
+
* @returns Find a challenge by its persistent content ID or current one-based display number. Returns undefined when the id or display number is absent.
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { getLevel } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
48
|
+
*
|
|
49
|
+
* console.log(getLevel(1)?.id);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
15
52
|
export function getLevel(id) {
|
|
16
53
|
if (typeof id === 'number')
|
|
17
54
|
return Number.isInteger(id) ? levelManifest.find(level => level.number === id) : undefined;
|
|
18
55
|
return levelManifest.find(level => level.id === id);
|
|
19
56
|
}
|
|
20
|
-
/** Construct a fresh engine-validated challenge from a content ID or display number.
|
|
57
|
+
/** Construct a fresh engine-validated challenge from a content ID or display number.
|
|
58
|
+
*
|
|
59
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
60
|
+
* @returns Construct a fresh engine-validated challenge from a content ID or display number.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { createLevel } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
64
|
+
*
|
|
65
|
+
* console.log(createLevel(1).phase);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
21
68
|
export function createLevel(id) {
|
|
22
69
|
const level = getLevel(id);
|
|
23
70
|
if (!level)
|
|
24
71
|
throw new RangeError(`Unknown Stone Collapse level: ${String(id)}`);
|
|
25
72
|
return createChallenge({ id: level.id, seed: level.seed, width: level.width, height: level.height, colourCount: level.colourCount, ...(level.mask ? { mask: level.mask } : {}), initialBoard: level.board, goal: level.goal, moveLimit: level.moveLimit, witness: level.witness });
|
|
26
73
|
}
|
|
27
|
-
/** Find a persistent interactive lesson by its stable ID.
|
|
74
|
+
/** Find a persistent interactive lesson by its stable ID.
|
|
75
|
+
*
|
|
76
|
+
* @param id - A stable content id, or the one-based display number when numbers are accepted.
|
|
77
|
+
* @returns Find a persistent interactive lesson by its stable ID. Returns undefined when the id or display number is absent.
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { getTutorial, tutorialManifest } from "@johnmorrisdotca/houseki/stone-collapse";
|
|
81
|
+
*
|
|
82
|
+
* console.log(getTutorial(tutorialManifest[0].id)?.id);
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
28
85
|
export function getTutorial(id) { return tutorialManifest.find(tutorial => tutorial.id === id); }
|