@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.
Files changed (72) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/README.md +77 -95
  3. package/dist/colour-chains/challenge.d.ts +12 -1
  4. package/dist/colour-chains/challenge.js +12 -1
  5. package/dist/colour-chains/content-types.d.ts +112 -0
  6. package/dist/colour-chains/content.d.ts +140 -3
  7. package/dist/colour-chains/content.js +140 -3
  8. package/dist/colour-chains/engine.d.ts +85 -6
  9. package/dist/colour-chains/engine.js +85 -6
  10. package/dist/colour-chains/input.d.ts +97 -7
  11. package/dist/colour-chains/input.js +97 -7
  12. package/dist/colour-chains/persistence.d.ts +36 -3
  13. package/dist/colour-chains/persistence.js +36 -3
  14. package/dist/colour-chains/types.d.ts +291 -17
  15. package/dist/colour-chains/validation.d.ts +12 -1
  16. package/dist/colour-chains/validation.js +12 -1
  17. package/dist/falling-triplets/content-types.d.ts +69 -0
  18. package/dist/falling-triplets/content.d.ts +60 -3
  19. package/dist/falling-triplets/content.js +60 -3
  20. package/dist/falling-triplets/engine.d.ts +122 -10
  21. package/dist/falling-triplets/engine.js +122 -10
  22. package/dist/falling-triplets/input.d.ts +61 -5
  23. package/dist/falling-triplets/input.js +61 -5
  24. package/dist/falling-triplets/match.d.ts +26 -2
  25. package/dist/falling-triplets/match.js +26 -2
  26. package/dist/falling-triplets/random.d.ts +34 -3
  27. package/dist/falling-triplets/random.js +34 -3
  28. package/dist/falling-triplets/types.d.ts +227 -3
  29. package/dist/gem-swap/content.d.ts +116 -0
  30. package/dist/gem-swap/content.js +72 -0
  31. package/dist/gem-swap/engine.d.ts +124 -9
  32. package/dist/gem-swap/engine.js +124 -9
  33. package/dist/gem-swap/persistence.d.ts +60 -4
  34. package/dist/gem-swap/persistence.js +65 -7
  35. package/dist/gem-swap/practice.js +2 -2
  36. package/dist/gem-swap/types.d.ts +336 -3
  37. package/dist/magnetic-blocks/content-types.d.ts +56 -0
  38. package/dist/magnetic-blocks/content.d.ts +91 -5
  39. package/dist/magnetic-blocks/content.js +91 -5
  40. package/dist/magnetic-blocks/engine.d.ts +63 -5
  41. package/dist/magnetic-blocks/engine.js +63 -5
  42. package/dist/magnetic-blocks/persistence.d.ts +36 -3
  43. package/dist/magnetic-blocks/persistence.js +36 -3
  44. package/dist/magnetic-blocks/physics.d.ts +176 -6
  45. package/dist/magnetic-blocks/physics.js +176 -6
  46. package/dist/magnetic-blocks/types.d.ts +185 -1
  47. package/dist/magnetic-blocks/validation.d.ts +12 -0
  48. package/dist/magnetic-blocks/validation.js +12 -0
  49. package/dist/nature/attraction.d.ts +24 -2
  50. package/dist/nature/attraction.js +24 -2
  51. package/dist/nature/environment.d.ts +200 -7
  52. package/dist/nature/environment.js +88 -7
  53. package/dist/nature/marking.d.ts +13 -1
  54. package/dist/nature/marking.js +13 -1
  55. package/dist/nature/rebound.d.ts +30 -2
  56. package/dist/nature/rebound.js +30 -2
  57. package/dist/nature/state.d.ts +11 -0
  58. package/dist/nature/state.js +11 -0
  59. package/dist/nature/types.d.ts +194 -1
  60. package/dist/nature/validation.d.ts +12 -0
  61. package/dist/nature/validation.js +12 -0
  62. package/dist/stone-collapse/content-types.d.ts +69 -0
  63. package/dist/stone-collapse/content.d.ts +60 -3
  64. package/dist/stone-collapse/content.js +60 -3
  65. package/dist/stone-collapse/engine.d.ts +99 -8
  66. package/dist/stone-collapse/engine.js +99 -8
  67. package/dist/stone-collapse/persistence.d.ts +36 -3
  68. package/dist/stone-collapse/persistence.js +36 -3
  69. package/dist/stone-collapse/types.d.ts +220 -3
  70. package/dist/stone-collapse/validation.d.ts +12 -1
  71. package/dist/stone-collapse/validation.js +12 -1
  72. package/package.json +34 -26
