warp12-engine 0.1.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 +25 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2028 -0
- package/dist/lib/ai/actions.d.ts +32 -0
- package/dist/lib/ai/actions.d.ts.map +1 -0
- package/dist/lib/ai/candidate-generator.d.ts +20 -0
- package/dist/lib/ai/candidate-generator.d.ts.map +1 -0
- package/dist/lib/ai/context.d.ts +19 -0
- package/dist/lib/ai/context.d.ts.map +1 -0
- package/dist/lib/ai/create-warp-ai.d.ts +49 -0
- package/dist/lib/ai/create-warp-ai.d.ts.map +1 -0
- package/dist/lib/ai/explain-action.d.ts +8 -0
- package/dist/lib/ai/explain-action.d.ts.map +1 -0
- package/dist/lib/ai/heuristics.d.ts +21 -0
- package/dist/lib/ai/heuristics.d.ts.map +1 -0
- package/dist/lib/ai/index.d.ts +19 -0
- package/dist/lib/ai/index.d.ts.map +1 -0
- package/dist/lib/ai/observation.d.ts +20 -0
- package/dist/lib/ai/observation.d.ts.map +1 -0
- package/dist/lib/ai/q-flash.d.ts +11 -0
- package/dist/lib/ai/q-flash.d.ts.map +1 -0
- package/dist/lib/ai/search-model.d.ts +33 -0
- package/dist/lib/ai/search-model.d.ts.map +1 -0
- package/dist/lib/ai/self-play.d.ts +50 -0
- package/dist/lib/ai/self-play.d.ts.map +1 -0
- package/dist/lib/ai/skill.d.ts +8 -0
- package/dist/lib/ai/skill.d.ts.map +1 -0
- package/dist/lib/ai/test-fixtures.d.ts +18 -0
- package/dist/lib/ai/test-fixtures.d.ts.map +1 -0
- package/dist/lib/constants/setup.d.ts +15 -0
- package/dist/lib/constants/setup.d.ts.map +1 -0
- package/dist/lib/domino/coordinates.d.ts +13 -0
- package/dist/lib/domino/coordinates.d.ts.map +1 -0
- package/dist/lib/engine/apply-action.d.ts +7 -0
- package/dist/lib/engine/apply-action.d.ts.map +1 -0
- package/dist/lib/engine/beacon.d.ts +30 -0
- package/dist/lib/engine/beacon.d.ts.map +1 -0
- package/dist/lib/engine/dead-red-alert.d.ts +4 -0
- package/dist/lib/engine/dead-red-alert.d.ts.map +1 -0
- package/dist/lib/engine/helpers.d.ts +12 -0
- package/dist/lib/engine/helpers.d.ts.map +1 -0
- package/dist/lib/engine/legal-moves.d.ts +10 -0
- package/dist/lib/engine/legal-moves.d.ts.map +1 -0
- package/dist/lib/engine/q-continuum.d.ts +25 -0
- package/dist/lib/engine/q-continuum.d.ts.map +1 -0
- package/dist/lib/engine/round-resolution.d.ts +13 -0
- package/dist/lib/engine/round-resolution.d.ts.map +1 -0
- package/dist/lib/engine/scoring.d.ts +9 -0
- package/dist/lib/engine/scoring.d.ts.map +1 -0
- package/dist/lib/engine/test-helpers.d.ts +26 -0
- package/dist/lib/engine/test-helpers.d.ts.map +1 -0
- package/dist/lib/fixtures/create-demo-game.d.ts +17 -0
- package/dist/lib/fixtures/create-demo-game.d.ts.map +1 -0
- package/dist/lib/setup/create-game.d.ts +51 -0
- package/dist/lib/setup/create-game.d.ts.map +1 -0
- package/dist/lib/table/pip-inventory.d.ts +12 -0
- package/dist/lib/table/pip-inventory.d.ts.map +1 -0
- package/dist/lib/table/table-state.d.ts +14 -0
- package/dist/lib/table/table-state.d.ts.map +1 -0
- package/dist/lib/types/actions.d.ts +64 -0
- package/dist/lib/types/actions.d.ts.map +1 -0
- package/dist/lib/types/anomalies.d.ts +29 -0
- package/dist/lib/types/anomalies.d.ts.map +1 -0
- package/dist/lib/types/coordinate.d.ts +22 -0
- package/dist/lib/types/coordinate.d.ts.map +1 -0
- package/dist/lib/types/game-state.d.ts +73 -0
- package/dist/lib/types/game-state.d.ts.map +1 -0
- package/dist/lib/types/modules.d.ts +32 -0
- package/dist/lib/types/modules.d.ts.map +1 -0
- package/dist/lib/types/objective.d.ts +5 -0
- package/dist/lib/types/objective.d.ts.map +1 -0
- package/dist/lib/types/player.d.ts +12 -0
- package/dist/lib/types/player.d.ts.map +1 -0
- package/dist/lib/types/q-continuum.d.ts +50 -0
- package/dist/lib/types/q-continuum.d.ts.map +1 -0
- package/dist/lib/types/trails.d.ts +20 -0
- package/dist/lib/types/trails.d.ts.map +1 -0
- package/dist/lib/violations/format-violation.d.ts +3 -0
- package/dist/lib/violations/format-violation.d.ts.map +1 -0
- package/dist/lib/warp12-lib.d.ts +22 -0
- package/dist/lib/warp12-lib.d.ts.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GameAction, LegalMove } from '../types/actions.js';
|
|
2
|
+
import { PlayerId } from '../types/player.js';
|
|
3
|
+
import { QFlashEffectKind } from '../types/q-continuum.js';
|
|
4
|
+
/**
|
|
5
|
+
* The AI's action space, mirroring the moves a captain can declare. `chart`
|
|
6
|
+
* wraps an engine {@link LegalMove}; the rest map 1:1 onto control actions.
|
|
7
|
+
* Custom variants can extend behavior with new heuristics/generators rather
|
|
8
|
+
* than new kinds, since these already cover every legal Warp 12 action.
|
|
9
|
+
*/
|
|
10
|
+
export type WarpAiAction = {
|
|
11
|
+
readonly kind: 'chart';
|
|
12
|
+
readonly move: LegalMove;
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: 'draw';
|
|
15
|
+
} | {
|
|
16
|
+
readonly kind: 'deploy-beacon';
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: 'pass-red-alert';
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'pass-turn';
|
|
21
|
+
} | {
|
|
22
|
+
readonly kind: 'declare-treaty';
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: 'invoke-q-flash';
|
|
25
|
+
readonly effect: QFlashEffectKind;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'resolve-q-gamble';
|
|
28
|
+
readonly keepIndex: 0 | 1;
|
|
29
|
+
};
|
|
30
|
+
/** Lowers an AI action into the engine {@link GameAction} for `applyAction`. */
|
|
31
|
+
export declare function toGameAction(action: WarpAiAction, playerId: PlayerId): GameAction;
|
|
32
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAA;CAAE,CAAC;AAErE,gFAAgF;AAChF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,GACjB,UAAU,CA4BZ"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { WarpAiAction } from './actions.js';
|
|
2
|
+
import { WarpAiObservation } from './observation.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the considered actions for a Warp 12 turn, deferring all rules gating
|
|
5
|
+
* (Distress Beacon access, Red Alert cover, Subspace Fracture stabilization) to
|
|
6
|
+
* the engine's {@link getLegalMoves}. Precedence:
|
|
7
|
+
*
|
|
8
|
+
* 1. Q-Flash / Q's gamble resolution when pending.
|
|
9
|
+
* 2. Impulse-drop obligation (round winner must drop to impulse) overrides everything.
|
|
10
|
+
* 3. Any legal chart move → chart candidates (canonical "play if you can").
|
|
11
|
+
* 4. Otherwise draw (if Uncharted Sectors remain).
|
|
12
|
+
* 5. Otherwise pass the Red Alert (if responsible) or deploy the Distress Beacon.
|
|
13
|
+
*
|
|
14
|
+
* House-rule variants can replace this generator wholesale.
|
|
15
|
+
*/
|
|
16
|
+
export declare function warpCandidateGenerator(obs: WarpAiObservation, options?: {
|
|
17
|
+
captains?: readonly import('../types/player.js').Captain[];
|
|
18
|
+
rng?: () => number;
|
|
19
|
+
}): WarpAiAction[];
|
|
20
|
+
//# sourceMappingURL=candidate-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-generator.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/candidate-generator.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,iBAAiB,EACtB,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,SAAS,OAAO,oBAAoB,EAAE,OAAO,EAAE,CAAC;IAC3D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,GACA,YAAY,EAAE,CAmDhB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Rng } from 'doubletwelve';
|
|
2
|
+
import { Coordinate } from '../types/coordinate.js';
|
|
3
|
+
import { ChartRoute } from '../types/actions.js';
|
|
4
|
+
import { RoundState, TableState } from '../types/game-state.js';
|
|
5
|
+
import { WarpAiObservation } from './observation.js';
|
|
6
|
+
/** Shared, pre-computed turn data handed to every Warp heuristic. */
|
|
7
|
+
export interface WarpEvalContext {
|
|
8
|
+
readonly obs: WarpAiObservation;
|
|
9
|
+
readonly hand: readonly Coordinate[];
|
|
10
|
+
/** Coordinates neither in this captain's hand nor already on the table. */
|
|
11
|
+
readonly unseen: readonly Coordinate[];
|
|
12
|
+
readonly rng: Rng;
|
|
13
|
+
}
|
|
14
|
+
/** Every coordinate currently visible on the table (spacedock, trails, zone, fracture). */
|
|
15
|
+
export declare function collectPlacedCoordinates(table: TableState): Coordinate[];
|
|
16
|
+
/** Open pip value a coordinate must match to chart onto the given route. */
|
|
17
|
+
export declare function connectingValueForRoute(round: RoundState, route: ChartRoute): number | null;
|
|
18
|
+
export declare function buildWarpContext(obs: WarpAiObservation, rng: Rng): WarpEvalContext;
|
|
19
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;CACnB;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE,CAoBxE;AAED,4EAA4E;AAC5E,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,UAAU,GAChB,MAAM,GAAG,IAAI,CAuBf;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,GAAG,GACP,eAAe,CAejB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GenericHeuristic, Rng, SkillProfile } from 'doubletwelve';
|
|
2
|
+
import { GameAction } from '../types/actions.js';
|
|
3
|
+
import { GameState } from '../types/game-state.js';
|
|
4
|
+
import { GameObjective } from '../types/objective.js';
|
|
5
|
+
import { PlayerId } from '../types/player.js';
|
|
6
|
+
import { WarpAiAction } from './actions.js';
|
|
7
|
+
import { WarpEvalContext } from './context.js';
|
|
8
|
+
import { WarpAiObservation } from './observation.js';
|
|
9
|
+
/**
|
|
10
|
+
* Turns on "gaming it out": instead of scoring the current options with
|
|
11
|
+
* heuristics, the bot simulates each move forward with the engine, samples the
|
|
12
|
+
* hidden hands/draw a few times, and looks `depth` plies ahead. More expensive,
|
|
13
|
+
* but it reasons about consequences (e.g. setting up an opponent to go out).
|
|
14
|
+
*/
|
|
15
|
+
export interface LookaheadOptions {
|
|
16
|
+
/** Plies to search, including the bot's own move (>= 1). */
|
|
17
|
+
depth: number;
|
|
18
|
+
/** Hidden-world samples per move for imperfect-information averaging (default 6). */
|
|
19
|
+
determinizations?: number;
|
|
20
|
+
/** Cap candidate moves expanded per node, best-first (default 6). */
|
|
21
|
+
maxBranch?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface CreateWarpAiPlayerOptions {
|
|
24
|
+
skill: SkillProfile;
|
|
25
|
+
/** Defaults to {@link DEFAULT_WARP_HEURISTICS}. Append your own for house tactics. */
|
|
26
|
+
heuristics?: ReadonlyArray<GenericHeuristic<WarpAiAction, WarpEvalContext>>;
|
|
27
|
+
/** Defaults to {@link warpCandidateGenerator}. Replace for house access rules. */
|
|
28
|
+
generateCandidates?: (obs: WarpAiObservation) => WarpAiAction[];
|
|
29
|
+
/** Opt into forward-simulating lookahead. Omit for the fast greedy policy. */
|
|
30
|
+
lookahead?: LookaheadOptions;
|
|
31
|
+
/** Victory condition the bot optimizes for (defaults to `penalty`). */
|
|
32
|
+
objective?: GameObjective;
|
|
33
|
+
/** Defaults to `Math.random`. Inject a seeded RNG for reproducible games/tests. */
|
|
34
|
+
rng?: Rng;
|
|
35
|
+
}
|
|
36
|
+
export interface WarpAiPlayer {
|
|
37
|
+
/** Choose an AI action for an explicit observation. */
|
|
38
|
+
decide(obs: WarpAiObservation): WarpAiAction;
|
|
39
|
+
/** Choose and lower to an engine action for `applyAction`; null if no round. */
|
|
40
|
+
decideGameAction(state: GameState, playerId: PlayerId): GameAction | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* An offline, heuristic Warp 12 captain. It runs entirely on Warp12-lib's own
|
|
44
|
+
* engine (so all of RULES.md — Distress Beacons, Red Alerts, Subspace Fractures,
|
|
45
|
+
* the Neutral Zone, treaties, modules — is honored) while reusing DoubleTwelve's
|
|
46
|
+
* model-agnostic decision policy for skill, scoring, and selection.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createWarpAiPlayer(options: CreateWarpAiPlayerOptions): WarpAiPlayer;
|
|
49
|
+
//# sourceMappingURL=create-warp-ai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-warp-ai.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/create-warp-ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACR,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAQjD,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEtE,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAMnE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,YAAY,CAAC;IACpB,sFAAsF;IACtF,UAAU,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAC5E,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,YAAY,EAAE,CAAC;IAChE,8EAA8E;IAC9E,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,uEAAuE;IACvE,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,mFAAmF;IACnF,GAAG,CAAC,EAAE,GAAG,CAAC;CACX;AAED,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,MAAM,CAAC,GAAG,EAAE,iBAAiB,GAAG,YAAY,CAAC;IAC7C,gFAAgF;IAChF,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI,CAAC;CAC3E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,yBAAyB,GACjC,YAAY,CAqEd"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { GameState } from '../types/game-state.js';
|
|
2
|
+
import { PlayerId } from '../types/player.js';
|
|
3
|
+
import { WarpAiAction } from './actions.js';
|
|
4
|
+
/** Human-readable factors that favor a suggested advisor move (heuristic layer). */
|
|
5
|
+
export declare function explainWarpAiAction(state: GameState, playerId: PlayerId, action: WarpAiAction, options?: {
|
|
6
|
+
maxReasons?: number;
|
|
7
|
+
}): string[];
|
|
8
|
+
//# sourceMappingURL=explain-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain-action.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/explain-action.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAiMjD,oFAAoF;AACpF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAChC,MAAM,EAAE,CAwDV"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GenericHeuristic } from 'doubletwelve';
|
|
2
|
+
import { WarpAiAction } from './actions.js';
|
|
3
|
+
import { WarpEvalContext } from './context.js';
|
|
4
|
+
export type WarpHeuristic = GenericHeuristic<WarpAiAction, WarpEvalContext>;
|
|
5
|
+
/** Stable ids for referencing/overriding Warp heuristics in skill profiles. */
|
|
6
|
+
export declare const WARP_HEURISTIC_IDS: {
|
|
7
|
+
readonly preferChart: "prefer-chart";
|
|
8
|
+
readonly dumpPips: "dump-pips";
|
|
9
|
+
readonly doublesEarly: "play-doubles-early";
|
|
10
|
+
readonly ownTrail: "own-trail";
|
|
11
|
+
readonly coverRelief: "cover-relief";
|
|
12
|
+
readonly redAlertSafe: "red-alert-safe";
|
|
13
|
+
readonly handFlexibility: "hand-flexibility";
|
|
14
|
+
readonly defensiveShared: "defensive-shared";
|
|
15
|
+
readonly salamanderDump: "salamander-dump";
|
|
16
|
+
readonly qContinuum: "q-continuum";
|
|
17
|
+
readonly goOutWin: "go-out-win";
|
|
18
|
+
};
|
|
19
|
+
/** The stock Warp 12 heuristic set. Append/replace by `id` to add house tactics. */
|
|
20
|
+
export declare const DEFAULT_WARP_HEURISTICS: WarpHeuristic[];
|
|
21
|
+
//# sourceMappingURL=heuristics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heuristics.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/heuristics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AASrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,aAAa,GAAG,gBAAgB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;AAE5E,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;CAYrB,CAAC;AAkMX,oFAAoF;AACpF,eAAO,MAAM,uBAAuB,EAAE,aAAa,EAYlD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type { WarpAiAction } from './actions.js';
|
|
2
|
+
export { toGameAction } from './actions.js';
|
|
3
|
+
export type { WarpAiObservation } from './observation.js';
|
|
4
|
+
export { observe } from './observation.js';
|
|
5
|
+
export type { WarpEvalContext } from './context.js';
|
|
6
|
+
export { buildWarpContext, collectPlacedCoordinates, connectingValueForRoute, } from './context.js';
|
|
7
|
+
export { warpCandidateGenerator } from './candidate-generator.js';
|
|
8
|
+
export type { WarpHeuristic } from './heuristics.js';
|
|
9
|
+
export { WARP_HEURISTIC_IDS, DEFAULT_WARP_HEURISTICS } from './heuristics.js';
|
|
10
|
+
export type { WarpSkillLevel } from './skill.js';
|
|
11
|
+
export { WARP_SKILL_PRESETS, getWarpSkillProfile } from './skill.js';
|
|
12
|
+
export type { CreateWarpAiPlayerOptions, LookaheadOptions, WarpAiPlayer, } from './create-warp-ai.js';
|
|
13
|
+
export { createWarpAiPlayer } from './create-warp-ai.js';
|
|
14
|
+
export { explainWarpAiAction } from './explain-action.js';
|
|
15
|
+
export { chooseQFlashEffect, chooseQGambleKeepIndex } from './q-flash.js';
|
|
16
|
+
export { createWarpSearchModel, observationToState, warpLeafEval, handPips, } from './search-model.js';
|
|
17
|
+
export type { SelfPlaySeat, PlaySelfPlayGameOptions, SelfPlayGameResult, SelfPlayMatchResult, } from './self-play.js';
|
|
18
|
+
export { playSelfPlayGame, runSelfPlayMatch } from './self-play.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE9E,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE,YAAY,EACV,yBAAyB,EACzB,gBAAgB,EAChB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { GameState, RoundState } from '../types/game-state.js';
|
|
2
|
+
import { GameModules } from '../types/modules.js';
|
|
3
|
+
import { GameObjective } from '../types/objective.js';
|
|
4
|
+
import { Captain, PlayerId } from '../types/player.js';
|
|
5
|
+
/**
|
|
6
|
+
* What a Warp 12 bot is allowed to see this turn: the public round state, which
|
|
7
|
+
* captain it is, and the active opt-in modules (so module-aware heuristics like
|
|
8
|
+
* Salamander and Q-Continuum can adjust). Opponent hands are intentionally
|
|
9
|
+
* excluded — only their hand counts/placed tiles are knowable.
|
|
10
|
+
*/
|
|
11
|
+
export interface WarpAiObservation {
|
|
12
|
+
readonly round: RoundState;
|
|
13
|
+
readonly playerId: PlayerId;
|
|
14
|
+
readonly modules: GameModules;
|
|
15
|
+
readonly objective: GameObjective;
|
|
16
|
+
readonly captains: readonly Captain[];
|
|
17
|
+
}
|
|
18
|
+
/** Builds an observation for `playerId` from a game state, or null if no round. */
|
|
19
|
+
export declare function observe(state: GameState, playerId: PlayerId): WarpAiObservation | null;
|
|
20
|
+
//# sourceMappingURL=observation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;CACvC;AAED,mFAAmF;AACnF,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,QAAQ,GACjB,iBAAiB,GAAG,IAAI,CAW1B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Captain } from '../types/player.js';
|
|
2
|
+
import { QFlashEffectKind } from '../types/q-continuum.js';
|
|
3
|
+
import { WarpAiObservation } from './observation.js';
|
|
4
|
+
export interface ChooseQFlashOptions {
|
|
5
|
+
readonly rng?: () => number;
|
|
6
|
+
}
|
|
7
|
+
/** Pick the best available Q-Flash for the invoker. */
|
|
8
|
+
export declare function chooseQFlashEffect(obs: WarpAiObservation, captains: readonly Captain[], options?: ChooseQFlashOptions): QFlashEffectKind;
|
|
9
|
+
/** Keep the stronger tile from Q's gamble. */
|
|
10
|
+
export declare function chooseQGambleKeepIndex(obs: WarpAiObservation, options?: ChooseQFlashOptions): 0 | 1;
|
|
11
|
+
//# sourceMappingURL=q-flash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"q-flash.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/q-flash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AA+CD,uDAAuD;AACvD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,iBAAiB,EACtB,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,OAAO,GAAE,mBAAwB,GAChC,gBAAgB,CAiBlB;AAED,8CAA8C;AAC9C,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,iBAAiB,EACtB,OAAO,GAAE,mBAAwB,GAChC,CAAC,GAAG,CAAC,CAYP"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PlayerRef, SearchModel } from 'doubletwelve';
|
|
2
|
+
import { Coordinate } from '../types/coordinate.js';
|
|
3
|
+
import { GameState } from '../types/game-state.js';
|
|
4
|
+
import { GameModules } from '../types/modules.js';
|
|
5
|
+
import { GameObjective } from '../types/objective.js';
|
|
6
|
+
import { WarpAiAction } from './actions.js';
|
|
7
|
+
import { WarpAiObservation } from './observation.js';
|
|
8
|
+
/** Penalty weight of a hand, honoring the Salamander module's 24-point 12-12. */
|
|
9
|
+
export declare function handPips(hand: readonly Coordinate[], modules: GameModules, roundNumber: number): number;
|
|
10
|
+
/** Tile count in hand — the go-out objective cares about this, not pip weight. */
|
|
11
|
+
export declare function handTileCount(hand: readonly Coordinate[]): number;
|
|
12
|
+
/**
|
|
13
|
+
* Leaf evaluation for the penalty-scoring campaign: minimize held pips, maximize
|
|
14
|
+
* what opponents are stuck with, treat going out as decisive.
|
|
15
|
+
*/
|
|
16
|
+
export declare function warpLeafEvalPenalty(state: GameState, perspective: PlayerRef): number;
|
|
17
|
+
/**
|
|
18
|
+
* Leaf evaluation for first-out-wins: minimize tiles held, maximize opponent
|
|
19
|
+
* hand sizes; pip weight and Salamander are irrelevant.
|
|
20
|
+
*/
|
|
21
|
+
export declare function warpLeafEvalGoOut(state: GameState, perspective: PlayerRef): number;
|
|
22
|
+
/** @deprecated Use {@link warpLeafEvalPenalty} or {@link warpLeafEvalGoOut}. */
|
|
23
|
+
export declare function warpLeafEval(state: GameState, perspective: PlayerRef): number;
|
|
24
|
+
/** Build a Game State wrapper around an observation for the forward model. */
|
|
25
|
+
export declare function observationToState(obs: WarpAiObservation): GameState;
|
|
26
|
+
/**
|
|
27
|
+
* A {@link SearchModel} over Warp12's own engine, in {@link WarpAiAction} space.
|
|
28
|
+
* Hidden information (opponent hands + the draw order) is resampled by
|
|
29
|
+
* `determinize`, so the search plays honestly rather than peeking at the
|
|
30
|
+
* authoritative round state.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createWarpSearchModel(objective?: GameObjective): SearchModel<GameState, WarpAiAction>;
|
|
33
|
+
//# sourceMappingURL=search-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-model.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/search-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAO,WAAW,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,iFAAiF;AACjF,wBAAgB,QAAQ,CACtB,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CAYR;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAEjE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,SAAS,GACrB,MAAM,CAyBR;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,SAAS,GACrB,MAAM,CAoBR;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,GAAG,MAAM,CAI7E;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,GAAG,SAAS,CAgBpE;AAyBD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,GAAE,aAAyB,GACnC,WAAW,CAAC,SAAS,EAAE,YAAY,CAAC,CA4FtC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { GameState } from '../types/game-state.js';
|
|
2
|
+
import { GameModuleConfig } from '../types/modules.js';
|
|
3
|
+
import { PlayerId } from '../types/player.js';
|
|
4
|
+
import { WarpAiPlayer } from './create-warp-ai.js';
|
|
5
|
+
export interface SelfPlaySeat {
|
|
6
|
+
id: PlayerId;
|
|
7
|
+
displayName?: string;
|
|
8
|
+
player: WarpAiPlayer;
|
|
9
|
+
}
|
|
10
|
+
export interface PlaySelfPlayGameOptions {
|
|
11
|
+
seats: readonly SelfPlaySeat[];
|
|
12
|
+
seed?: number;
|
|
13
|
+
modules?: GameModuleConfig;
|
|
14
|
+
/** Safety cap so a blocked round can't loop forever (default 20000). */
|
|
15
|
+
maxSteps?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface SelfPlayGameResult {
|
|
18
|
+
/** Lowest cumulative penalty at completion; null if the game didn't finish. */
|
|
19
|
+
winnerId: PlayerId | null;
|
|
20
|
+
completed: boolean;
|
|
21
|
+
completedRounds: number;
|
|
22
|
+
steps: number;
|
|
23
|
+
penalties: Record<PlayerId, number>;
|
|
24
|
+
finalState: GameState;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Plays one full game between the supplied AI seats, driving the engine
|
|
28
|
+
* directly: act on the active captain, and tally rounds via `scoreRound` when a
|
|
29
|
+
* round ends. Deterministic for a given `seed` (and seeded players).
|
|
30
|
+
*/
|
|
31
|
+
export declare function playSelfPlayGame(options: PlaySelfPlayGameOptions): SelfPlayGameResult;
|
|
32
|
+
export interface SelfPlayMatchResult {
|
|
33
|
+
games: number;
|
|
34
|
+
completed: number;
|
|
35
|
+
/** Games each seat id won (completed games only). */
|
|
36
|
+
wins: Record<PlayerId, number>;
|
|
37
|
+
/** Cumulative penalty each seat id accrued across all games (lower = better). */
|
|
38
|
+
penalties: Record<PlayerId, number>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Runs a series of games and aggregates wins and accrued penalties per seat id.
|
|
42
|
+
* `makeSeats(gameIndex)` is called per game so callers can rebuild freshly
|
|
43
|
+
* seeded players and/or rotate seating to cancel first-mover advantage.
|
|
44
|
+
*/
|
|
45
|
+
export declare function runSelfPlayMatch(makeSeats: (gameIndex: number) => readonly SelfPlaySeat[], options: {
|
|
46
|
+
games: number;
|
|
47
|
+
seed?: number;
|
|
48
|
+
modules?: GameModuleConfig;
|
|
49
|
+
}): SelfPlayMatchResult;
|
|
50
|
+
//# sourceMappingURL=self-play.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-play.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/self-play.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,QAAQ,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,SAAS,CAAC;CACvB;AAqCD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,uBAAuB,GAC/B,kBAAkB,CAoGpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/B,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,YAAY,EAAE,EACzD,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;CAAE,GACpE,mBAAmB,CA0BrB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SkillProfile } from 'doubletwelve';
|
|
2
|
+
import { GameObjective } from '../types/objective.js';
|
|
3
|
+
declare const PENALTY_PRESETS: Record<'beginner' | 'intermediate' | 'advanced', SkillProfile>;
|
|
4
|
+
export declare const WARP_SKILL_PRESETS: Record<"beginner" | "intermediate" | "advanced", SkillProfile>;
|
|
5
|
+
export type WarpSkillLevel = keyof typeof PENALTY_PRESETS;
|
|
6
|
+
export declare function getWarpSkillProfile(level: WarpSkillLevel, objective?: GameObjective): SkillProfile;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAK3D,QAAA,MAAM,eAAe,EAAE,MAAM,CAC3B,UAAU,GAAG,cAAc,GAAG,UAAU,EACxC,YAAY,CAsDb,CAAC;AA8DF,eAAO,MAAM,kBAAkB,gEAAkB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,eAAe,CAAC;AAE1D,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,SAAS,GAAE,aAAyB,GACnC,YAAY,CAGd"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { normalizeCoordinate, Coordinate } from '../types/coordinate.js';
|
|
2
|
+
import { RoundState, TableState } from '../types/game-state.js';
|
|
3
|
+
import { GameModules } from '../types/modules.js';
|
|
4
|
+
import { GameObjective } from '../types/objective.js';
|
|
5
|
+
import { WarpAiObservation } from './observation.js';
|
|
6
|
+
export declare const N: typeof normalizeCoordinate;
|
|
7
|
+
export declare const TURN: readonly ["a", "b"];
|
|
8
|
+
export declare const TEST_CAPTAINS: {
|
|
9
|
+
id: string;
|
|
10
|
+
displayName: string;
|
|
11
|
+
penaltyScore: number;
|
|
12
|
+
}[];
|
|
13
|
+
export declare function makeRound(over: Partial<RoundState>): RoundState;
|
|
14
|
+
export declare function tableWithNeutralOpen(value: number): TableState;
|
|
15
|
+
export declare function tableWithOwnTrail(playerId: string, trailTile: Coordinate, openValue: number): TableState;
|
|
16
|
+
export declare function obsFor(round: RoundState, modules?: GameModules, objective?: GameObjective, playerId?: string): WarpAiObservation;
|
|
17
|
+
export declare function modulesWithQ(): GameModules;
|
|
18
|
+
//# sourceMappingURL=test-fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-fixtures.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/test-fixtures.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAmC,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,eAAO,MAAM,CAAC,4BAAsB,CAAC;AAErC,eAAO,MAAM,IAAI,qBAAsB,CAAC;AAExC,eAAO,MAAM,aAAa;;;;GAIzB,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAuB/D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAQ9D;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,MAAM,GAChB,UAAU,CAaZ;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,WAA6B,EACtC,SAAS,GAAE,aAAsC,EACjD,QAAQ,SAAM,GACb,iBAAiB,CAQnB;AAED,wBAAgB,YAAY,IAAI,WAAW,CAE1C"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Hand sizes by fleet size (RULES.md §II). */
|
|
2
|
+
export declare const HAND_SIZE_BY_PLAYER_COUNT: Readonly<Record<number, number>>;
|
|
3
|
+
/** Total coordinates in a double-twelve set. */
|
|
4
|
+
export declare const DOUBLE_TWELVE_SET_SIZE = 91;
|
|
5
|
+
/** Highest pip value in a double-twelve set. */
|
|
6
|
+
export declare const DOUBLE_TWELVE_MAX_PIPS = 12;
|
|
7
|
+
/** Starting Spacedock double for round 1. */
|
|
8
|
+
export declare const INITIAL_SPACEDOCK_VALUE = 12;
|
|
9
|
+
/** Standard Salamander penalty multiplier for the 12-12 tile. */
|
|
10
|
+
export declare const SALAMANDER_PENALTY_TILE_VALUE = 24;
|
|
11
|
+
export declare function handSizeForPlayerCount(playerCount: number): number;
|
|
12
|
+
export declare function spacedockValueForRound(roundNumber: number): number;
|
|
13
|
+
/** 12-12 is set aside as Spacedock in round 1; Salamander applies from round 2 onward. */
|
|
14
|
+
export declare function salamanderPenaltyApplies(roundNumber: number): boolean;
|
|
15
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/lib/constants/setup.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQtE,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,gDAAgD;AAChD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,6CAA6C;AAC7C,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,iEAAiE;AACjE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQlE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED,0FAA0F;AAC1F,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAErE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Coordinate } from '../types/coordinate.js';
|
|
2
|
+
/** Every unique coordinate in a double-twelve set (91 tiles). */
|
|
3
|
+
export declare function generateCoordinateSet(maxPips?: number): Coordinate[];
|
|
4
|
+
export declare function assertCoordinateSetSize(coordinates: readonly Coordinate[], expected?: number): void;
|
|
5
|
+
/** Fisher–Yates shuffle. Pass a seeded rng for deterministic tests. */
|
|
6
|
+
export declare function shuffleCoordinates(coordinates: readonly Coordinate[], random?: () => number): Coordinate[];
|
|
7
|
+
export declare function findCoordinateInHand(hand: readonly Coordinate[], target: Coordinate): number;
|
|
8
|
+
export declare function removeCoordinateFromHand(hand: readonly Coordinate[], target: Coordinate): {
|
|
9
|
+
hand: Coordinate[];
|
|
10
|
+
removed: Coordinate | null;
|
|
11
|
+
};
|
|
12
|
+
export declare function handContains(hand: readonly Coordinate[], target: Coordinate): boolean;
|
|
13
|
+
//# sourceMappingURL=coordinates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinates.d.ts","sourceRoot":"","sources":["../../../src/lib/domino/coordinates.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,wBAAwB,CAAC;AAGhC,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,OAAO,SAAK,GAAG,UAAU,EAAE,CAQhE;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,QAAQ,SAAyB,GAChC,IAAI,CAWN;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,MAAM,GAAE,MAAM,MAAoB,GACjC,UAAU,EAAE,CAOd;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,MAAM,EAAE,UAAU,GACjB,MAAM,CAGR;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,MAAM,EAAE,UAAU,GACjB;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAA;CAAE,CAQpD;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,MAAM,EAAE,UAAU,GACjB,OAAO,CAET"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { GameAction, ActionResult } from '../types/actions.js';
|
|
2
|
+
import { GameState, RoundState } from '../types/game-state.js';
|
|
3
|
+
import { getLegalMoves } from './legal-moves.js';
|
|
4
|
+
declare function advanceTurn(round: RoundState): RoundState;
|
|
5
|
+
export declare function applyAction(state: GameState, action: GameAction): ActionResult;
|
|
6
|
+
export { getLegalMoves, advanceTurn };
|
|
7
|
+
//# sourceMappingURL=apply-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-action.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/apply-action.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAc,MAAM,qBAAqB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAc,MAAM,wBAAwB,CAAC;AAmChF,OAAO,EAAE,aAAa,EAA2B,MAAM,kBAAkB,CAAC;AA4S1E,iBAAS,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAUlD;AA2TD,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,YAAY,CAgK9E;AAED,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { RoundState } from '../types/game-state.js';
|
|
2
|
+
import { PlayerId } from '../types/player.js';
|
|
3
|
+
/** Captain has charted at least one coordinate on their own warp trail. */
|
|
4
|
+
export declare function hasEstablishedWarpTrail(round: RoundState, playerId: PlayerId): boolean;
|
|
5
|
+
/** Must draw from Uncharted Sectors before passing when tiles remain. */
|
|
6
|
+
export declare function mustDrawBeforePassing(round: RoundState, playerId: PlayerId): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Deploy the Distress Beacon (shields down).
|
|
9
|
+
*
|
|
10
|
+
* Forced only: no legal chart moves and the draw pile is empty (or after
|
|
11
|
+
* drawing on a Red Alert pass). Matches standard Mexican Train — the marker
|
|
12
|
+
* is not deployed voluntarily while other routes are available.
|
|
13
|
+
*/
|
|
14
|
+
export declare function canDeployDistressBeacon(round: RoundState, playerId: PlayerId, options?: {
|
|
15
|
+
afterDraw?: boolean;
|
|
16
|
+
}): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* End the turn without charting when shields are already down and no other
|
|
19
|
+
* resolution applies (draw pile empty, no Red Alert pass pending).
|
|
20
|
+
*/
|
|
21
|
+
export declare function canPassTurn(round: RoundState, playerId: PlayerId, options?: {
|
|
22
|
+
afterDraw?: boolean;
|
|
23
|
+
}): boolean;
|
|
24
|
+
/** Pass a blocking Red Alert to the next captain (also deploys your beacon). */
|
|
25
|
+
export declare function canPassRedAlert(round: RoundState, playerId: PlayerId, options?: {
|
|
26
|
+
afterDraw?: boolean;
|
|
27
|
+
}): boolean;
|
|
28
|
+
/** Shields rise only by charting on your own warp trail while the beacon is active. */
|
|
29
|
+
export declare function canRaiseShieldsByCharting(round: RoundState, playerId: PlayerId): boolean;
|
|
30
|
+
//# sourceMappingURL=beacon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beacon.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/beacon.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,2EAA2E;AAC3E,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAET;AAkBD,yEAAyE;AACzE,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAKT;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAChC,OAAO,CAuBT;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAChC,OAAO,CAoBT;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAChC,OAAO,CAiBT;AAED,uFAAuF;AACvF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAQT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-red-alert.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/dead-red-alert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAQjE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GameState, RoundState } from '../types/game-state.js';
|
|
2
|
+
import { ActionViolation } from '../types/actions.js';
|
|
3
|
+
export declare function fail(violation: ActionViolation): {
|
|
4
|
+
ok: false;
|
|
5
|
+
violation: ActionViolation;
|
|
6
|
+
};
|
|
7
|
+
export declare function requireActiveRound(state: GameState): RoundState | ActionViolation;
|
|
8
|
+
export declare function requirePlayerTurn(round: RoundState, playerId: string): true | ActionViolation;
|
|
9
|
+
export declare function nextPlayerId(turnOrder: readonly string[], currentPlayerId: string): string;
|
|
10
|
+
export declare function withRound(state: GameState, round: RoundState): GameState;
|
|
11
|
+
export declare function withRoundAndCaptains(state: GameState, round: RoundState, captains: GameState['captains']): GameState;
|
|
12
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,wBAAgB,IAAI,CAAC,SAAS,EAAE,eAAe,GAAG;IAChD,EAAE,EAAE,KAAK,CAAC;IACV,SAAS,EAAE,eAAe,CAAC;CAC5B,CAEA;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,GACf,UAAU,GAAG,eAAe,CAQ9B;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,GACf,IAAI,GAAG,eAAe,CAKxB;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,eAAe,EAAE,MAAM,GACtB,MAAM,CAGR;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,UAAU,GAChB,SAAS,CAEX;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,GAC9B,SAAS,CAEX"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Coordinate, PlacedCoordinate } from '../types/coordinate.js';
|
|
2
|
+
import { ChartRoute, LegalMove } from '../types/actions.js';
|
|
3
|
+
import { RoundState } from '../types/game-state.js';
|
|
4
|
+
import { PlayerId } from '../types/player.js';
|
|
5
|
+
declare function placedTile(coordinate: Coordinate, index: number, connectingValue: number): PlacedCoordinate | null;
|
|
6
|
+
declare function canStabilizeFracture(round: RoundState, coordinate: Coordinate): boolean;
|
|
7
|
+
export declare function getLegalMoves(round: RoundState, playerId: PlayerId): LegalMove[];
|
|
8
|
+
export declare function isLegalMove(round: RoundState, playerId: PlayerId, coordinate: Coordinate, route: ChartRoute): boolean;
|
|
9
|
+
export { placedTile, canStabilizeFracture };
|
|
10
|
+
//# sourceMappingURL=legal-moves.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legal-moves.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/legal-moves.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAenD,iBAAS,UAAU,CACjB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,gBAAgB,GAAG,IAAI,CAMzB;AAoDD,iBAAS,oBAAoB,CAC3B,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,UAAU,GACrB,OAAO,CAMT;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,GACjB,SAAS,EAAE,CA6Gb;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,UAAU,GAChB,OAAO,CAOT;AAwBD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Captain, PlayerId } from '../types/player.js';
|
|
2
|
+
import { GameState, RoundState } from '../types/game-state.js';
|
|
3
|
+
import { QFlashEffect, QFlashEffectKind, QGamblePending, QRoundEffects } from '../types/q-continuum.js';
|
|
4
|
+
declare function mergeQEffects(current: QRoundEffects | null, patch: Partial<QRoundEffects>): QRoundEffects;
|
|
5
|
+
export declare function turnOrderReversed(round: RoundState): boolean;
|
|
6
|
+
export declare function consumeSkipForPlayer(effects: QRoundEffects | null, playerId: PlayerId): QRoundEffects | null;
|
|
7
|
+
export declare function nextActivePlayerId(round: RoundState, currentPlayerId: PlayerId): PlayerId;
|
|
8
|
+
export declare function advanceActivePlayer(round: RoundState): RoundState;
|
|
9
|
+
export declare function lowestPenaltyCaptainId(captains: readonly Captain[]): PlayerId | null;
|
|
10
|
+
export declare function highestPenaltyCaptainId(captains: readonly Captain[], excludeId?: PlayerId): PlayerId | null;
|
|
11
|
+
export declare function buildQFlashEffect(kind: QFlashEffectKind, state: GameState, round: RoundState, invokerId: PlayerId): QFlashEffect | null;
|
|
12
|
+
export declare function applyQFlashEffect(round: RoundState, effect: QFlashEffect, invokerId: PlayerId): {
|
|
13
|
+
round: RoundState;
|
|
14
|
+
gamble: QGamblePending | null;
|
|
15
|
+
};
|
|
16
|
+
export declare function clearTemporalInversionOnDouble(round: RoundState): RoundState;
|
|
17
|
+
export declare function consumeFractureImmunity(round: RoundState): {
|
|
18
|
+
round: RoundState;
|
|
19
|
+
consumed: boolean;
|
|
20
|
+
};
|
|
21
|
+
export declare function resolveQGamble(round: RoundState, playerId: PlayerId, keepIndex: 0 | 1): RoundState;
|
|
22
|
+
export declare function treatyRequiredForWin(round: RoundState, routeKind: import('../types/actions.js').ChartRoute['kind']): boolean;
|
|
23
|
+
export declare function trailsOpenToOthers(round: RoundState, trailPlayerId: PlayerId): boolean;
|
|
24
|
+
export { mergeQEffects };
|
|
25
|
+
//# sourceMappingURL=q-continuum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"q-continuum.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/q-continuum.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,yBAAyB,CAAC;AAGjC,iBAAS,aAAa,CACpB,OAAO,EAAE,aAAa,GAAG,IAAI,EAC7B,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,aAAa,CAsBf;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAM5D;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,GAAG,IAAI,EAC7B,QAAQ,EAAE,QAAQ,GACjB,aAAa,GAAG,IAAI,CAOtB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,QAAQ,GACxB,QAAQ,CAgBV;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAOjE;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,QAAQ,GAAG,IAAI,CAOjB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,SAAS,CAAC,EAAE,QAAQ,GACnB,QAAQ,GAAG,IAAI,CAUjB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,QAAQ,GAClB,YAAY,GAAG,IAAI,CAgCrB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,QAAQ,GAClB;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAA;CAAE,CAuFtD;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,UAAU,GAChB,UAAU,CAQZ;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,GAChB;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAW1C;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,CAAC,GAAG,CAAC,GACf,UAAU,CAkBZ;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,OAAO,qBAAqB,EAAE,UAAU,CAAC,MAAM,CAAC,GAC1D,OAAO,CAKT;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,GAAG,OAAO,CAKtF;AAGD,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ChartRoute } from '../types/actions.js';
|
|
2
|
+
import { RoundState } from '../types/game-state.js';
|
|
3
|
+
/** Draw pile empty and no captain can chart anywhere (after dead-double resolution). */
|
|
4
|
+
export declare function isRoundBlocked(round: RoundState): boolean;
|
|
5
|
+
export declare function endBlockedRound(round: RoundState): RoundState;
|
|
6
|
+
export declare function maybeEndBlockedRound(round: RoundState): RoundState;
|
|
7
|
+
export interface PendingRoundWin {
|
|
8
|
+
readonly playerId: string;
|
|
9
|
+
readonly routeKind: ChartRoute['kind'];
|
|
10
|
+
}
|
|
11
|
+
export declare function applyPendingRoundWin(round: RoundState): RoundState;
|
|
12
|
+
export declare function finalizeRoundWinAfterQ(round: RoundState): RoundState;
|
|
13
|
+
//# sourceMappingURL=round-resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"round-resolution.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/round-resolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKzD,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CA4BzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAW7D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAMlE;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAelE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAMpE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GameState, RoundState } from '../types/game-state.js';
|
|
2
|
+
import { ActionResult } from '../types/actions.js';
|
|
3
|
+
/** Pip penalty for tiles still in hand (same rules as end-of-round scoring). */
|
|
4
|
+
export declare function handPenaltyPoints(hand: readonly {
|
|
5
|
+
low: number;
|
|
6
|
+
high: number;
|
|
7
|
+
}[], salamanderEnabled: boolean, roundNumber: number): number;
|
|
8
|
+
export declare function scoreRound(state: GameState, round: RoundState, random?: () => number): ActionResult;
|
|
9
|
+
//# sourceMappingURL=scoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/scoring.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAsCxD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAC9C,iBAAiB,EAAE,OAAO,EAC1B,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAiED,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,UAAU,EACjB,MAAM,GAAE,MAAM,MAAoB,GACjC,YAAY,CAgEd"}
|