@pompidup/kingdomino-engine 3.5.1 → 3.7.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 +35 -18
- package/dist/index.d.ts +1454 -677
- package/dist/index.js +4370 -2514
- package/dist/index.js.map +1 -1
- package/dist/index.universal.js +4370 -2514
- package/dist/wasm-bridge.js +4018 -2249
- package/package.json +1 -9
package/README.md
CHANGED
|
@@ -42,15 +42,19 @@ while (isGameWithNextAction(game)) {
|
|
|
42
42
|
const { nextLord, nextAction } = game.nextAction;
|
|
43
43
|
|
|
44
44
|
if (nextAction === "pickDomino") {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
game = engine.chooseDomino({ game, lordId: nextLord, dominoPick: domino.domino.number });
|
|
48
|
-
}
|
|
45
|
+
const [dominoPick] = engine.getValidDominoPicks({ game });
|
|
46
|
+
game = engine.chooseDomino({ game, lordId: nextLord, dominoPick });
|
|
49
47
|
} else if (nextAction === "placeDomino") {
|
|
50
48
|
const lord = game.lords.find((l) => l.id === nextLord);
|
|
51
49
|
const player = game.players.find((p) => p.id === lord?.playerId);
|
|
52
50
|
if (lord?.dominoPicked && player) {
|
|
53
|
-
|
|
51
|
+
// maxKingdomSize: 5, or 7 for a 7x7 kingdom (The Mighty Duel, Neolithic,
|
|
52
|
+
// QueenDomino and AgeOfGiants-QueenDomino at 2 players)
|
|
53
|
+
const placements = engine.getValidPlacements({
|
|
54
|
+
kingdom: player.kingdom,
|
|
55
|
+
domino: lord.dominoPicked,
|
|
56
|
+
maxKingdomSize: game.rules.basic.maxKingdomSize,
|
|
57
|
+
});
|
|
54
58
|
if (placements.length > 0) {
|
|
55
59
|
game = engine.placeDomino({ game, lordId: nextLord, position: placements[0].position, rotation: placements[0].rotation });
|
|
56
60
|
} else {
|
|
@@ -71,12 +75,12 @@ console.log(results.result);
|
|
|
71
75
|
| Mode | Description |
|
|
72
76
|
|------|-------------|
|
|
73
77
|
| **Classic** | Original Kingdomino rules. 1-4 players, 5x5 kingdom, terrain-based scoring. |
|
|
74
|
-
| **QueenDomino** | Full Queendomino expansion with buildings, coins, knights, the Queen and the Dragon. |
|
|
78
|
+
| **QueenDomino** | Full Queendomino expansion with buildings, coins, knights, the Queen and the Dragon. 2-4 players (7x7 kingdom with the 48 dominoes at 2 players). |
|
|
75
79
|
| **KingdominoOrigins-Discovery** | Origins expansion — volcanoes, fire tokens, fire-based scoring. |
|
|
76
80
|
| **KingdominoOrigins-Totem** | Origins — Discovery + wooden resources + totem majority tiles. |
|
|
77
81
|
| **KingdominoOrigins-Tribe** | Origins — Discovery + resources + cave board + cavemen recruitment. |
|
|
78
82
|
| **AgeOfGiants** | Age of Giants extension — giants, quest tiles, 5-player support, 12 new dominos on Classic. |
|
|
79
|
-
| **AgeOfGiants-QueenDomino** | Age of Giants combined with QueenDomino. |
|
|
83
|
+
| **AgeOfGiants-QueenDomino** | Age of Giants combined with QueenDomino (7x7 kingdom with the 60 dominoes at 2 players). |
|
|
80
84
|
|
|
81
85
|
```typescript
|
|
82
86
|
let game = engine.createGame({ mode: "Classic" });
|
|
@@ -92,11 +96,12 @@ See [Game Modes](docs/game-modes.md) for rules, player counts, and extra rules d
|
|
|
92
96
|
The QueenDomino mode adds significant new mechanics to the base game:
|
|
93
97
|
|
|
94
98
|
- **Construction squares** on some domino tiles where buildings can be placed
|
|
95
|
-
- **Coins** (7 starting) used to purchase buildings or
|
|
96
|
-
- **Knights** (
|
|
97
|
-
- **Buildings**
|
|
98
|
-
- **The Queen**
|
|
99
|
-
- **The Dragon** burns a building tile from the Builders Board
|
|
99
|
+
- **Coins** (7 starting) used to purchase buildings or bribe the Dragon; 1 point per 3 unused coins at the end of the game
|
|
100
|
+
- **Knights** (1 at the start, more from building bonuses) placed on the domino just placed, up to 2 per turn, collecting 1 coin per square of the territory
|
|
101
|
+
- **Buildings** purchased from the 6-spot Builders Board (spots costing 5 to 0 coins), granting crowns, towers, and end-game bonuses
|
|
102
|
+
- **The Queen** hosted by the player who reaches the most towers (even on a tie): -1 coin on her host's constructions, +1 crown on their largest territory at the end
|
|
103
|
+
- **The Dragon** burns a building tile from the Builders Board for 1 coin
|
|
104
|
+
- **2 players**: 7x7 kingdoms with all 48 dominoes (official rule)
|
|
100
105
|
|
|
101
106
|
The turn flow is extended with optional actions after placing a domino:
|
|
102
107
|
|
|
@@ -147,10 +152,13 @@ if (nextAction === "placeGiant") {
|
|
|
147
152
|
game = engine.placeGiant({ game, lordId: nextLord, position });
|
|
148
153
|
}
|
|
149
154
|
if (nextAction === "sendGiant") {
|
|
150
|
-
|
|
155
|
+
// The targeted opponent chooses the crown the giant covers
|
|
156
|
+
game = engine.sendGiant({ game, lordId: nextLord, giantIndex, targetPlayerId });
|
|
151
157
|
}
|
|
152
158
|
```
|
|
153
159
|
|
|
160
|
+
After `sendGiant`, a single free crown of the opponent is covered automatically. With several free crowns, `game.ageOfGiants.pendingGiant` is set and the game waits for a `placeGiant` played by a lord of the **targeted** player (`getValidGiantPositions` lists its crowns). `targetCrownPosition` is still accepted for backward compatibility.
|
|
161
|
+
|
|
154
162
|
See [Age of Giants Guide](docs/age-of-giants.md) for the complete rules and mechanics.
|
|
155
163
|
|
|
156
164
|
## Extra Rules
|
|
@@ -159,13 +167,16 @@ See [Age of Giants Guide](docs/age-of-giants.md) for the complete rules and mech
|
|
|
159
167
|
|------|-------------|-------------|
|
|
160
168
|
| **The Middle Kingdom** | +10 points if castle is centered | — |
|
|
161
169
|
| **Harmony** | +5 points if no dominos were discarded | — |
|
|
162
|
-
| **The Mighty Duel** | All 48 dominos, 7x7 kingdom | 2 players only |
|
|
170
|
+
| **The Mighty Duel** | All 48 dominos, 7x7 kingdom | 2 players only (QueenDomino already plays 7x7 at 2 players: accepted, without further effect) |
|
|
163
171
|
| **Dynasty** | Play 3 games, highest total wins | — |
|
|
164
172
|
|
|
173
|
+
Origins has its own equivalents: **Empire of Fire**, **Homo Habilis**, **Neolithic** (2 players, 7x7, and the first pick of each line takes the dominoes 1 & 4 or 2 & 3 — see [Origins Guide](docs/origins.md#neolithic-2-players)) and **Dynasty**.
|
|
174
|
+
|
|
165
175
|
```typescript
|
|
166
176
|
game = engine.addExtraRules({ game, extraRules: ["The middle Kingdom", "Harmony"] });
|
|
167
177
|
|
|
168
|
-
// Dynasty: aggregate results from multiple games
|
|
178
|
+
// Dynasty: aggregate results from multiple games (grouped by player id: pass
|
|
179
|
+
// the same stable ids to addPlayers in every game, e.g. { id: "alice", name: "Alice" })
|
|
169
180
|
const dynastyResults = engine.getDynastyResults({ games: [game1, game2, game3] });
|
|
170
181
|
```
|
|
171
182
|
|
|
@@ -202,6 +213,8 @@ const engine = createGameEngine({
|
|
|
202
213
|
| `calculateScore` | Calculate score for any kingdom |
|
|
203
214
|
| `getValidPlacements` | Find all valid placements for a domino |
|
|
204
215
|
| `canPlaceDomino` | Check if any placement exists |
|
|
216
|
+
| `getValidDominoPicks` | Dominoes the lord to play may pick (Neolithic reservations included) |
|
|
217
|
+
| `calculatePlayerScore` | Mode-aware live (or final) score of one player, with its breakdown |
|
|
205
218
|
| `serialize` / `deserialize` | Save and restore game state |
|
|
206
219
|
| `getDynastyResults` | Aggregate scores from multiple games |
|
|
207
220
|
|
|
@@ -211,7 +224,7 @@ const engine = createGameEngine({
|
|
|
211
224
|
|--------|-------------|
|
|
212
225
|
| `placeKnight` | Place a knight and collect tax |
|
|
213
226
|
| `constructBuilding` | Buy and place a building |
|
|
214
|
-
| `useDragon` | Destroy a building tile from the board |
|
|
227
|
+
| `useDragon` | Destroy a building tile from the board (1 coin) |
|
|
215
228
|
| `skipOptionalAction` | Skip the current optional action |
|
|
216
229
|
|
|
217
230
|
### Origins Methods
|
|
@@ -228,14 +241,18 @@ const engine = createGameEngine({
|
|
|
228
241
|
| `placeGiant` | Place a giant on a crown in your kingdom |
|
|
229
242
|
| `sendGiant` | Send a giant to an opponent's kingdom |
|
|
230
243
|
|
|
244
|
+
### Valid targets
|
|
245
|
+
|
|
246
|
+
`getValidFireTokenPositions`, `getValidKnightPositions`, `getValidBuildingPositions`, `getAffordableBuildings`, `getValidDragonTargets`, `getValidCavemanPlacements`, `getValidGiantPositions`, `getValidGiantTargets` and `canSkipOptionalAction` list what the extension actions accept, with the same checks as the actions (see [Valid targets](docs/api-reference.md#valid-targets-for-extension-actions)).
|
|
247
|
+
|
|
231
248
|
See [API Reference](docs/api-reference.md) for complete method signatures, types, and error codes.
|
|
232
249
|
|
|
233
250
|
## Additional Features
|
|
234
251
|
|
|
235
|
-
- **Bot / AI**: 4 built-in strategies (`randomStrategy`, `greedyStrategy`, `advancedStrategy`, `expertStrategy`) with `playBotTurn()` helper
|
|
252
|
+
- **Bot / AI**: 4 built-in strategies (`randomStrategy`, `greedyStrategy`, `advancedStrategy`, `expertStrategy`) with `playBotTurn()` helper; mode-aware (they evaluate with the mode-aware score and play the Queendomino, Origins and Age of Giants actions — see [Bot Strategies](docs/api-reference.md#bot-strategies))
|
|
236
253
|
- **Mixed games**: Human and bot players in the same game via `bot: { strategyName }` on player input
|
|
237
254
|
- **Undo / Redo**: Snapshot-based history with `createGameHistory()`, `pushState()`, `undo()`, `redo()`
|
|
238
|
-
- **Action Log**: Immutable log via `wrapWithActionLog(engine)` for replay with `replayActions()
|
|
255
|
+
- **Action Log**: Immutable log via `wrapWithActionLog(engine)` for replay with `replayActions()`; format v2 records the seed and the game, player and lord ids, so a replay gives a strictly identical state (v1 logs remain replayable)
|
|
239
256
|
- **Events**: Callbacks via `EngineConfig.events` (`onDominoPlaced`, `onGameEnd`, etc.)
|
|
240
257
|
- **Debug Mode**: `wrapWithDebug(engine)` with 3 verbosity levels
|
|
241
258
|
- **Seeded games**: Deterministic shuffle via `createGame({ mode, seed: "my-seed" })`
|