@@ -7,18 +7,108 @@ export interface InputSchedulerState {
7
7
  readonly held: Readonly<Partial<Record<HeldControl, number>>>;
8
8
  readonly queued: readonly EdgeAction[];
9
9
  }
10
- /** Creates an empty held-input scheduler. */
10
+ /** Creates an empty held-input scheduler.
11
+ *
12
+ * @returns Creates an empty held-input scheduler.
13
+ * @example
14
+ * ```ts
15
+ * import { createInputScheduler } from "@johnmorrisdotca/houseki/colour-chains";
16
+ *
17
+ * console.log(Object.keys(createInputScheduler()));
18
+ * ```
19
+ */
11
20
  export declare function createInputScheduler(): InputSchedulerState;
12
- /** Starts or releases one held control. Repeated press edges do not reset its repeat counter. */
21
+ /** Starts or releases one held control. Repeated press edges do not reset its repeat counter.
22
+ *
23
+ * @param state - The immutable native state to read or transition; the input is retained.
24
+ * @param control - The native held-control name.
25
+ * @param pressed - Whether this control is currently pressed.
26
+ * @returns Starts or releases one held control. Repeated press edges do not reset its repeat counter.
27
+ * @example
28
+ * ```ts
29
+ * import { createInputScheduler, setHeldInput } from "@johnmorrisdotca/houseki/colour-chains";
30
+ *
31
+ * const input=createInputScheduler();
32
+ * console.log(setHeldInput(input,"left",true));
33
+ * ```
34
+ */
13
35
  export declare function setHeldInput(state: InputSchedulerState, control: HeldControl, pressed: boolean): InputSchedulerState;
14
- /** Queues a one-shot rotation, drop, Place, pause or resume edge for the next logical tick. */
36
+ /** Queues a one-shot rotation, drop, Place, pause or resume edge for the next logical tick.
37
+ *
38
+ * @param state - The immutable native state to read or transition; the input is retained.
39
+ * @param action - One native action for this entry point; inspect accepted and reason on the result.
40
+ * @returns Queues a one-shot rotation, drop, Place, pause or resume edge for the next logical tick.
41
+ * @example
42
+ * ```ts
43
+ * import { createInputScheduler, queueInputEdge } from "@johnmorrisdotca/houseki/colour-chains";
44
+ *
45
+ * const input=createInputScheduler();
46
+ * console.log(queueInputEdge(input,{kind:"hard-drop"}));
47
+ * ```
48
+ */
15
49
  export declare function queueInputEdge(state: InputSchedulerState, action: EdgeAction): InputSchedulerState;
16
- /** Releases every held or queued control after focus loss, lock, resolution or pause. */
50
+ /** Releases every held or queued control after focus loss, lock, resolution or pause.
51
+ *
52
+ * @param state - The immutable native state to read or transition; the input is retained.
53
+ * @returns Releases every held or queued control after focus loss, lock, resolution or pause.
54
+ * @example
55
+ * ```ts
56
+ * import { createInputScheduler, releaseAllInput } from "@johnmorrisdotca/houseki/colour-chains";
57
+ *
58
+ * const input=createInputScheduler();
59
+ * console.log(releaseAllInput(input));
60
+ * ```
61
+ */
17
62
  export declare function releaseAllInput(state: InputSchedulerState): InputSchedulerState;
