@pompidup/kingdomino-engine 3.0.0 → 3.2.0
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/README.md +240 -110
- package/dist/index.d.ts +1137 -2
- package/dist/index.js +2103 -325
- package/dist/index.js.map +1 -1
- package/package.json +31 -21
package/dist/index.d.ts
CHANGED
|
@@ -1,86 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All possible ground/terrain types in Kingdomino.
|
|
3
|
+
* Each type can form contiguous properties for scoring.
|
|
4
|
+
*/
|
|
1
5
|
declare const GROUND: readonly ["castle", "wheat", "forest", "sea", "plain", "swamp", "mine"];
|
|
6
|
+
/** Union type of all terrain types */
|
|
2
7
|
type Ground = (typeof GROUND)[number];
|
|
8
|
+
/** Special ground type for empty/unplaced tiles */
|
|
3
9
|
type EmptyGround = "empty";
|
|
10
|
+
/** Number of crowns on a tile (0-3) */
|
|
4
11
|
type Crown = number;
|
|
12
|
+
/**
|
|
13
|
+
* Represents a single tile with terrain and crowns.
|
|
14
|
+
* Two tiles form a domino.
|
|
15
|
+
*/
|
|
5
16
|
type Tile = {
|
|
17
|
+
/** The terrain type of this tile */
|
|
6
18
|
type: Ground;
|
|
19
|
+
/** Number of crowns (0-3), multiplier for scoring */
|
|
7
20
|
crowns: Crown;
|
|
8
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Represents an empty/unplaced tile on the kingdom grid.
|
|
24
|
+
*/
|
|
9
25
|
type EmptyTile = {
|
|
26
|
+
/** Always "empty" for unplaced tiles */
|
|
10
27
|
type: EmptyGround;
|
|
28
|
+
/** Empty tiles have no crowns */
|
|
11
29
|
crowns: 0;
|
|
12
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Represents a domino piece consisting of two connected tiles.
|
|
33
|
+
* Dominoes are the main game pieces that players place on their kingdoms.
|
|
34
|
+
*/
|
|
13
35
|
type Domino = {
|
|
36
|
+
/** The left tile of the domino */
|
|
14
37
|
left: Tile;
|
|
38
|
+
/** The right tile of the domino */
|
|
15
39
|
right: Tile;
|
|
40
|
+
/** Unique number identifying this domino (1-48 in Classic mode) */
|
|
16
41
|
number: number;
|
|
17
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* Represents a domino that has been revealed for player selection.
|
|
45
|
+
* Contains selection state for the current turn.
|
|
46
|
+
*/
|
|
18
47
|
type RevealsDomino = {
|
|
48
|
+
/** The actual domino piece */
|
|
19
49
|
domino: Domino;
|
|
50
|
+
/** Whether this domino has been picked by a lord */
|
|
20
51
|
picked: boolean;
|
|
52
|
+
/** ID of the lord who picked this domino, or null if unpicked */
|
|
21
53
|
lordId: string | null;
|
|
54
|
+
/** Display position in the revealed set (for UI ordering) */
|
|
22
55
|
position: number;
|
|
23
56
|
};
|
|
24
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Represents a position on the kingdom grid.
|
|
60
|
+
* Origin (0,0) is at the top-left corner.
|
|
61
|
+
*/
|
|
25
62
|
type Position = {
|
|
63
|
+
/** Column index (0-8, left to right) */
|
|
26
64
|
x: number;
|
|
65
|
+
/** Row index (0-8, top to bottom) */
|
|
27
66
|
y: number;
|
|
28
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Rotation angle for domino placement.
|
|
70
|
+
* - 0: Horizontal, left tile at position, right tile to the east
|
|
71
|
+
* - 90: Vertical, left tile at position, right tile to the south
|
|
72
|
+
* - 180: Horizontal, right tile at position, left tile to the east
|
|
73
|
+
* - 270: Vertical, right tile at position, left tile to the south
|
|
74
|
+
*/
|
|
29
75
|
type Rotation = 0 | 90 | 180 | 270;
|
|
76
|
+
/**
|
|
77
|
+
* Represents a player's kingdom as a 2D grid of tiles.
|
|
78
|
+
* The grid is 9x9 to allow for the 5x5 maximum kingdom size
|
|
79
|
+
* with the castle at any position.
|
|
80
|
+
*/
|
|
30
81
|
type Kingdom = (Tile | EmptyTile)[][];
|
|
82
|
+
/**
|
|
83
|
+
* The size of the kingdom grid (9x9).
|
|
84
|
+
* This allows for a 5x5 kingdom with the castle placed anywhere.
|
|
85
|
+
*/
|
|
31
86
|
declare const GRIDSIZE = 9;
|
|
87
|
+
/**
|
|
88
|
+
* Maximum kingdom size (5x5 in standard rules, 7x7 for Mighty Duel).
|
|
89
|
+
*/
|
|
90
|
+
declare const MAX_KINGDOM_SIZE = 5;
|
|
32
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Represents a lord (player token) used for turn order and domino selection.
|
|
94
|
+
* In games with 2 players, each player has 2 lords.
|
|
95
|
+
* In games with 3-4 players, each player has 1 lord.
|
|
96
|
+
*/
|
|
33
97
|
type Lord = {
|
|
98
|
+
/** Unique identifier for this lord */
|
|
34
99
|
id: string;
|
|
100
|
+
/** ID of the player who owns this lord */
|
|
35
101
|
playerId: string;
|
|
102
|
+
/** Whether this lord has finished their turn */
|
|
36
103
|
turnEnded: boolean;
|
|
104
|
+
/** Whether this lord has picked a domino this round */
|
|
37
105
|
hasPick: boolean;
|
|
106
|
+
/** Whether this lord has placed/discarded a domino this round */
|
|
38
107
|
hasPlace: boolean;
|
|
108
|
+
/** The domino this lord picked (if any) */
|
|
39
109
|
dominoPicked?: Domino;
|
|
40
110
|
};
|
|
41
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Represents a game mode with its configuration.
|
|
114
|
+
* Currently only "Classic" mode is available.
|
|
115
|
+
*/
|
|
42
116
|
type GameMode = {
|
|
117
|
+
/** Name of the game mode (e.g., "Classic") */
|
|
43
118
|
name: string;
|
|
119
|
+
/** Description of the game mode */
|
|
44
120
|
description: string;
|
|
45
121
|
};
|
|
46
122
|
|
|
47
123
|
type ObjectValues<T> = T[keyof T];
|
|
48
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Represents a player in the game.
|
|
127
|
+
*/
|
|
49
128
|
type Player = {
|
|
129
|
+
/** Unique identifier for the player */
|
|
50
130
|
id: string;
|
|
131
|
+
/** Display name of the player */
|
|
51
132
|
name: string;
|
|
133
|
+
/** The player's kingdom grid where dominoes are placed */
|
|
52
134
|
kingdom: Kingdom;
|
|
135
|
+
/** If set, this player is controlled by a bot with the named strategy */
|
|
136
|
+
bot?: {
|
|
137
|
+
strategyName: string;
|
|
138
|
+
};
|
|
53
139
|
};
|
|
140
|
+
/**
|
|
141
|
+
* Payload for creating a new player.
|
|
142
|
+
*/
|
|
54
143
|
type PlayerPayload = {
|
|
144
|
+
/** Display name for the player (minimum 3 characters) */
|
|
55
145
|
name: string;
|
|
56
146
|
};
|
|
147
|
+
/** Array of player creation payloads */
|
|
57
148
|
type PlayersPayload = PlayerPayload[];
|
|
149
|
+
/** Array of players */
|
|
58
150
|
type Players = Player[];
|
|
151
|
+
/**
|
|
152
|
+
* Available actions a player can perform during their turn.
|
|
153
|
+
*/
|
|
59
154
|
declare const playerActions: {
|
|
155
|
+
/** Place a previously picked domino on the kingdom */
|
|
60
156
|
readonly placeDomino: "placeDomino";
|
|
157
|
+
/** Pick a domino from the revealed set */
|
|
61
158
|
readonly pickDomino: "pickDomino";
|
|
159
|
+
/** Pass/discard when no valid placement exists */
|
|
62
160
|
readonly pass: "pass";
|
|
63
161
|
};
|
|
162
|
+
/** Union type of all player actions */
|
|
64
163
|
type PlayerActions = ObjectValues<typeof playerActions>;
|
|
65
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Basic rules that vary based on player count.
|
|
167
|
+
*/
|
|
66
168
|
type BasicRules = {
|
|
169
|
+
/** Number of lords per player */
|
|
67
170
|
lords: number;
|
|
171
|
+
/** Maximum number of dominoes in the game */
|
|
68
172
|
maxDominoes: number;
|
|
173
|
+
/** Number of dominoes revealed each turn */
|
|
69
174
|
dominoesPerTurn: number;
|
|
175
|
+
/** Maximum number of turns in the game */
|
|
70
176
|
maxTurns: number;
|
|
177
|
+
/** Maximum kingdom grid size (5 for standard, 7 for Mighty Duel) */
|
|
178
|
+
maxKingdomSize: number;
|
|
71
179
|
};
|
|
180
|
+
/**
|
|
181
|
+
* Optional extra rules that modify gameplay and scoring.
|
|
182
|
+
*/
|
|
72
183
|
type ExtraRule = {
|
|
184
|
+
/** Name of the rule (e.g., "The middle Kingdom", "Harmony") */
|
|
73
185
|
name: string;
|
|
186
|
+
/** Description of what the rule does */
|
|
74
187
|
description: string;
|
|
188
|
+
/** Game modes this rule is compatible with */
|
|
75
189
|
mode: GameMode[];
|
|
190
|
+
/** Maximum number of players for this rule (optional) */
|
|
76
191
|
playersLimit?: number;
|
|
77
192
|
};
|
|
193
|
+
/**
|
|
194
|
+
* Complete rules configuration loaded from data source.
|
|
195
|
+
*/
|
|
78
196
|
type Rules = {
|
|
197
|
+
/** Basic rules indexed by player count (1-4) */
|
|
79
198
|
basic: Record<number, BasicRules>;
|
|
199
|
+
/** Available extra rules */
|
|
80
200
|
extraRules: ExtraRule[];
|
|
81
201
|
};
|
|
202
|
+
/**
|
|
203
|
+
* Rules selected for a specific game instance.
|
|
204
|
+
*/
|
|
82
205
|
type SelectedRules = {
|
|
206
|
+
/** The basic rules for the current player count */
|
|
83
207
|
basic: BasicRules;
|
|
208
|
+
/** Extra rules enabled for this game */
|
|
84
209
|
extra: ExtraRule[];
|
|
85
210
|
};
|
|
86
211
|
|
|
@@ -94,60 +219,147 @@ interface Err {
|
|
|
94
219
|
readonly error: string;
|
|
95
220
|
}
|
|
96
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Represents the complete state of a Kingdomino game.
|
|
224
|
+
* This is the main aggregate containing all game data.
|
|
225
|
+
*/
|
|
97
226
|
type Game = {
|
|
227
|
+
/** Unique identifier for the game */
|
|
98
228
|
id: string;
|
|
229
|
+
/** Remaining dominoes in the draw pile */
|
|
99
230
|
dominoes: Domino[];
|
|
231
|
+
/** Currently revealed dominoes available for picking */
|
|
100
232
|
currentDominoes: RevealsDomino[];
|
|
233
|
+
/** Players participating in the game with their kingdoms */
|
|
101
234
|
players: Player[];
|
|
235
|
+
/** Lords (player tokens) used for turn order and domino selection */
|
|
102
236
|
lords: Lord[];
|
|
237
|
+
/** Current turn number (1-based) */
|
|
103
238
|
turn: number;
|
|
239
|
+
/** Next required action or game step */
|
|
104
240
|
nextAction: NextAction | NextStep;
|
|
241
|
+
/** Active rules for this game */
|
|
105
242
|
rules: SelectedRules;
|
|
243
|
+
/** Game mode being played */
|
|
106
244
|
mode: GameMode;
|
|
245
|
+
/** Optional seed for deterministic shuffle (replays, sharing) */
|
|
246
|
+
seed?: string;
|
|
107
247
|
};
|
|
248
|
+
/**
|
|
249
|
+
* Available game steps representing phases of game setup and completion.
|
|
250
|
+
*/
|
|
108
251
|
declare const gameSteps: {
|
|
252
|
+
/** Waiting for players to be added */
|
|
109
253
|
readonly addPlayers: "addPlayers";
|
|
254
|
+
/** Optional rules selection phase */
|
|
110
255
|
readonly options: "options";
|
|
256
|
+
/** Ready to start the game */
|
|
111
257
|
readonly start: "start";
|
|
258
|
+
/** Game has ended, results available */
|
|
112
259
|
readonly result: "result";
|
|
113
260
|
};
|
|
261
|
+
/** Union type of all possible game steps */
|
|
114
262
|
type GameSteps = ObjectValues<typeof gameSteps>;
|
|
263
|
+
/**
|
|
264
|
+
* Represents a player action that needs to be performed.
|
|
265
|
+
* Used during active gameplay.
|
|
266
|
+
*/
|
|
115
267
|
type NextAction = {
|
|
268
|
+
/** Discriminator for action type */
|
|
116
269
|
type: "action";
|
|
270
|
+
/** ID of the lord who must perform the action */
|
|
117
271
|
nextLord: string;
|
|
272
|
+
/** The action the lord must perform */
|
|
118
273
|
nextAction: PlayerActions;
|
|
119
274
|
};
|
|
275
|
+
/**
|
|
276
|
+
* Represents a game phase transition.
|
|
277
|
+
* Used during setup and game end.
|
|
278
|
+
*/
|
|
120
279
|
type NextStep = {
|
|
280
|
+
/** Discriminator for step type */
|
|
121
281
|
type: "step";
|
|
282
|
+
/** The current game step/phase */
|
|
122
283
|
step: GameSteps;
|
|
123
284
|
};
|
|
285
|
+
/** Game state where a player action is required */
|
|
124
286
|
type GameWithNextAction = Game & {
|
|
125
287
|
nextAction: NextAction;
|
|
126
288
|
};
|
|
289
|
+
/** Game state where a phase transition is occurring */
|
|
127
290
|
type GameWithNextStep = Game & {
|
|
128
291
|
nextAction: NextStep;
|
|
129
292
|
};
|
|
293
|
+
/** Union of all possible game states */
|
|
130
294
|
type GameState = GameWithNextAction | GameWithNextStep;
|
|
295
|
+
/** Result wrapper for game state operations */
|
|
131
296
|
type GameStateResult = Result<GameState>;
|
|
297
|
+
/**
|
|
298
|
+
* Type guard to check if the game requires a player action.
|
|
299
|
+
* @param game - The game state to check
|
|
300
|
+
* @returns True if the game is waiting for a player action
|
|
301
|
+
*/
|
|
132
302
|
declare const isGameWithNextAction: (game: GameWithNextAction | GameWithNextStep) => game is GameWithNextAction;
|
|
303
|
+
/**
|
|
304
|
+
* Type guard to check if the game is in a phase transition.
|
|
305
|
+
* @param game - The game state to check
|
|
306
|
+
* @returns True if the game is transitioning between phases
|
|
307
|
+
*/
|
|
133
308
|
declare const isGameWithNextStep: (game: GameWithNextAction | GameWithNextStep) => game is GameWithNextStep;
|
|
309
|
+
/**
|
|
310
|
+
* Represents the score calculation for a kingdom.
|
|
311
|
+
*/
|
|
134
312
|
type Score = {
|
|
313
|
+
/** Total points earned */
|
|
135
314
|
points: number;
|
|
315
|
+
/** Size of the largest contiguous property */
|
|
136
316
|
maxPropertiesSize: number;
|
|
317
|
+
/** Total number of crowns in the kingdom */
|
|
137
318
|
totalCrowns: number;
|
|
138
319
|
};
|
|
320
|
+
/**
|
|
321
|
+
* Score result for a specific player.
|
|
322
|
+
*/
|
|
139
323
|
type ScoreResult = {
|
|
324
|
+
/** Player's unique identifier */
|
|
140
325
|
playerId: string;
|
|
326
|
+
/** Player's display name */
|
|
141
327
|
playerName: string;
|
|
328
|
+
/** Detailed score breakdown */
|
|
142
329
|
details: Score;
|
|
143
330
|
};
|
|
331
|
+
/**
|
|
332
|
+
* Final result including ranking position.
|
|
333
|
+
*/
|
|
144
334
|
type FinalResult = ScoreResult & {
|
|
335
|
+
/** Player's final position (1 = winner) */
|
|
145
336
|
position: number;
|
|
146
337
|
};
|
|
338
|
+
/** Game state with final results calculated */
|
|
147
339
|
type GameWithResults = Game & {
|
|
148
340
|
result: FinalResult[];
|
|
149
341
|
};
|
|
150
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Severity level for a validation issue.
|
|
345
|
+
* - "error": The state is corrupted and cannot be used safely.
|
|
346
|
+
* - "warning": The state is suspicious but may still work.
|
|
347
|
+
*/
|
|
348
|
+
type ValidationSeverity = "error" | "warning";
|
|
349
|
+
/**
|
|
350
|
+
* Describes a single validation issue found in a game state.
|
|
351
|
+
*/
|
|
352
|
+
type ValidationIssue = {
|
|
353
|
+
/** JSON-path-like location of the issue (e.g. "players[0].kingdom") */
|
|
354
|
+
path: string;
|
|
355
|
+
/** Machine-readable code identifying the kind of issue */
|
|
356
|
+
code: string;
|
|
357
|
+
/** Human-readable description of the issue */
|
|
358
|
+
message: string;
|
|
359
|
+
/** Severity level */
|
|
360
|
+
severity: ValidationSeverity;
|
|
361
|
+
};
|
|
362
|
+
|
|
151
363
|
type GetModesCommand = Record<string, never>;
|
|
152
364
|
|
|
153
365
|
type GetExtraRulesCommand = {
|
|
@@ -157,11 +369,21 @@ type GetExtraRulesCommand = {
|
|
|
157
369
|
|
|
158
370
|
type CreateGameCommand = {
|
|
159
371
|
mode: string;
|
|
372
|
+
seed?: string;
|
|
160
373
|
};
|
|
161
374
|
|
|
375
|
+
/**
|
|
376
|
+
* Input for a single player: either a name string (human) or an object with bot config.
|
|
377
|
+
*/
|
|
378
|
+
type PlayerInput = string | {
|
|
379
|
+
name: string;
|
|
380
|
+
bot?: {
|
|
381
|
+
strategyName: string;
|
|
382
|
+
};
|
|
383
|
+
};
|
|
162
384
|
type AddPlayersCommand = {
|
|
163
385
|
game: GameState;
|
|
164
|
-
players:
|
|
386
|
+
players: PlayerInput[];
|
|
165
387
|
};
|
|
166
388
|
|
|
167
389
|
type AddExtraRulesCommand = {
|
|
@@ -199,30 +421,943 @@ type CalculateScoreCommand = {
|
|
|
199
421
|
kingdom: Kingdom;
|
|
200
422
|
};
|
|
201
423
|
|
|
424
|
+
/**
|
|
425
|
+
* Command to get all valid placements for a domino on a kingdom.
|
|
426
|
+
*/
|
|
427
|
+
type GetValidPlacementsCommand = {
|
|
428
|
+
/** The kingdom grid to check placements on */
|
|
429
|
+
kingdom: Kingdom;
|
|
430
|
+
/** The domino to find placements for */
|
|
431
|
+
domino: Domino;
|
|
432
|
+
/** Maximum kingdom size (default: 5, use 7 for Mighty Duel) */
|
|
433
|
+
maxKingdomSize?: number;
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Command to check if a domino can be placed anywhere on a kingdom.
|
|
438
|
+
*/
|
|
439
|
+
type CanPlaceDominoCommand = {
|
|
440
|
+
/** The kingdom grid to check */
|
|
441
|
+
kingdom: Kingdom;
|
|
442
|
+
/** The domino to check placement for */
|
|
443
|
+
domino: Domino;
|
|
444
|
+
/** Maximum kingdom size (default: 5, use 7 for Mighty Duel) */
|
|
445
|
+
maxKingdomSize?: number;
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Command to serialize a game state to JSON.
|
|
450
|
+
*/
|
|
451
|
+
type SerializeGameCommand = {
|
|
452
|
+
/** The game state to serialize */
|
|
453
|
+
game: GameState;
|
|
454
|
+
};
|
|
455
|
+
/**
|
|
456
|
+
* Command to deserialize a game state from JSON.
|
|
457
|
+
*/
|
|
458
|
+
type DeserializeGameCommand = {
|
|
459
|
+
/** The JSON string to deserialize */
|
|
460
|
+
json: string;
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
type GetDynastyResultCommand = {
|
|
464
|
+
games: GameWithResults[];
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Represents a valid placement position with rotation.
|
|
469
|
+
*/
|
|
470
|
+
type ValidPlacement = {
|
|
471
|
+
position: Position;
|
|
472
|
+
rotation: Rotation;
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
type DynastyResult = {
|
|
476
|
+
playerId: string;
|
|
477
|
+
playerName: string;
|
|
478
|
+
totalPoints: number;
|
|
479
|
+
gamesPoints: number[];
|
|
480
|
+
position: number;
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* The main interface for interacting with the Kingdomino game engine.
|
|
485
|
+
*
|
|
486
|
+
* This interface provides all methods needed to manage a complete game lifecycle,
|
|
487
|
+
* from creation to scoring. Each method follows a command pattern and returns
|
|
488
|
+
* an updated game state.
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```typescript
|
|
492
|
+
* import { createGameEngine, isGameWithNextAction } from '@pompidup/kingdomino-engine';
|
|
493
|
+
*
|
|
494
|
+
* const engine = createGameEngine({});
|
|
495
|
+
* let game = engine.createGame({ mode: 'Classic' });
|
|
496
|
+
* game = engine.addPlayers({ game, players: ['Alice', 'Bob'] });
|
|
497
|
+
* game = engine.startGame({ game });
|
|
498
|
+
*
|
|
499
|
+
* while (isGameWithNextAction(game)) {
|
|
500
|
+
* // Handle player actions...
|
|
501
|
+
* }
|
|
502
|
+
*
|
|
503
|
+
* const results = engine.getResults({ game });
|
|
504
|
+
* ```
|
|
505
|
+
*/
|
|
202
506
|
type GameEngine = {
|
|
507
|
+
/**
|
|
508
|
+
* Retrieves all available game modes.
|
|
509
|
+
* @param command - Empty command object
|
|
510
|
+
* @returns Array of available game modes (e.g., 'Classic')
|
|
511
|
+
*/
|
|
203
512
|
getModes: (command: GetModesCommand) => GameMode[];
|
|
513
|
+
/**
|
|
514
|
+
* Retrieves available extra rules for a specific mode and player count.
|
|
515
|
+
* @param command - Contains mode name and number of players
|
|
516
|
+
* @returns Array of applicable extra rules
|
|
517
|
+
*/
|
|
204
518
|
getExtraRules: (command: GetExtraRulesCommand) => ExtraRule[];
|
|
519
|
+
/**
|
|
520
|
+
* Creates a new game instance with the specified mode.
|
|
521
|
+
* This is the first step in setting up a game.
|
|
522
|
+
* @param command - Contains the game mode name
|
|
523
|
+
* @returns Game state with next step 'addPlayers'
|
|
524
|
+
*/
|
|
205
525
|
createGame: (command: CreateGameCommand) => GameWithNextStep;
|
|
526
|
+
/**
|
|
527
|
+
* Adds players to the game and initializes their kingdoms.
|
|
528
|
+
* Each player receives an empty kingdom with a castle at the center.
|
|
529
|
+
* @param command - Contains game state and array of player names (1-4 players)
|
|
530
|
+
* @returns Game state with next step 'options' or 'start'
|
|
531
|
+
* @throws Error if player count is invalid or names are too short
|
|
532
|
+
*/
|
|
206
533
|
addPlayers: (command: AddPlayersCommand) => GameWithNextStep;
|
|
534
|
+
/**
|
|
535
|
+
* Adds optional extra rules to modify gameplay.
|
|
536
|
+
* @param command - Contains game state and array of extra rule names
|
|
537
|
+
* @returns Game state with next step 'start'
|
|
538
|
+
*/
|
|
207
539
|
addExtraRules: (command: AddExtraRulesCommand) => GameWithNextStep;
|
|
540
|
+
/**
|
|
541
|
+
* Starts the game, initializing lords, shuffling dominoes, and revealing the first set.
|
|
542
|
+
* @param command - Contains the game state
|
|
543
|
+
* @returns Game state with first player action required
|
|
544
|
+
*/
|
|
208
545
|
startGame: (command: StartGameCommand) => GameWithNextAction;
|
|
546
|
+
/**
|
|
547
|
+
* Allows a lord to choose a domino from the currently revealed set.
|
|
548
|
+
* The chosen domino is reserved for that lord to place later.
|
|
549
|
+
* @param command - Contains game state, lord ID, and domino number to pick
|
|
550
|
+
* @returns Updated game state with next action
|
|
551
|
+
*/
|
|
209
552
|
chooseDomino: (command: ChooseDominoCommand) => GameWithNextAction;
|
|
553
|
+
/**
|
|
554
|
+
* Places a domino on the lord's kingdom at the specified position and rotation.
|
|
555
|
+
* The domino must be adjacent to an existing tile and match terrain types.
|
|
556
|
+
* @param command - Contains game state, lord ID, position {x, y}, and rotation (0, 90, 180, 270)
|
|
557
|
+
* @returns Updated game state (may transition to 'result' step if game ends)
|
|
558
|
+
* @throws Error if placement is invalid
|
|
559
|
+
*/
|
|
210
560
|
placeDomino: (command: PlaceDominoCommand) => GameState;
|
|
561
|
+
/**
|
|
562
|
+
* Discards a domino when no valid placement exists.
|
|
563
|
+
* The lord forfeits placing the domino this turn.
|
|
564
|
+
* @param command - Contains game state and lord ID
|
|
565
|
+
* @returns Updated game state with next action
|
|
566
|
+
*/
|
|
211
567
|
discardDomino: (command: DiscardDominoCommand) => GameState;
|
|
568
|
+
/**
|
|
569
|
+
* Calculates and returns final results after the game ends.
|
|
570
|
+
* Applies extra rule bonuses and ranks players.
|
|
571
|
+
* @param command - Contains the final game state
|
|
572
|
+
* @returns Game state with complete results including positions
|
|
573
|
+
*/
|
|
212
574
|
getResults: (command: GetResultCommand) => GameWithResults;
|
|
575
|
+
/**
|
|
576
|
+
* Calculates the score for a single kingdom.
|
|
577
|
+
* Useful for showing live scores during gameplay.
|
|
578
|
+
* @param command - Contains the kingdom grid to score
|
|
579
|
+
* @returns Score with points, largest property size, and total crowns
|
|
580
|
+
*/
|
|
213
581
|
calculateScore: (command: CalculateScoreCommand) => Score;
|
|
582
|
+
/**
|
|
583
|
+
* Finds all valid placements for a domino on a kingdom.
|
|
584
|
+
* Useful for AI players or showing available moves to human players.
|
|
585
|
+
* @param command - Contains kingdom and domino to check
|
|
586
|
+
* @returns Array of valid position/rotation combinations
|
|
587
|
+
*/
|
|
588
|
+
getValidPlacements: (command: GetValidPlacementsCommand) => ValidPlacement[];
|
|
589
|
+
/**
|
|
590
|
+
* Checks if a domino can be placed anywhere on a kingdom.
|
|
591
|
+
* Quick check before deciding to discard.
|
|
592
|
+
* @param command - Contains kingdom and domino to check
|
|
593
|
+
* @returns True if at least one valid placement exists
|
|
594
|
+
*/
|
|
595
|
+
canPlaceDomino: (command: CanPlaceDominoCommand) => boolean;
|
|
596
|
+
/**
|
|
597
|
+
* Serializes the game state to a JSON string for persistence.
|
|
598
|
+
* @param command - Contains the game state to serialize
|
|
599
|
+
* @returns JSON string representation of the game
|
|
600
|
+
*/
|
|
601
|
+
serialize: (command: SerializeGameCommand) => string;
|
|
602
|
+
/**
|
|
603
|
+
* Deserializes a JSON string back to a game state.
|
|
604
|
+
* @param command - Contains the JSON string to parse
|
|
605
|
+
* @returns The restored game state
|
|
606
|
+
* @throws Error if the JSON is invalid or incompatible
|
|
607
|
+
*/
|
|
608
|
+
deserialize: (command: DeserializeGameCommand) => GameState;
|
|
609
|
+
/**
|
|
610
|
+
* Calculates dynasty results from multiple completed games.
|
|
611
|
+
* Sum total points across games, highest total wins.
|
|
612
|
+
* @param command - Contains array of completed games with results
|
|
613
|
+
* @returns Ranked dynasty results per player
|
|
614
|
+
*/
|
|
615
|
+
getDynastyResults: (command: GetDynastyResultCommand) => DynastyResult[];
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Error codes for domain-level errors.
|
|
620
|
+
* These codes can be used for i18n and programmatic error handling.
|
|
621
|
+
*/
|
|
622
|
+
declare const ErrorCode: {
|
|
623
|
+
readonly INVALID_STEP: "INVALID_STEP";
|
|
624
|
+
readonly STEP_EXECUTION_FAILED: "STEP_EXECUTION_FAILED";
|
|
625
|
+
readonly ACTION_EXECUTION_FAILED: "ACTION_EXECUTION_FAILED";
|
|
626
|
+
readonly LORD_NOT_FOUND: "LORD_NOT_FOUND";
|
|
627
|
+
readonly PLAYER_NOT_FOUND: "PLAYER_NOT_FOUND";
|
|
628
|
+
readonly DOMINO_NOT_FOUND: "DOMINO_NOT_FOUND";
|
|
629
|
+
readonly MODE_NOT_FOUND: "MODE_NOT_FOUND";
|
|
630
|
+
readonly INVALID_PLAYER_COUNT: "INVALID_PLAYER_COUNT";
|
|
631
|
+
readonly INVALID_PLAYER_NAME: "INVALID_PLAYER_NAME";
|
|
632
|
+
readonly INVALID_PLACEMENT: "INVALID_PLACEMENT";
|
|
633
|
+
readonly PLACEMENT_NOT_EMPTY: "PLACEMENT_NOT_EMPTY";
|
|
634
|
+
readonly PLACEMENT_NOT_ADJACENT: "PLACEMENT_NOT_ADJACENT";
|
|
635
|
+
readonly PLACEMENT_INVALID_TERRAIN: "PLACEMENT_INVALID_TERRAIN";
|
|
636
|
+
readonly PLACEMENT_OUT_OF_BOUNDS: "PLACEMENT_OUT_OF_BOUNDS";
|
|
637
|
+
readonly PLACEMENT_EXCEEDS_KINGDOM_SIZE: "PLACEMENT_EXCEEDS_KINGDOM_SIZE";
|
|
638
|
+
readonly NOT_YOUR_TURN: "NOT_YOUR_TURN";
|
|
639
|
+
readonly CANNOT_PICK: "CANNOT_PICK";
|
|
640
|
+
readonly CANNOT_PLACE: "CANNOT_PLACE";
|
|
641
|
+
readonly DOMINO_ALREADY_PICKED: "DOMINO_ALREADY_PICKED";
|
|
642
|
+
readonly UNDO_UNAVAILABLE: "UNDO_UNAVAILABLE";
|
|
643
|
+
readonly REDO_UNAVAILABLE: "REDO_UNAVAILABLE";
|
|
644
|
+
};
|
|
645
|
+
type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode];
|
|
646
|
+
/**
|
|
647
|
+
* Structured domain error with code and context.
|
|
648
|
+
*/
|
|
649
|
+
interface DomainError {
|
|
650
|
+
/** Error code for programmatic handling */
|
|
651
|
+
code: ErrorCodeType;
|
|
652
|
+
/** Human-readable error message */
|
|
653
|
+
message: string;
|
|
654
|
+
/** Optional context data for debugging */
|
|
655
|
+
context?: Record<string, unknown>;
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Creates a domain error object.
|
|
659
|
+
*/
|
|
660
|
+
declare const createDomainError: (code: ErrorCodeType, message: string, context?: Record<string, unknown>) => DomainError;
|
|
661
|
+
/**
|
|
662
|
+
* Base class for domain errors thrown by handlers.
|
|
663
|
+
*/
|
|
664
|
+
declare class DomainException extends Error {
|
|
665
|
+
readonly code: ErrorCodeType;
|
|
666
|
+
readonly context?: Record<string, unknown>;
|
|
667
|
+
constructor(error: DomainError);
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Error thrown when the game is in an invalid step for the requested action.
|
|
671
|
+
*/
|
|
672
|
+
declare class InvalidStepError extends DomainException {
|
|
673
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Error thrown when a step execution fails.
|
|
677
|
+
*/
|
|
678
|
+
declare class StepExecutionError extends DomainException {
|
|
679
|
+
constructor(message: string, code?: ErrorCodeType, context?: Record<string, unknown>);
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Error thrown when an action execution fails.
|
|
683
|
+
*/
|
|
684
|
+
declare class ActionExecutionError extends DomainException {
|
|
685
|
+
constructor(message: string, code?: ErrorCodeType, context?: Record<string, unknown>);
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Error thrown when a required entity is not found.
|
|
689
|
+
*/
|
|
690
|
+
declare class NotFoundError extends DomainException {
|
|
691
|
+
constructor(message: string, code?: ErrorCodeType, context?: Record<string, unknown>);
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Error thrown when validation fails.
|
|
695
|
+
*/
|
|
696
|
+
declare class ValidationError extends DomainException {
|
|
697
|
+
constructor(message: string, code: ErrorCodeType, context?: Record<string, unknown>);
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Error thrown when undo is requested but no previous state exists.
|
|
701
|
+
*/
|
|
702
|
+
declare class UndoError extends DomainException {
|
|
703
|
+
constructor(message?: string, context?: Record<string, unknown>);
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Error thrown when redo is requested but no future state exists.
|
|
707
|
+
*/
|
|
708
|
+
declare class RedoError extends DomainException {
|
|
709
|
+
constructor(message?: string, context?: Record<string, unknown>);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Translation keys for internationalization support.
|
|
714
|
+
* Use these keys instead of hardcoded strings for translatable content.
|
|
715
|
+
*/
|
|
716
|
+
declare const TranslationKey: {
|
|
717
|
+
readonly ERROR_INVALID_STEP: "error.invalidStep";
|
|
718
|
+
readonly ERROR_STEP_EXECUTION_FAILED: "error.stepExecutionFailed";
|
|
719
|
+
readonly ERROR_ACTION_EXECUTION_FAILED: "error.actionExecutionFailed";
|
|
720
|
+
readonly ERROR_LORD_NOT_FOUND: "error.lordNotFound";
|
|
721
|
+
readonly ERROR_PLAYER_NOT_FOUND: "error.playerNotFound";
|
|
722
|
+
readonly ERROR_DOMINO_NOT_FOUND: "error.dominoNotFound";
|
|
723
|
+
readonly ERROR_MODE_NOT_FOUND: "error.modeNotFound";
|
|
724
|
+
readonly ERROR_INVALID_PLACEMENT: "error.invalidPlacement";
|
|
725
|
+
readonly ERROR_PLACEMENT_NOT_EMPTY: "error.placementNotEmpty";
|
|
726
|
+
readonly ERROR_PLACEMENT_NOT_ADJACENT: "error.placementNotAdjacent";
|
|
727
|
+
readonly ERROR_PLACEMENT_INVALID_TERRAIN: "error.placementInvalidTerrain";
|
|
728
|
+
readonly ERROR_PLACEMENT_OUT_OF_BOUNDS: "error.placementOutOfBounds";
|
|
729
|
+
readonly ERROR_PLACEMENT_EXCEEDS_KINGDOM_SIZE: "error.placementExceedsKingdomSize";
|
|
730
|
+
readonly ERROR_NOT_YOUR_TURN: "error.notYourTurn";
|
|
731
|
+
readonly ERROR_CANNOT_PICK: "error.cannotPick";
|
|
732
|
+
readonly ERROR_CANNOT_PLACE: "error.cannotPlace";
|
|
733
|
+
readonly ERROR_DOMINO_ALREADY_PICKED: "error.dominoAlreadyPicked";
|
|
734
|
+
readonly ERROR_INVALID_PLAYER_COUNT: "error.invalidPlayerCount";
|
|
735
|
+
readonly ERROR_INVALID_PLAYER_NAME: "error.invalidPlayerName";
|
|
736
|
+
readonly ERROR_UNDO_UNAVAILABLE: "error.undoUnavailable";
|
|
737
|
+
readonly ERROR_REDO_UNAVAILABLE: "error.redoUnavailable";
|
|
738
|
+
readonly MODE_CLASSIC: "mode.classic";
|
|
739
|
+
readonly RULE_MIDDLE_KINGDOM: "rule.middleKingdom";
|
|
740
|
+
readonly RULE_HARMONY: "rule.harmony";
|
|
741
|
+
readonly GROUND_CASTLE: "ground.castle";
|
|
742
|
+
readonly GROUND_WHEAT: "ground.wheat";
|
|
743
|
+
readonly GROUND_FOREST: "ground.forest";
|
|
744
|
+
readonly GROUND_SEA: "ground.sea";
|
|
745
|
+
readonly GROUND_PLAIN: "ground.plain";
|
|
746
|
+
readonly GROUND_SWAMP: "ground.swamp";
|
|
747
|
+
readonly GROUND_MINE: "ground.mine";
|
|
748
|
+
readonly PHASE_ADD_PLAYERS: "phase.addPlayers";
|
|
749
|
+
readonly PHASE_OPTIONS: "phase.options";
|
|
750
|
+
readonly PHASE_START: "phase.start";
|
|
751
|
+
readonly PHASE_RESULT: "phase.result";
|
|
752
|
+
readonly ACTION_PICK_DOMINO: "action.pickDomino";
|
|
753
|
+
readonly ACTION_PLACE_DOMINO: "action.placeDomino";
|
|
754
|
+
readonly ACTION_PASS: "action.pass";
|
|
214
755
|
};
|
|
756
|
+
type TranslationKeyType = (typeof TranslationKey)[keyof typeof TranslationKey];
|
|
757
|
+
/**
|
|
758
|
+
* Default English translations.
|
|
759
|
+
*/
|
|
760
|
+
declare const defaultTranslations: Record<TranslationKeyType, string>;
|
|
761
|
+
/**
|
|
762
|
+
* Maps ErrorCode values to their corresponding TranslationKey values.
|
|
763
|
+
* Used by handlers to translate error codes into localized messages.
|
|
764
|
+
*/
|
|
765
|
+
declare const errorCodeToTranslationKey: Record<ErrorCodeType, TranslationKeyType>;
|
|
766
|
+
/**
|
|
767
|
+
* Translates an error code to a localized message.
|
|
768
|
+
* Convenience function combining errorCodeToTranslationKey lookup and translation.
|
|
769
|
+
*/
|
|
770
|
+
declare const translateErrorCode: (translator: Translator, code: ErrorCodeType, params?: Record<string, string | number>) => string;
|
|
771
|
+
/**
|
|
772
|
+
* Translator interface for custom translations.
|
|
773
|
+
*/
|
|
774
|
+
interface Translator {
|
|
775
|
+
/**
|
|
776
|
+
* Translate a key to the current language.
|
|
777
|
+
* @param key - The translation key
|
|
778
|
+
* @param params - Optional parameters for interpolation
|
|
779
|
+
* @returns The translated string
|
|
780
|
+
*/
|
|
781
|
+
t(key: TranslationKeyType, params?: Record<string, string | number>): string;
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Creates a translator with the provided translations.
|
|
785
|
+
* Falls back to default English translations for missing keys.
|
|
786
|
+
*
|
|
787
|
+
* @param translations - Custom translations to use
|
|
788
|
+
* @returns A translator instance
|
|
789
|
+
*/
|
|
790
|
+
declare const createTranslator: (translations?: Partial<Record<TranslationKeyType, string>>) => Translator;
|
|
791
|
+
/**
|
|
792
|
+
* Default translator using English translations.
|
|
793
|
+
*/
|
|
794
|
+
declare const defaultTranslator: Translator;
|
|
795
|
+
|
|
796
|
+
type Logger = Readonly<{
|
|
797
|
+
info: (message: string) => void;
|
|
798
|
+
error: (message: string) => void;
|
|
799
|
+
}>;
|
|
215
800
|
|
|
216
801
|
type ShuffleMethod = <T>(array: T[]) => T[];
|
|
217
802
|
|
|
218
803
|
type UuidMethod = () => string;
|
|
219
804
|
|
|
805
|
+
/**
|
|
806
|
+
* Debug log verbosity level.
|
|
807
|
+
* - `minimal`: method name + phase only
|
|
808
|
+
* - `standard`: + game state summary + key params
|
|
809
|
+
* - `verbose`: + full game state JSON dump
|
|
810
|
+
*/
|
|
811
|
+
type DebugLogLevel = "minimal" | "standard" | "verbose";
|
|
812
|
+
/**
|
|
813
|
+
* Summary of the current game state, extracted for quick inspection.
|
|
814
|
+
*/
|
|
815
|
+
type GameStateSummary = {
|
|
816
|
+
gameId: string;
|
|
817
|
+
turn: number;
|
|
818
|
+
nextAction: string;
|
|
819
|
+
playersCount: number;
|
|
820
|
+
dominoesRemaining: number;
|
|
821
|
+
currentDominoesCount: number;
|
|
822
|
+
lordsCount: number;
|
|
823
|
+
};
|
|
824
|
+
/**
|
|
825
|
+
* A single debug log entry emitted by the debug wrapper.
|
|
826
|
+
*/
|
|
827
|
+
type DebugLogEntry = {
|
|
828
|
+
timestamp: string;
|
|
829
|
+
method: string;
|
|
830
|
+
phase: "before" | "after" | "error";
|
|
831
|
+
summary: GameStateSummary | null;
|
|
832
|
+
params?: Record<string, unknown>;
|
|
833
|
+
error?: string;
|
|
834
|
+
durationMs?: number;
|
|
835
|
+
fullState?: GameState;
|
|
836
|
+
};
|
|
837
|
+
/**
|
|
838
|
+
* Custom debug logger interface.
|
|
839
|
+
* Consumers can provide their own to redirect debug output.
|
|
840
|
+
*/
|
|
841
|
+
type DebugLogger = {
|
|
842
|
+
log: (entry: DebugLogEntry) => void;
|
|
843
|
+
};
|
|
844
|
+
/**
|
|
845
|
+
* Configuration for the debug wrapper.
|
|
846
|
+
*/
|
|
847
|
+
type DebugOptions = {
|
|
848
|
+
/** Custom debug logger. Defaults to console-based logger. */
|
|
849
|
+
logger?: DebugLogger;
|
|
850
|
+
/** Verbosity level. Defaults to "standard". */
|
|
851
|
+
level?: DebugLogLevel;
|
|
852
|
+
};
|
|
853
|
+
/**
|
|
854
|
+
* Extracts a concise summary from a game state object.
|
|
855
|
+
*/
|
|
856
|
+
declare const summarizeGameState: (game: GameState) => GameStateSummary;
|
|
857
|
+
/**
|
|
858
|
+
* Wraps a GameEngine to emit detailed debug log entries before and after each method call.
|
|
859
|
+
* Useful for UI developers to inspect engine behavior at every step.
|
|
860
|
+
*
|
|
861
|
+
* @param engine - The base game engine to wrap
|
|
862
|
+
* @param options - Debug configuration (logger, verbosity level)
|
|
863
|
+
* @returns A new GameEngine that emits debug logs
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```typescript
|
|
867
|
+
* const debugEngine = wrapWithDebug(engine, { level: "verbose" });
|
|
868
|
+
* let game = debugEngine.createGame({ mode: "Classic" });
|
|
869
|
+
* // Console: [KDomino:Debug] ... BEFORE createGame
|
|
870
|
+
* // Console: [KDomino:Debug] ... AFTER createGame | turn=0 ...
|
|
871
|
+
* ```
|
|
872
|
+
*/
|
|
873
|
+
declare const wrapWithDebug: (engine: GameEngine, options?: DebugOptions) => GameEngine;
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Optional callbacks for game events.
|
|
877
|
+
* Consumers provide these to react to state changes (UI updates, animations, logging).
|
|
878
|
+
* All callbacks are optional — only the ones you provide will be called.
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```typescript
|
|
882
|
+
* const engine = createGameEngine({
|
|
883
|
+
* events: {
|
|
884
|
+
* onDominoPlaced: ({ game, lordId }) => {
|
|
885
|
+
* console.log(`Lord ${lordId} placed a domino`);
|
|
886
|
+
* animatePlacement(game);
|
|
887
|
+
* },
|
|
888
|
+
* onTurnEnd: ({ turn }) => console.log(`Turn ${turn} ended`),
|
|
889
|
+
* onGameEnd: () => showResultsScreen(),
|
|
890
|
+
* },
|
|
891
|
+
* });
|
|
892
|
+
* ```
|
|
893
|
+
*/
|
|
894
|
+
type GameEventCallbacks = {
|
|
895
|
+
/** Called after a new game is created */
|
|
896
|
+
onGameCreated?: (event: {
|
|
897
|
+
game: GameWithNextStep;
|
|
898
|
+
}) => void;
|
|
899
|
+
/** Called after players are added to the game */
|
|
900
|
+
onPlayersAdded?: (event: {
|
|
901
|
+
game: GameWithNextStep;
|
|
902
|
+
}) => void;
|
|
903
|
+
/** Called after the game starts (first dominoes revealed) */
|
|
904
|
+
onGameStarted?: (event: {
|
|
905
|
+
game: GameWithNextAction;
|
|
906
|
+
}) => void;
|
|
907
|
+
/** Called after a lord picks a domino */
|
|
908
|
+
onDominoPicked?: (event: {
|
|
909
|
+
game: GameState;
|
|
910
|
+
lordId: string;
|
|
911
|
+
dominoNumber: number;
|
|
912
|
+
}) => void;
|
|
913
|
+
/** Called after a lord places a domino on their kingdom */
|
|
914
|
+
onDominoPlaced?: (event: {
|
|
915
|
+
game: GameState;
|
|
916
|
+
lordId: string;
|
|
917
|
+
}) => void;
|
|
918
|
+
/** Called after a lord discards a domino (no valid placement) */
|
|
919
|
+
onDominoDiscarded?: (event: {
|
|
920
|
+
game: GameState;
|
|
921
|
+
lordId: string;
|
|
922
|
+
}) => void;
|
|
923
|
+
/** Called when a new turn begins */
|
|
924
|
+
onTurnStart?: (event: {
|
|
925
|
+
game: GameState;
|
|
926
|
+
turn: number;
|
|
927
|
+
}) => void;
|
|
928
|
+
/** Called when a turn ends (all lords have played) */
|
|
929
|
+
onTurnEnd?: (event: {
|
|
930
|
+
game: GameState;
|
|
931
|
+
turn: number;
|
|
932
|
+
}) => void;
|
|
933
|
+
/** Called when the game reaches the result phase */
|
|
934
|
+
onGameEnd?: (event: {
|
|
935
|
+
game: GameState;
|
|
936
|
+
}) => void;
|
|
937
|
+
};
|
|
938
|
+
/**
|
|
939
|
+
* Wraps a GameEngine to emit event callbacks after each state-changing method.
|
|
940
|
+
* Read-only methods (getModes, calculateScore, etc.) are passed through unchanged.
|
|
941
|
+
*
|
|
942
|
+
* Derived events:
|
|
943
|
+
* - `onTurnEnd` + `onTurnStart`: emitted when `chooseDomino` causes a turn increment
|
|
944
|
+
* - `onGameEnd`: emitted when `placeDomino` or `discardDomino` transitions to the "result" step
|
|
945
|
+
*
|
|
946
|
+
* @param engine - The base game engine to wrap
|
|
947
|
+
* @param callbacks - Optional event callbacks
|
|
948
|
+
* @returns A new GameEngine that emits events
|
|
949
|
+
*/
|
|
950
|
+
declare const wrapWithEvents: (engine: GameEngine, callbacks: GameEventCallbacks) => GameEngine;
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* Configuration options for the game engine.
|
|
954
|
+
*/
|
|
220
955
|
type EngineConfig = {
|
|
956
|
+
/** Custom UUID generation method. Defaults to crypto.randomUUID() */
|
|
221
957
|
uuidMethod?: UuidMethod;
|
|
958
|
+
/** Custom shuffle method. Defaults to Fisher-Yates algorithm */
|
|
222
959
|
shuffleMethod?: ShuffleMethod;
|
|
960
|
+
/** Enable console logging. Defaults to false */
|
|
223
961
|
logging?: boolean;
|
|
962
|
+
/** Custom logger instance. When provided, takes precedence over 'logging' option */
|
|
963
|
+
logger?: Logger;
|
|
964
|
+
/** Optional event callbacks for UI/animation integration */
|
|
965
|
+
events?: GameEventCallbacks;
|
|
966
|
+
/** Custom translator for i18n error messages. Defaults to English */
|
|
967
|
+
translator?: Translator;
|
|
968
|
+
/** Enable debug mode with detailed logging. Pass `true` for defaults or a `DebugOptions` object. */
|
|
969
|
+
debug?: boolean | DebugOptions;
|
|
970
|
+
};
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* Validates the integrity of a game state.
|
|
974
|
+
*
|
|
975
|
+
* Use this function after deserializing or restoring a persisted game state
|
|
976
|
+
* to detect corruptions before resuming gameplay.
|
|
977
|
+
*
|
|
978
|
+
* @param game - The game state to validate
|
|
979
|
+
* @returns An array of validation issues. Empty array means the state is valid.
|
|
980
|
+
*
|
|
981
|
+
* @example
|
|
982
|
+
* ```typescript
|
|
983
|
+
* const issues = validateGameState(game);
|
|
984
|
+
* if (issues.length > 0) {
|
|
985
|
+
* console.error("Game state is corrupted:", issues);
|
|
986
|
+
* }
|
|
987
|
+
* ```
|
|
988
|
+
*/
|
|
989
|
+
declare const validateGameState: (game: Game) => ValidationIssue[];
|
|
990
|
+
|
|
991
|
+
type DominoesRepository = {
|
|
992
|
+
getForMode: (mode: GameMode) => Domino[] | [];
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
type ModeRepository = {
|
|
996
|
+
getAvailables: () => GameMode[];
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
type RuleRepository = {
|
|
1000
|
+
getAll: () => Rules;
|
|
1001
|
+
getAllExtra: () => ExtraRule[];
|
|
224
1002
|
};
|
|
225
1003
|
|
|
1004
|
+
/**
|
|
1005
|
+
* Context provided to a bot strategy when choosing a domino to pick.
|
|
1006
|
+
*/
|
|
1007
|
+
type PickContext = {
|
|
1008
|
+
game: GameWithNextAction;
|
|
1009
|
+
lordId: string;
|
|
1010
|
+
availableDominoes: RevealsDomino[];
|
|
1011
|
+
};
|
|
1012
|
+
/**
|
|
1013
|
+
* Context provided to a bot strategy when choosing where to place a domino.
|
|
1014
|
+
*/
|
|
1015
|
+
type PlaceContext = {
|
|
1016
|
+
game: GameWithNextAction;
|
|
1017
|
+
lordId: string;
|
|
1018
|
+
domino: Domino;
|
|
1019
|
+
kingdom: Kingdom;
|
|
1020
|
+
validPlacements: ValidPlacement[];
|
|
1021
|
+
};
|
|
1022
|
+
/**
|
|
1023
|
+
* A bot strategy that decides which domino to pick and where to place it.
|
|
1024
|
+
* Strategies are stateless — all information comes from the context.
|
|
1025
|
+
*/
|
|
1026
|
+
type BotStrategy = {
|
|
1027
|
+
chooseDomino: (context: PickContext) => number;
|
|
1028
|
+
choosePlacement: (context: PlaceContext) => ValidPlacement | null;
|
|
1029
|
+
};
|
|
1030
|
+
/**
|
|
1031
|
+
* Bot strategy that makes random choices.
|
|
1032
|
+
* Picks a random available domino and places it at a random valid position.
|
|
1033
|
+
*/
|
|
1034
|
+
declare const randomStrategy: BotStrategy;
|
|
1035
|
+
/**
|
|
1036
|
+
* Bot strategy that maximizes the immediate score.
|
|
1037
|
+
* Evaluates every valid placement and picks the one yielding the highest score.
|
|
1038
|
+
* When picking a domino, simulates the best placement for each option.
|
|
1039
|
+
*/
|
|
1040
|
+
declare const greedyStrategy: BotStrategy;
|
|
1041
|
+
/**
|
|
1042
|
+
* Bot strategy with 1-turn lookahead.
|
|
1043
|
+
* When making decisions, considers not just the immediate score but also
|
|
1044
|
+
* the best possible score achievable in the next turn by peeking at
|
|
1045
|
+
* the upcoming domino batch from the draw pile.
|
|
1046
|
+
*/
|
|
1047
|
+
declare const advancedStrategy: BotStrategy;
|
|
1048
|
+
/**
|
|
1049
|
+
* Bot strategy that searches the game tree with beam-search pruning.
|
|
1050
|
+
* Explores all remaining turns, but limits the number of placements
|
|
1051
|
+
* evaluated per domino to the top candidates (by greedy score).
|
|
1052
|
+
* Since kingdoms are independent, this is a solo optimization (no adversarial search needed).
|
|
1053
|
+
*/
|
|
1054
|
+
declare const expertStrategy: BotStrategy;
|
|
1055
|
+
/**
|
|
1056
|
+
* Executes a single bot turn using the given strategy and engine.
|
|
1057
|
+
* Reads the current game state to determine the required action,
|
|
1058
|
+
* asks the strategy for a decision, and executes it via the engine.
|
|
1059
|
+
*
|
|
1060
|
+
* @param engine - The game engine instance
|
|
1061
|
+
* @param game - Current game state (must require a player action)
|
|
1062
|
+
* @param strategy - The bot strategy to use for decisions
|
|
1063
|
+
* @returns Updated game state after the bot's action
|
|
1064
|
+
*/
|
|
1065
|
+
declare const playBotTurn: (engine: GameEngine, game: GameWithNextAction, strategy: BotStrategy) => GameState;
|
|
1066
|
+
/**
|
|
1067
|
+
* Checks if the current turn belongs to a bot player.
|
|
1068
|
+
*/
|
|
1069
|
+
declare const isBotTurn: (game: GameWithNextAction) => boolean;
|
|
1070
|
+
/**
|
|
1071
|
+
* Plays all consecutive bot turns until a human turn or game end is reached.
|
|
1072
|
+
* Resolves each bot's strategy by name from the registry (or custom map).
|
|
1073
|
+
* Falls back to randomStrategy if the strategy name is not found.
|
|
1074
|
+
*
|
|
1075
|
+
* @param engine - The game engine instance
|
|
1076
|
+
* @param game - Current game state
|
|
1077
|
+
* @param customStrategies - Optional custom strategy map (name → BotStrategy)
|
|
1078
|
+
* @returns Updated game state paused at the next human turn or game end
|
|
1079
|
+
*/
|
|
1080
|
+
declare const playBotTurns: (engine: GameEngine, game: GameState, customStrategies?: Record<string, BotStrategy>) => GameState;
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* Built-in strategy names.
|
|
1084
|
+
*/
|
|
1085
|
+
type StrategyName = "random" | "greedy" | "advanced" | "expert";
|
|
1086
|
+
/**
|
|
1087
|
+
* Resolves a strategy by name. Checks custom strategies first, then defaults.
|
|
1088
|
+
* Returns undefined if the name is not found.
|
|
1089
|
+
*/
|
|
1090
|
+
declare const getStrategy: (name: string, custom?: Record<string, BotStrategy>) => BotStrategy | undefined;
|
|
1091
|
+
/**
|
|
1092
|
+
* Returns the list of built-in strategy names.
|
|
1093
|
+
*/
|
|
1094
|
+
declare const getStrategyNames: () => string[];
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* The types of state-changing actions that can be recorded.
|
|
1098
|
+
*/
|
|
1099
|
+
type ActionType = "createGame" | "addPlayers" | "addExtraRules" | "startGame" | "chooseDomino" | "placeDomino" | "discardDomino";
|
|
1100
|
+
/**
|
|
1101
|
+
* Payload types for each action, containing only the command parameters
|
|
1102
|
+
* (excluding the game state, which is too large to store).
|
|
1103
|
+
*/
|
|
1104
|
+
type ActionPayloadMap = {
|
|
1105
|
+
createGame: {
|
|
1106
|
+
mode: string;
|
|
1107
|
+
seed?: string;
|
|
1108
|
+
};
|
|
1109
|
+
addPlayers: {
|
|
1110
|
+
players: PlayerInput[];
|
|
1111
|
+
};
|
|
1112
|
+
addExtraRules: {
|
|
1113
|
+
extraRules: string[];
|
|
1114
|
+
};
|
|
1115
|
+
startGame: Record<string, never>;
|
|
1116
|
+
chooseDomino: {
|
|
1117
|
+
lordId: string;
|
|
1118
|
+
dominoPick: number;
|
|
1119
|
+
};
|
|
1120
|
+
placeDomino: {
|
|
1121
|
+
lordId: string;
|
|
1122
|
+
position: Position;
|
|
1123
|
+
rotation: Rotation;
|
|
1124
|
+
};
|
|
1125
|
+
discardDomino: {
|
|
1126
|
+
lordId: string;
|
|
1127
|
+
};
|
|
1128
|
+
};
|
|
1129
|
+
/**
|
|
1130
|
+
* A single recorded action in the game log.
|
|
1131
|
+
*/
|
|
1132
|
+
type ActionEntry<T extends ActionType = ActionType> = {
|
|
1133
|
+
/** Auto-incrementing index (0-based) */
|
|
1134
|
+
id: number;
|
|
1135
|
+
/** Timestamp when the action was recorded (Date.now()) */
|
|
1136
|
+
timestamp: number;
|
|
1137
|
+
/** The type of action performed */
|
|
1138
|
+
action: T;
|
|
1139
|
+
/** Command parameters (excludes game state) */
|
|
1140
|
+
payload: ActionPayloadMap[T];
|
|
1141
|
+
/** Turn number after the action was applied */
|
|
1142
|
+
turn: number;
|
|
1143
|
+
};
|
|
1144
|
+
/**
|
|
1145
|
+
* An immutable log of all actions performed during a game.
|
|
1146
|
+
* Can be used to replay a game or analyze player decisions.
|
|
1147
|
+
*
|
|
1148
|
+
* @example
|
|
1149
|
+
* ```typescript
|
|
1150
|
+
* const { engine, getLog } = wrapWithActionLog(baseEngine);
|
|
1151
|
+
* let game = engine.createGame({ mode: 'Classic' });
|
|
1152
|
+
* game = engine.addPlayers({ game, players: ['Alice', 'Bob'] });
|
|
1153
|
+
* // ... play the game ...
|
|
1154
|
+
* const log = getLog();
|
|
1155
|
+
* console.log(log.entries); // all actions recorded
|
|
1156
|
+
* ```
|
|
1157
|
+
*/
|
|
1158
|
+
type GameActionLog = {
|
|
1159
|
+
/** The game ID this log belongs to */
|
|
1160
|
+
gameId: string;
|
|
1161
|
+
/** Immutable array of recorded actions */
|
|
1162
|
+
entries: readonly ActionEntry[];
|
|
1163
|
+
};
|
|
1164
|
+
/**
|
|
1165
|
+
* Creates an empty action log for a game.
|
|
1166
|
+
*/
|
|
1167
|
+
declare const createActionLog: (gameId: string) => GameActionLog;
|
|
1168
|
+
/**
|
|
1169
|
+
* Appends an action to the log (immutable — returns a new log).
|
|
1170
|
+
*/
|
|
1171
|
+
declare const appendAction: (log: GameActionLog, entry: Omit<ActionEntry, "id" | "timestamp">) => GameActionLog;
|
|
1172
|
+
/**
|
|
1173
|
+
* Returns all entries in the log.
|
|
1174
|
+
*/
|
|
1175
|
+
declare const getActions: (log: GameActionLog) => readonly ActionEntry[];
|
|
1176
|
+
/**
|
|
1177
|
+
* Returns entries filtered by action type.
|
|
1178
|
+
*/
|
|
1179
|
+
declare const getActionsByType: (log: GameActionLog, type: ActionType) => readonly ActionEntry[];
|
|
1180
|
+
/**
|
|
1181
|
+
* Returns entries filtered by turn number.
|
|
1182
|
+
*/
|
|
1183
|
+
declare const getActionsByTurn: (log: GameActionLog, turn: number) => readonly ActionEntry[];
|
|
1184
|
+
/**
|
|
1185
|
+
* Wraps a GameEngine to automatically record every state-changing action.
|
|
1186
|
+
* Read-only methods are passed through unchanged.
|
|
1187
|
+
*
|
|
1188
|
+
* @param engine - The base game engine to wrap
|
|
1189
|
+
* @returns An object with the wrapped engine and a getLog() accessor
|
|
1190
|
+
*
|
|
1191
|
+
* @example
|
|
1192
|
+
* ```typescript
|
|
1193
|
+
* const { engine: logged, getLog } = wrapWithActionLog(baseEngine);
|
|
1194
|
+
* let game = logged.createGame({ mode: 'Classic' });
|
|
1195
|
+
* // ... play ...
|
|
1196
|
+
* const log = getLog(); // retrieve the full action log
|
|
1197
|
+
* ```
|
|
1198
|
+
*/
|
|
1199
|
+
declare const wrapWithActionLog: (engine: GameEngine) => {
|
|
1200
|
+
engine: GameEngine;
|
|
1201
|
+
getLog: () => GameActionLog;
|
|
1202
|
+
};
|
|
1203
|
+
/**
|
|
1204
|
+
* Replays all actions from a log on a fresh engine to reconstruct the final game state.
|
|
1205
|
+
* The engine should use the same configuration (especially shuffleMethod) as the original game
|
|
1206
|
+
* to guarantee deterministic results when a seed is present.
|
|
1207
|
+
*
|
|
1208
|
+
* @param engine - A game engine instance (should match original config)
|
|
1209
|
+
* @param log - The action log to replay
|
|
1210
|
+
* @returns The final game state after replaying all actions
|
|
1211
|
+
*/
|
|
1212
|
+
declare const replayActions: (engine: GameEngine, log: GameActionLog) => GameState;
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Manages a history of game states for undo/redo support.
|
|
1216
|
+
* Uses a snapshot-based approach: each state is stored as a full GameState.
|
|
1217
|
+
*
|
|
1218
|
+
* @example
|
|
1219
|
+
* ```typescript
|
|
1220
|
+
* let history = createGameHistory(initialGame);
|
|
1221
|
+
* const newGame = engine.chooseDomino({ game: history.current, ... });
|
|
1222
|
+
* history = pushState(history, newGame);
|
|
1223
|
+
* history = undo(history); // back to initialGame
|
|
1224
|
+
* history = redo(history); // forward to newGame
|
|
1225
|
+
* ```
|
|
1226
|
+
*/
|
|
1227
|
+
type GameHistory = {
|
|
1228
|
+
/** The current game state */
|
|
1229
|
+
current: GameState;
|
|
1230
|
+
/** Stack of previous states (most recent last) */
|
|
1231
|
+
past: GameState[];
|
|
1232
|
+
/** Stack of undone states (most recent last) */
|
|
1233
|
+
future: GameState[];
|
|
1234
|
+
};
|
|
1235
|
+
/**
|
|
1236
|
+
* Creates a new game history initialized with a game state.
|
|
1237
|
+
*
|
|
1238
|
+
* @param initialState - The starting game state
|
|
1239
|
+
* @returns A new GameHistory with empty past and future
|
|
1240
|
+
*/
|
|
1241
|
+
declare const createGameHistory: (initialState: GameState) => GameHistory;
|
|
1242
|
+
/**
|
|
1243
|
+
* Records a new game state in the history.
|
|
1244
|
+
* The current state is pushed to the past stack, and the future stack is cleared
|
|
1245
|
+
* (branching from a previous undo point discards the old future).
|
|
1246
|
+
*
|
|
1247
|
+
* @param history - The current history
|
|
1248
|
+
* @param newState - The new game state to record
|
|
1249
|
+
* @returns Updated history with the new state as current
|
|
1250
|
+
*/
|
|
1251
|
+
declare const pushState: (history: GameHistory, newState: GameState) => GameHistory;
|
|
1252
|
+
/**
|
|
1253
|
+
* Reverts to the previous game state.
|
|
1254
|
+
* The current state is moved to the future stack for potential redo.
|
|
1255
|
+
*
|
|
1256
|
+
* @param history - The current history
|
|
1257
|
+
* @returns Updated history with the previous state as current
|
|
1258
|
+
* @throws {UndoError} If there is no previous state to revert to
|
|
1259
|
+
*/
|
|
1260
|
+
declare const undo: (history: GameHistory) => GameHistory;
|
|
1261
|
+
/**
|
|
1262
|
+
* Re-applies a previously undone game state.
|
|
1263
|
+
* The current state is moved to the past stack.
|
|
1264
|
+
*
|
|
1265
|
+
* @param history - The current history
|
|
1266
|
+
* @returns Updated history with the next undone state as current
|
|
1267
|
+
* @throws {RedoError} If there is no undone state to re-apply
|
|
1268
|
+
*/
|
|
1269
|
+
declare const redo: (history: GameHistory) => GameHistory;
|
|
1270
|
+
/**
|
|
1271
|
+
* Checks whether an undo operation is available.
|
|
1272
|
+
*/
|
|
1273
|
+
declare const canUndo: (history: GameHistory) => boolean;
|
|
1274
|
+
/**
|
|
1275
|
+
* Checks whether a redo operation is available.
|
|
1276
|
+
*/
|
|
1277
|
+
declare const canRedo: (history: GameHistory) => boolean;
|
|
1278
|
+
/**
|
|
1279
|
+
* Clears the undo/redo history, keeping only the current state.
|
|
1280
|
+
*
|
|
1281
|
+
* @param history - The current history
|
|
1282
|
+
* @returns A new history with empty past and future
|
|
1283
|
+
*/
|
|
1284
|
+
declare const clearHistory: (history: GameHistory) => GameHistory;
|
|
1285
|
+
/**
|
|
1286
|
+
* Returns the number of states in the past and future stacks.
|
|
1287
|
+
*/
|
|
1288
|
+
declare const getHistorySize: (history: GameHistory) => {
|
|
1289
|
+
past: number;
|
|
1290
|
+
future: number;
|
|
1291
|
+
};
|
|
1292
|
+
|
|
1293
|
+
/**
|
|
1294
|
+
* Serializes a game state to a JSON string.
|
|
1295
|
+
* The serialized string includes version information for future compatibility.
|
|
1296
|
+
*
|
|
1297
|
+
* @param game - The game state to serialize
|
|
1298
|
+
* @returns JSON string representation of the game
|
|
1299
|
+
*/
|
|
1300
|
+
declare const serializeGame: (game: GameState) => string;
|
|
1301
|
+
/**
|
|
1302
|
+
* Deserializes a JSON string back to a game state.
|
|
1303
|
+
* Validates the structure and version before returning.
|
|
1304
|
+
*
|
|
1305
|
+
* @param json - The JSON string to deserialize
|
|
1306
|
+
* @returns Result containing the game state or an error
|
|
1307
|
+
*/
|
|
1308
|
+
declare const deserializeGame: (json: string) => Result<GameState>;
|
|
1309
|
+
/**
|
|
1310
|
+
* Creates a save point for the current game state.
|
|
1311
|
+
* Includes metadata for debugging and restore purposes.
|
|
1312
|
+
*/
|
|
1313
|
+
interface GameSavePoint {
|
|
1314
|
+
/** Serialized game data */
|
|
1315
|
+
serialized: string;
|
|
1316
|
+
/** When the save was created */
|
|
1317
|
+
createdAt: string;
|
|
1318
|
+
/** Game ID for reference */
|
|
1319
|
+
gameId: string;
|
|
1320
|
+
/** Current turn number */
|
|
1321
|
+
turn: number;
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* Creates a save point from a game state.
|
|
1325
|
+
*
|
|
1326
|
+
* @param game - The game state to save
|
|
1327
|
+
* @returns A save point object with metadata
|
|
1328
|
+
*/
|
|
1329
|
+
declare const createSavePoint: (game: GameState) => GameSavePoint;
|
|
1330
|
+
/**
|
|
1331
|
+
* Restores a game state from a save point.
|
|
1332
|
+
*
|
|
1333
|
+
* @param savePoint - The save point to restore from
|
|
1334
|
+
* @returns Result containing the restored game state or an error
|
|
1335
|
+
*/
|
|
1336
|
+
declare const restoreFromSavePoint: (savePoint: GameSavePoint) => Result<GameState>;
|
|
1337
|
+
|
|
1338
|
+
/**
|
|
1339
|
+
* Creates a new Kingdomino game engine instance.
|
|
1340
|
+
*
|
|
1341
|
+
* @param config - Configuration options for the engine
|
|
1342
|
+
* @returns A fully configured GameEngine instance
|
|
1343
|
+
*
|
|
1344
|
+
* @example
|
|
1345
|
+
* ```typescript
|
|
1346
|
+
* // Basic usage
|
|
1347
|
+
* const engine = createGameEngine({});
|
|
1348
|
+
*
|
|
1349
|
+
* // With logging
|
|
1350
|
+
* const engine = createGameEngine({ logging: true });
|
|
1351
|
+
*
|
|
1352
|
+
* // With event callbacks
|
|
1353
|
+
* const engine = createGameEngine({
|
|
1354
|
+
* events: {
|
|
1355
|
+
* onDominoPlaced: ({ lordId }) => console.log(`${lordId} placed`),
|
|
1356
|
+
* onGameEnd: () => console.log('Game over!'),
|
|
1357
|
+
* },
|
|
1358
|
+
* });
|
|
1359
|
+
* ```
|
|
1360
|
+
*/
|
|
226
1361
|
declare const createGameEngine: (config: Partial<EngineConfig>) => GameEngine;
|
|
227
1362
|
|
|
228
|
-
export { type AddExtraRulesCommand, type AddPlayersCommand, type BasicRules, type CalculateScoreCommand, type ChooseDominoCommand, type CreateGameCommand, type Crown, type DiscardDominoCommand, type Domino, type EmptyGround, type EmptyTile, type ExtraRule, type FinalResult, GRIDSIZE, GROUND, type Game, type GameEngine, type GameMode, type GameState, type GameStateResult, type GameSteps, type GameWithNextAction, type GameWithNextStep, type GameWithResults, type GetExtraRulesCommand, type GetModesCommand, type GetResultCommand, type Ground, type Kingdom, type Lord, type NextAction, type NextStep, type ObjectValues, type PlaceDominoCommand, type Player, type PlayerActions, type PlayerPayload, type Players, type PlayersPayload, type Position, type RevealsDomino, type Rotation, type Rules, type Score, type ScoreResult, type SelectedRules, type ShuffleMethod, type StartGameCommand, type Tile, type UuidMethod, createGameEngine, gameSteps, isGameWithNextAction, isGameWithNextStep, playerActions };
|
|
1363
|
+
export { type ActionEntry, ActionExecutionError, type ActionPayloadMap, type ActionType, type AddExtraRulesCommand, type AddPlayersCommand, type BasicRules, type BotStrategy, type CalculateScoreCommand, type CanPlaceDominoCommand, type ChooseDominoCommand, type CreateGameCommand, type Crown, type DebugLogEntry, type DebugLogLevel, type DebugLogger, type DebugOptions, type DeserializeGameCommand, type DiscardDominoCommand, type DomainError, DomainException, type Domino, type DominoesRepository, type DynastyResult, type EmptyGround, type EmptyTile, type EngineConfig, ErrorCode, type ErrorCodeType, type ExtraRule, type FinalResult, GRIDSIZE, GROUND, type Game, type GameActionLog, type GameEngine, type GameEventCallbacks, type GameHistory, type GameMode, type GameSavePoint, type GameState, type GameStateResult, type GameStateSummary, type GameSteps, type GameWithNextAction, type GameWithNextStep, type GameWithResults, type GetDynastyResultCommand, type GetExtraRulesCommand, type GetModesCommand, type GetResultCommand, type GetValidPlacementsCommand, type Ground, InvalidStepError, type Kingdom, type Logger, type Lord, MAX_KINGDOM_SIZE, type ModeRepository, type NextAction, type NextStep, NotFoundError, type ObjectValues, type PickContext, type PlaceContext, type PlaceDominoCommand, type Player, type PlayerActions, type PlayerInput, type PlayerPayload, type Players, type PlayersPayload, type Position, RedoError, type RevealsDomino, type Rotation, type RuleRepository, type Rules, type Score, type ScoreResult, type SelectedRules, type SerializeGameCommand, type ShuffleMethod, type StartGameCommand, StepExecutionError, type StrategyName, type Tile, TranslationKey, type TranslationKeyType, type Translator, UndoError, type UuidMethod, type ValidPlacement, ValidationError, type ValidationIssue, type ValidationSeverity, advancedStrategy, appendAction, canRedo, canUndo, clearHistory, createActionLog, createDomainError, createGameEngine, createGameHistory, createSavePoint, createTranslator, defaultTranslations, defaultTranslator, deserializeGame, errorCodeToTranslationKey, expertStrategy, gameSteps, getActions, getActionsByTurn, getActionsByType, getHistorySize, getStrategy, getStrategyNames, greedyStrategy, isBotTurn, isGameWithNextAction, isGameWithNextStep, playBotTurn, playBotTurns, playerActions, pushState, randomStrategy, redo, replayActions, restoreFromSavePoint, serializeGame, summarizeGameState, translateErrorCode, undo, validateGameState, wrapWithActionLog, wrapWithDebug, wrapWithEvents };
|