18
- /** Resolves this tick's inputs in lateral, rotation, drop, soft-drop, pause order. */
63
+ /** Resolves this tick's inputs in lateral, rotation, drop, soft-drop, pause order.
64
+ *
65
+ * @param game - The native game state used to resolve scheduled input.
66
+ * @param input - The held-input scheduler state for this logical tick.
67
+ * @returns Resolves this tick's inputs in lateral, rotation, drop, soft-drop, pause order.
68
+ * @example
69
+ * ```ts
70
+ * import { actionsForTick, createGame, createInputScheduler } from "@johnmorrisdotca/houseki/colour-chains";
71
+ *
72
+ * const state=createGame({seed:"docs"});
73
+ * const input=createInputScheduler();
74
+ * console.log(actionsForTick(state,input)[0]);
75
+ * ```
76
+ */
19
77
  export declare function actionsForTick(game: GameState, input: InputSchedulerState): readonly [readonly Action[], InputSchedulerState];
20
- /** Applies a scheduler batch until the pair locks or the run pauses; accepted actions are recorded by the engine. */
78
+ /** Applies a scheduler batch until the pair locks or the run pauses; accepted actions are recorded by the engine.
79
+ *
80
+ * @param game - The native game state used to resolve scheduled input.
81
+ * @param input - The held-input scheduler state for this logical tick.
82
+ * @param actions - Native actions in the scheduler’s canonical order.
83
+ * @param applyAction - The native applyAction function for this game.
84
+ * @returns Applies a scheduler batch until the pair locks or the run pauses; accepted actions are recorded by the engine.
85
+ * @example
86
+ * ```ts
87
+ * import { applyAction, applyScheduledActions, createGame, createInputScheduler } from "@johnmorrisdotca/houseki/colour-chains";
88
+ * import type { Action } from "@johnmorrisdotca/houseki/colour-chains";
89
+ *
90
+ * const state=createGame({seed:"docs"});
91
+ * const action: Action={kind:"left"};
92
+ * const input=createInputScheduler();
93
+ * console.log(applyScheduledActions(state,input,[action],applyAction)[0].phase);
94
+ * ```
95
+ */
21
96
  export declare function applyScheduledActions(game: GameState, input: InputSchedulerState, actions: readonly Action[], applyAction: (state: GameState, action: Action) => Transition): readonly [GameState, InputSchedulerState, readonly Transition[]];
22
- /** Applies a complete deterministic held-input and simulation tick, releasing controls on lock or resolution. */
97
+ /** Applies a complete deterministic held-input and simulation tick, releasing controls on lock or resolution.
98
+ *
99
+ * @param game - The native game state used to resolve scheduled input.
100
+ * @param input - The held-input scheduler state for this logical tick.
101
+ * @param apply - The native applyAction function for this game.
102
+ * @param tick - The native advanceTicks function for this game.
103
+ * @returns Applies a complete deterministic held-input and simulation tick, releasing controls on lock or resolution.
104
+ * @example
105
+ * ```ts
106
+ * import { advanceTicks, applyAction, createGame, createInputScheduler, processInputTick } from "@johnmorrisdotca/houseki/colour-chains";
107
+ *
108
+ * const state=createGame({seed:"docs"});
109
+ * const input=createInputScheduler();
110
+ * console.log(processInputTick(state,input,applyAction,advanceTicks)[0].phase);
111
+ * ```
112
+ */
23
113
  export declare function processInputTick(game: GameState, input: InputSchedulerState, apply: (state: GameState, action: Action) => Transition, tick: (state: GameState, ticks: number) => Transition): readonly [GameState, InputSchedulerState, readonly Transition[]];
24
114
  export {};
@@ -1,6 +1,28 @@
1
- /** Creates an empty held-input scheduler. */
1
+ /** Creates an empty held-input scheduler.
2
+ *
3
+ * @returns Creates an empty held-input scheduler.
4
+ * @example
5
+ * ```ts
6
+ * import { createInputScheduler } from "@johnmorrisdotca/houseki/colour-chains";
7
+ *
8
+ * console.log(Object.keys(createInputScheduler()));
9
+ * ```
10
+ */
2
11
  export function createInputScheduler() { return { held: Object.freeze({}), queued: Object.freeze([]) }; }
3
- /** Starts or releases one held control. Repeated press edges do not reset its repeat counter. */
12
+ /** Starts or releases one held control. Repeated press edges do not reset its repeat counter.
13
+ *
14
+ * @param state - The immutable native state to read or transition; the input is retained.
15
+ * @param control - The native held-control name.
16
+ * @param pressed - Whether this control is currently pressed.
17
+ * @returns Starts or releases one held control. Repeated press edges do not reset its repeat counter.
18
+ * @example
19
+ * ```ts
20
+ * import { createInputScheduler, setHeldInput } from "@johnmorrisdotca/houseki/colour-chains";
21
+ *
22
+ * const input=createInputScheduler();
23
+ * console.log(setHeldInput(input,"left",true));
24
+ * ```
25
+ */
4
26
  export function setHeldInput(state, control, pressed) {
5
27
  const held = { ...state.held };
6
28
  if (pressed) {
@@ -11,12 +33,48 @@ export function setHeldInput(state, control, pressed) {
11
33
  delete held[control];
12
34
  return { ...state, held: Object.freeze(held) };
13
35
  }
14
- /** Queues a one-shot rotation, drop, Place, pause or resume edge for the next logical tick. */
36
+ /** Queues a one-shot rotation, drop, Place, pause or resume edge for the next logical tick.
37
+ *
38
+ * @param state - The immutable native state to read or transition; the input is retained.
39
+ * @param action - One native action for this entry point; inspect accepted and reason on the result.
40
+ * @returns Queues a one-shot rotation, drop, Place, pause or resume edge for the next logical tick.
41
+ * @example
42
+ * ```ts
43
+ * import { createInputScheduler, queueInputEdge } from "@johnmorrisdotca/houseki/colour-chains";
44
+ *
45
+ * const input=createInputScheduler();
46
+ * console.log(queueInputEdge(input,{kind:"hard-drop"}));
47
+ * ```
48
+ */
15
49
  export function queueInputEdge(state, action) { return { ...state, queued: Object.freeze([...state.queued, action]) }; }
16
- /** Releases every held or queued control after focus loss, lock, resolution or pause. */
50
+ /** Releases every held or queued control after focus loss, lock, resolution or pause.
51
+ *
52
+ * @param state - The immutable native state to read or transition; the input is retained.
53
+ * @returns Releases every held or queued control after focus loss, lock, resolution or pause.
54
+ * @example
55
+ * ```ts
56
+ * import { createInputScheduler, releaseAllInput } from "@johnmorrisdotca/houseki/colour-chains";
57
+ *
58
+ * const input=createInputScheduler();
59
+ * console.log(releaseAllInput(input));
60
+ * ```
61
+ */
17
62
  // eslint-disable-next-line @typescript-eslint/no-unused-vars -- the public signature takes the state a caller holds, though nothing of it is kept
18
63
  export function releaseAllInput(state) { return createInputScheduler(); }
19
- /** Resolves this tick's inputs in lateral, rotation, drop, soft-drop, pause order. */
64
+ /** Resolves this tick's inputs in lateral, rotation, drop, soft-drop, pause order.
65
+ *
66
+ * @param game - The native game state used to resolve scheduled input.
67
+ * @param input - The held-input scheduler state for this logical tick.
68
+ * @returns Resolves this tick's inputs in lateral, rotation, drop, soft-drop, pause order.
69
+ * @example
70
+ * ```ts
71
+ * import { actionsForTick, createGame, createInputScheduler } from "@johnmorrisdotca/houseki/colour-chains";
72
+ *
73
+ * const state=createGame({seed:"docs"});
74
+ * const input=createInputScheduler();
75
+ * console.log(actionsForTick(state,input)[0]);
76
+ * ```
77
+ */
20
78
  export function actionsForTick(game, input) {
21
79
  if (game.phase === 'paused') {
22
80
  const resume = input.queued.filter(action => action.kind === 'resume');
@@ -45,7 +103,24 @@ export function actionsForTick(game, input) {
45
103
  held[control] = (held[control] ?? 0) + 1;
46
104
  return [actions, { held: Object.freeze(held), queued: Object.freeze([]) }];
47
105
  }
48
- /** Applies a scheduler batch until the pair locks or the run pauses; accepted actions are recorded by the engine. */
106
+ /** Applies a scheduler batch until the pair locks or the run pauses; accepted actions are recorded by the engine.
107
+ *
108
+ * @param game - The native game state used to resolve scheduled input.
109
+ * @param input - The held-input scheduler state for this logical tick.
110
+ * @param actions - Native actions in the scheduler’s canonical order.
111
+ * @param applyAction - The native applyAction function for this game.
112
+ * @returns Applies a scheduler batch until the pair locks or the run pauses; accepted actions are recorded by the engine.
113
+ * @example
114
+ * ```ts
115
+ * import { applyAction, applyScheduledActions, createGame, createInputScheduler } from "@johnmorrisdotca/houseki/colour-chains";
116
+ * import type { Action } from "@johnmorrisdotca/houseki/colour-chains";
117
+ *
118
+ * const state=createGame({seed:"docs"});
119
+ * const action: Action={kind:"left"};
120
+ * const input=createInputScheduler();
121
+ * console.log(applyScheduledActions(state,input,[action],applyAction)[0].phase);
122
+ * ```
123
+ */
49
124
  export function applyScheduledActions(game, input, actions, applyAction) {
50
125
  let state = game;
51
126
  const transitions = [];
@@ -64,7 +139,22 @@ export function applyScheduledActions(game, input, actions, applyAction) {
64
139
  const lockedOrPaused = transitions.some(result => result.events.some(event => event.type === 'pair-locked' || event.type === 'paused')) || state.phase !== 'falling';
65
140
  return [state, lockedOrPaused ? createInputScheduler() : input, transitions];
66
141
  }
67
- /** Applies a complete deterministic held-input and simulation tick, releasing controls on lock or resolution. */
142
+ /** Applies a complete deterministic held-input and simulation tick, releasing controls on lock or resolution.
143
+ *
144
+ * @param game - The native game state used to resolve scheduled input.
145
+ * @param input - The held-input scheduler state for this logical tick.
146
+ * @param apply - The native applyAction function for this game.
147
+ * @param tick - The native advanceTicks function for this game.
148
+ * @returns Applies a complete deterministic held-input and simulation tick, releasing controls on lock or resolution.
149
+ * @example
150
+ * ```ts
151
+ * import { advanceTicks, applyAction, createGame, createInputScheduler, processInputTick } from "@johnmorrisdotca/houseki/colour-chains";
152
+ *
153
+ * const state=createGame({seed:"docs"});
154
+ * const input=createInputScheduler();
155
+ * console.log(processInputTick(state,input,applyAction,advanceTicks)[0].phase);
156
+ * ```
157
+ */
68
158
  export function processInputTick(game, input, apply, tick) {
69
159
  const [actions, scheduled] = actionsForTick(game, input);
70
160
  const [afterInput, retained, transitions] = applyScheduledActions(game, scheduled, actions, apply);
@@ -1,7 +1,40 @@
1
1
  import type { GameState } from './types.js';
2
- /** Restarts the same seed/date or original witnessed challenge board and queue. */
2
+ /** Restarts the same seed/date or original witnessed challenge board and queue.
3
+ *
4
+ * @param state - The immutable native state to read or transition; the input is retained.
5
+ * @returns Restarts the same seed/date or original witnessed challenge board and queue.
6
+ * @example
7
+ * ```ts
8
+ * import { createGame, restartGame } from "@johnmorrisdotca/houseki/colour-chains";
9
+ *
10
+ * const state=createGame({seed:"docs"});
11
+ * console.log(restartGame(state).phase);
12
+ * ```
13
+ */
3
14
  export declare function restartGame(state: GameState): GameState;
4
- /** Encodes canonical initial settings, accepted ordinal actions and a derived checkpoint. */
15
+ /** Encodes canonical initial settings, accepted ordinal actions and a derived checkpoint.
16
+ *
17
+ * @param state - The immutable native state to read or transition; the input is retained.
18
+ * @returns Encodes canonical initial settings, accepted ordinal actions and a derived checkpoint.
19
+ * @example
20
+ * ```ts
21
+ * import { createGame, encodeGame } from "@johnmorrisdotca/houseki/colour-chains";
22
+ *
23
+ * const state=createGame({seed:"docs"});
24
+ * console.log(encodeGame(state).length);
25
+ * ```
26
+ */
5
27
  export declare function encodeGame(state: GameState): string;
6
- /** Reconstructs a bounded action replay and rejects any checkpoint that differs from replay. */
28
+ /** Reconstructs a bounded action replay and rejects any checkpoint that differs from replay.
29
+ *
30
+ * @param text - A saved JSON recording from this entry’s encodeGame; malformed or inconsistent saves throw.
31
+ * @returns Reconstructs a bounded action replay and rejects any checkpoint that differs from replay.
32
+ * @example
33
+ * ```ts
34
+ * import { createGame, decodeGame, encodeGame } from "@johnmorrisdotca/houseki/colour-chains";
35
+ *
36
+ * const state=createGame({seed:"docs"});
37
+ * console.log(decodeGame(encodeGame(state)).phase);
38
+ * ```
39
+ */
7
40
  export declare function decodeGame(text: string): GameState;
@@ -30,9 +30,31 @@ function createFromSettings(settings) {
30
30
  throw new TypeError('Save settings are not canonical');
31
31
  return state;
32
32
  }
33
- /** Restarts the same seed/date or original witnessed challenge board and queue. */
33
+ /** Restarts the same seed/date or original witnessed challenge board and queue.
34
+ *
35
+ * @param state - The immutable native state to read or transition; the input is retained.
36
+ * @returns Restarts the same seed/date or original witnessed challenge board and queue.
37
+ * @example
38
+ * ```ts
39
+ * import { createGame, restartGame } from "@johnmorrisdotca/houseki/colour-chains";
40
+ *
41
+ * const state=createGame({seed:"docs"});
42
+ * console.log(restartGame(state).phase);
43
+ * ```
44
+ */
34
45
  export function restartGame(state) { return createFromSettings(state.settings); }
35
- /** Encodes canonical initial settings, accepted ordinal actions and a derived checkpoint. */
46
+ /** Encodes canonical initial settings, accepted ordinal actions and a derived checkpoint.
47
+ *
48
+ * @param state - The immutable native state to read or transition; the input is retained.
49
+ * @returns Encodes canonical initial settings, accepted ordinal actions and a derived checkpoint.
50
+ * @example
51
+ * ```ts
52
+ * import { createGame, encodeGame } from "@johnmorrisdotca/houseki/colour-chains";
53
+ *
54
+ * const state=createGame({seed:"docs"});
55
+ * console.log(encodeGame(state).length);
56
+ * ```
57
+ */
36
58
  export function encodeGame(state) {
37
59
  if (!Number.isSafeInteger(state.elapsedTicks) || state.elapsedTicks < 0 || state.elapsedTicks > MAX_TICKS || state.recording.length > MAX_ACTIONS)
38
60
  throw new RangeError('Run exceeds replay limits');
@@ -41,7 +63,18 @@ export function encodeGame(state) {
41
63
  throw new RangeError('Save exceeds 2 MiB');
42
64
  return text;
43
65
  }
44
- /** Reconstructs a bounded action replay and rejects any checkpoint that differs from replay. */
66
+ /** Reconstructs a bounded action replay and rejects any checkpoint that differs from replay.
67
+ *
68
+ * @param text - A saved JSON recording from this entry’s encodeGame; malformed or inconsistent saves throw.
69
+ * @returns Reconstructs a bounded action replay and rejects any checkpoint that differs from replay.
70
+ * @example
71
+ * ```ts
72
+ * import { createGame, decodeGame, encodeGame } from "@johnmorrisdotca/houseki/colour-chains";
73
+ *
74
+ * const state=createGame({seed:"docs"});
75
+ * console.log(decodeGame(encodeGame(state)).phase);
76
+ * ```
77
+ */
45
78
  export function decodeGame(text) {
46
79
  if (typeof text !== 'string' || new TextEncoder().encode(text).byteLength > MAX_SAVE_BYTES)
47
80
  throw new RangeError('Save must be text no larger than 2 MiB');