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.
Files changed (83) hide show
  1. package/README.md +25 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +2028 -0
  5. package/dist/lib/ai/actions.d.ts +32 -0
  6. package/dist/lib/ai/actions.d.ts.map +1 -0
  7. package/dist/lib/ai/candidate-generator.d.ts +20 -0
  8. package/dist/lib/ai/candidate-generator.d.ts.map +1 -0
  9. package/dist/lib/ai/context.d.ts +19 -0
  10. package/dist/lib/ai/context.d.ts.map +1 -0
  11. package/dist/lib/ai/create-warp-ai.d.ts +49 -0
  12. package/dist/lib/ai/create-warp-ai.d.ts.map +1 -0
  13. package/dist/lib/ai/explain-action.d.ts +8 -0
  14. package/dist/lib/ai/explain-action.d.ts.map +1 -0
  15. package/dist/lib/ai/heuristics.d.ts +21 -0
  16. package/dist/lib/ai/heuristics.d.ts.map +1 -0
  17. package/dist/lib/ai/index.d.ts +19 -0
  18. package/dist/lib/ai/index.d.ts.map +1 -0
  19. package/dist/lib/ai/observation.d.ts +20 -0
  20. package/dist/lib/ai/observation.d.ts.map +1 -0
  21. package/dist/lib/ai/q-flash.d.ts +11 -0
  22. package/dist/lib/ai/q-flash.d.ts.map +1 -0
  23. package/dist/lib/ai/search-model.d.ts +33 -0
  24. package/dist/lib/ai/search-model.d.ts.map +1 -0
  25. package/dist/lib/ai/self-play.d.ts +50 -0
  26. package/dist/lib/ai/self-play.d.ts.map +1 -0
  27. package/dist/lib/ai/skill.d.ts +8 -0
  28. package/dist/lib/ai/skill.d.ts.map +1 -0
  29. package/dist/lib/ai/test-fixtures.d.ts +18 -0
  30. package/dist/lib/ai/test-fixtures.d.ts.map +1 -0
  31. package/dist/lib/constants/setup.d.ts +15 -0
  32. package/dist/lib/constants/setup.d.ts.map +1 -0
  33. package/dist/lib/domino/coordinates.d.ts +13 -0
  34. package/dist/lib/domino/coordinates.d.ts.map +1 -0
  35. package/dist/lib/engine/apply-action.d.ts +7 -0
  36. package/dist/lib/engine/apply-action.d.ts.map +1 -0
  37. package/dist/lib/engine/beacon.d.ts +30 -0
  38. package/dist/lib/engine/beacon.d.ts.map +1 -0
  39. package/dist/lib/engine/dead-red-alert.d.ts +4 -0
  40. package/dist/lib/engine/dead-red-alert.d.ts.map +1 -0
  41. package/dist/lib/engine/helpers.d.ts +12 -0
  42. package/dist/lib/engine/helpers.d.ts.map +1 -0
  43. package/dist/lib/engine/legal-moves.d.ts +10 -0
  44. package/dist/lib/engine/legal-moves.d.ts.map +1 -0
  45. package/dist/lib/engine/q-continuum.d.ts +25 -0
  46. package/dist/lib/engine/q-continuum.d.ts.map +1 -0
  47. package/dist/lib/engine/round-resolution.d.ts +13 -0
  48. package/dist/lib/engine/round-resolution.d.ts.map +1 -0
  49. package/dist/lib/engine/scoring.d.ts +9 -0
  50. package/dist/lib/engine/scoring.d.ts.map +1 -0
  51. package/dist/lib/engine/test-helpers.d.ts +26 -0
  52. package/dist/lib/engine/test-helpers.d.ts.map +1 -0
  53. package/dist/lib/fixtures/create-demo-game.d.ts +17 -0
  54. package/dist/lib/fixtures/create-demo-game.d.ts.map +1 -0
  55. package/dist/lib/setup/create-game.d.ts +51 -0
  56. package/dist/lib/setup/create-game.d.ts.map +1 -0
  57. package/dist/lib/table/pip-inventory.d.ts +12 -0
  58. package/dist/lib/table/pip-inventory.d.ts.map +1 -0
  59. package/dist/lib/table/table-state.d.ts +14 -0
  60. package/dist/lib/table/table-state.d.ts.map +1 -0
  61. package/dist/lib/types/actions.d.ts +64 -0
  62. package/dist/lib/types/actions.d.ts.map +1 -0
  63. package/dist/lib/types/anomalies.d.ts +29 -0
  64. package/dist/lib/types/anomalies.d.ts.map +1 -0
  65. package/dist/lib/types/coordinate.d.ts +22 -0
  66. package/dist/lib/types/coordinate.d.ts.map +1 -0
  67. package/dist/lib/types/game-state.d.ts +73 -0
  68. package/dist/lib/types/game-state.d.ts.map +1 -0
  69. package/dist/lib/types/modules.d.ts +32 -0
  70. package/dist/lib/types/modules.d.ts.map +1 -0
  71. package/dist/lib/types/objective.d.ts +5 -0
  72. package/dist/lib/types/objective.d.ts.map +1 -0
  73. package/dist/lib/types/player.d.ts +12 -0
  74. package/dist/lib/types/player.d.ts.map +1 -0
  75. package/dist/lib/types/q-continuum.d.ts +50 -0
  76. package/dist/lib/types/q-continuum.d.ts.map +1 -0
  77. package/dist/lib/types/trails.d.ts +20 -0
  78. package/dist/lib/types/trails.d.ts.map +1 -0
  79. package/dist/lib/violations/format-violation.d.ts +3 -0
  80. package/dist/lib/violations/format-violation.d.ts.map +1 -0
  81. package/dist/lib/warp12-lib.d.ts +22 -0
  82. package/dist/lib/warp12-lib.d.ts.map +1 -0
  83. package/package.json +50 -0
@@ -0,0 +1,26 @@
1
+ import { normalizeCoordinate, Coordinate, PlacedCoordinate } from '../types/coordinate.js';
2
+ import { GameState, RoundState } from '../types/game-state.js';
3
+ import { PlayerId } from '../types/player.js';
4
+ export declare const T: typeof normalizeCoordinate;
5
+ export declare const DEFAULT_CAPTAINS: readonly [{
6
+ readonly id: "a";
7
+ readonly displayName: "Alpha";
8
+ readonly penaltyScore: 0;
9
+ }, {
10
+ readonly id: "b";
11
+ readonly displayName: "Beta";
12
+ readonly penaltyScore: 0;
13
+ }, {
14
+ readonly id: "c";
15
+ readonly displayName: "Charlie";
16
+ readonly penaltyScore: 0;
17
+ }];
18
+ export declare function placed(coordinate: Coordinate, index: number, openValue: number): PlacedCoordinate;
19
+ /** Every unique tile in a double-twelve set that contains `pip`. */
20
+ export declare function allTilesWithPip(pip: number, maxPips?: number): Coordinate[];
21
+ export declare function emptyRoundFields(): Pick<RoundState, 'mandatoryPlay' | 'pendingRoundWin' | 'roundBlocked' | 'qPendingInvoker' | 'qEffects' | 'qGamblePending' | 'treatyDeclarationRequired' | 'treatyDeclared' | 'roundWinnerId'>;
22
+ export declare function makeRound(turnOrder: readonly PlayerId[], over?: Partial<RoundState>): RoundState;
23
+ export declare function makeGame(round: RoundState, over?: Partial<GameState>): GameState;
24
+ /** Spread charted tiles across trails and neutral zone for table setup. */
25
+ export declare function chartTilesOnTable(round: RoundState, tiles: readonly Coordinate[], hostPlayerId?: PlayerId): RoundState['table'];
26
+ //# sourceMappingURL=test-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/test-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,eAAO,MAAM,CAAC,4BAAsB,CAAC;AAErC,eAAO,MAAM,gBAAgB;;;;;;;;;;;;EAInB,CAAC;AAEX,wBAAgB,MAAM,CACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAElB;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,SAAK,GAAG,UAAU,EAAE,CAQvE;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CACtC,UAAU,EACR,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,iBAAiB,GACjB,UAAU,GACV,gBAAgB,GAChB,2BAA2B,GAC3B,gBAAgB,GAChB,eAAe,CAClB,CAYA;AAED,wBAAgB,SAAS,CACvB,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,IAAI,GAAE,OAAO,CAAC,UAAU,CAAM,GAC7B,UAAU,CAeZ;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE,OAAO,CAAC,SAAS,CAAM,GAC5B,SAAS,CAeX;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,YAAY,GAAE,QAA6B,GAC1C,UAAU,CAAC,OAAO,CAAC,CA+BrB"}
@@ -0,0 +1,17 @@
1
+ import { GameState } from '../types/game-state.js';
2
+ export declare const DEMO_CAPTAINS: readonly [{
3
+ readonly id: "you";
4
+ readonly displayName: "You";
5
+ }, {
6
+ readonly id: "riker";
7
+ readonly displayName: "Riker";
8
+ }, {
9
+ readonly id: "troi";
10
+ readonly displayName: "Troi";
11
+ }, {
12
+ readonly id: "worf";
13
+ readonly displayName: "Worf";
14
+ }];
15
+ export declare function createDemoGame(seed?: number): GameState;
16
+ export declare function captainNameMap(state: GameState): Readonly<Record<string, string>>;
17
+ //# sourceMappingURL=create-demo-game.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-demo-game.d.ts","sourceRoot":"","sources":["../../../src/lib/fixtures/create-demo-game.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGxD,eAAO,MAAM,aAAa;;;;;;;;;;;;EAKhB,CAAC;AAUX,wBAAgB,cAAc,CAAC,IAAI,SAAa,GAAG,SAAS,CAc3D;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,GACf,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAIlC"}
@@ -0,0 +1,51 @@
1
+ import { Coordinate } from '../types/coordinate.js';
2
+ import { createInitialTable } from '../table/table-state.js';
3
+ import { CreateGameInput, GameState, RoundState } from '../types/game-state.js';
4
+ import { Captain, PlayerId } from '../types/player.js';
5
+ export declare function createCaptain(id: string, displayName: string): Captain;
6
+ export declare function createLobbyState(input: CreateGameInput): GameState;
7
+ export interface RoundDealResult {
8
+ readonly roundNumber: number;
9
+ readonly captains: readonly Captain[];
10
+ readonly turnOrder: readonly PlayerId[];
11
+ readonly spacedockValue: number;
12
+ readonly spacedockPlacedBy: PlayerId;
13
+ readonly hands: Readonly<Record<PlayerId, readonly Coordinate[]>>;
14
+ readonly unchartedSectors: readonly Coordinate[];
15
+ }
16
+ /** Round starter rotates clockwise through turn order (standard Mexican Train). */
17
+ export declare function roundStarterForRound(turnOrder: readonly PlayerId[], roundNumber: number): PlayerId;
18
+ /**
19
+ * Deal a round per standard Mexican Train setup: set aside the round Spacedock
20
+ * double before dealing hands; remaining tiles form Uncharted Sectors.
21
+ */
22
+ export declare function dealRoundFromShuffled(input: {
23
+ readonly shuffledCoordinates: readonly Coordinate[];
24
+ readonly roundNumber: number;
25
+ readonly captains: readonly Captain[];
26
+ readonly turnOrder: readonly PlayerId[];
27
+ readonly roundStarterId?: PlayerId;
28
+ }): RoundDealResult;
29
+ export declare function createRoundStateFromDeal(deal: RoundDealResult): RoundState;
30
+ /** @deprecated Use dealRoundFromShuffled — Spacedock is set aside before dealing. */
31
+ export interface DealRoundInput {
32
+ roundNumber: number;
33
+ captains: readonly Captain[];
34
+ shuffledCoordinates: readonly Coordinate[];
35
+ spacedockPlacedBy: PlayerId;
36
+ turnOrder: readonly PlayerId[];
37
+ table: ReturnType<typeof createInitialTable>;
38
+ }
39
+ /** @deprecated Use dealRoundFromShuffled + createRoundStateFromDeal. */
40
+ export declare function createRoundState(input: DealRoundInput): RoundState;
41
+ export interface StartGameInput {
42
+ shuffledCoordinates: readonly Coordinate[];
43
+ /** Round-one starter; defaults to the first captain in turn order. */
44
+ roundStarterId?: PlayerId;
45
+ }
46
+ export declare function startGame(input: CreateGameInput, deal: StartGameInput): GameState;
47
+ /** Gather every coordinate from a finished round for the next shuffle. */
48
+ export declare function collectRoundCoordinatesForRecycle(round: RoundState): Coordinate[];
49
+ /** @deprecated Spacedock is set aside before dealing; use roundStarterForRound instead. */
50
+ export declare function findSpacedockHolder(hands: Readonly<Record<PlayerId, readonly Coordinate[]>>, spacedockValue: number): PlayerId | null;
51
+ //# sourceMappingURL=create-game.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-game.d.ts","sourceRoot":"","sources":["../../../src/lib/setup/create-game.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAI5D,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,GAClB,OAAO,CAET;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,CAUlE;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IACxC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC;IAClE,QAAQ,CAAC,gBAAgB,EAAE,SAAS,UAAU,EAAE,CAAC;CAClD;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,WAAW,EAAE,MAAM,GAClB,QAAQ,CAKV;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,QAAQ,CAAC,mBAAmB,EAAE,SAAS,UAAU,EAAE,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC;CACpC,GAAG,eAAe,CAuClB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,UAAU,CAwB1E;AAED,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,mBAAmB,EAAE,SAAS,UAAU,EAAE,CAAC;IAC3C,iBAAiB,EAAE,QAAQ,CAAC;IAC5B,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC/B,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;CAC9C;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CASlE;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB,EAAE,SAAS,UAAU,EAAE,CAAC;IAC3C,sEAAsE;IACtE,cAAc,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,cAAc,GACnB,SAAS,CAgBX;AAED,0EAA0E;AAC1E,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,UAAU,GAChB,UAAU,EAAE,CA6Bd;AAED,2FAA2F;AAC3F,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC,CAAC,EACxD,cAAc,EAAE,MAAM,GACrB,QAAQ,GAAG,IAAI,CAUjB"}
@@ -0,0 +1,12 @@
1
+ import { Coordinate } from '../types/coordinate.js';
2
+ import { RoundState } from '../types/game-state.js';
3
+ /** Tiles in a double-N set that contain pip `pip` (e.g. thirteen sixes in double-twelve). */
4
+ export declare function maxTilesWithPipInSet(pip: number, maxPips?: number): number;
5
+ export declare function coordinateContainsPip(coordinate: Coordinate, pip: number): boolean;
6
+ /** Count tiles on the table whose pip values include `pip`. */
7
+ export declare function countChartedTilesWithPip(round: RoundState, pip: number): number;
8
+ /** True when every tile in the set containing `pip` is already charted. */
9
+ export declare function isPipExhausted(round: RoundState, pip: number, maxPips?: number): boolean;
10
+ /** Red Alert double is dead when no tile with that pip remains off the table. */
11
+ export declare function isRedAlertDoubleDead(round: RoundState): boolean;
12
+ //# sourceMappingURL=pip-inventory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pip-inventory.d.ts","sourceRoot":"","sources":["../../../src/lib/table/pip-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,SAAyB,GAC/B,MAAM,CAKR;AAwBD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAElF;AAED,+DAA+D;AAC/D,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,GACV,MAAM,CAQR;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,SAAyB,GAC/B,OAAO,CAIT;AAED,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAU/D"}
@@ -0,0 +1,14 @@
1
+ import { TableState } from '../types/game-state.js';
2
+ import { PlayerId } from '../types/player.js';
3
+ import { NeutralZone, WarpTrail } from '../types/trails.js';
4
+ export declare function createInitialTable(playerIds: readonly PlayerId[], spacedockValue: number, spacedockPlacedBy: PlayerId): TableState;
5
+ export declare function trailOpenValue(trail: WarpTrail, spacedockValue: number): number;
6
+ export declare function neutralZoneOpenValue(zone: NeutralZone, spacedockValue: number): number;
7
+ export declare function isUncoveredDoubleAtTrailEnd(trail: WarpTrail): boolean;
8
+ export declare function isUncoveredDoubleAtNeutralZoneEnd(zone: NeutralZone): boolean;
9
+ /** Any trail or neutral zone ends on an open (uncovered) double. */
10
+ export declare function hasUncoveredDoubleOnTable(table: TableState): boolean;
11
+ /** Charted doubles on warp trails and the neutral zone (excludes Spacedock). */
12
+ export declare function countDoublesOnTable(table: TableState): number;
13
+ export declare function countActiveDistressBeacons(table: TableState): number;
14
+ //# sourceMappingURL=table-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-state.d.ts","sourceRoot":"","sources":["../../../src/lib/table/table-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEjE,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,QAAQ,GAC1B,UAAU,CAkBZ;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,EAChB,cAAc,EAAE,MAAM,GACrB,MAAM,CAKR;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,WAAW,EACjB,cAAc,EAAE,MAAM,GACrB,MAAM,CAKR;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAOrE;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAO5E;AAED,oEAAoE;AACpE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAUpE;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAe7D;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAQpE"}
@@ -0,0 +1,64 @@
1
+ import { Coordinate } from './coordinate.js';
2
+ import { PlayerId } from './player.js';
3
+ import { QFlashEffectKind } from './q-continuum.js';
4
+ /** Route a coordinate may be charted onto. */
5
+ export type ChartRoute = {
6
+ kind: 'warp-trail';
7
+ playerId: PlayerId;
8
+ } | {
9
+ kind: 'neutral-zone';
10
+ } | {
11
+ kind: 'fracture-stabilizer';
12
+ } | {
13
+ kind: 'red-alert-cover';
14
+ trailPlayerId?: PlayerId;
15
+ neutralZone?: true;
16
+ };
17
+ export type GameAction = {
18
+ type: 'CHART_COORDINATE';
19
+ playerId: PlayerId;
20
+ coordinate: Coordinate;
21
+ route: ChartRoute;
22
+ } | {
23
+ type: 'DRAW_FROM_UNCHARTED';
24
+ playerId: PlayerId;
25
+ } | {
26
+ type: 'PASS_RED_ALERT';
27
+ playerId: PlayerId;
28
+ } | {
29
+ type: 'PASS_TURN';
30
+ playerId: PlayerId;
31
+ } | {
32
+ type: 'DEPLOY_DISTRESS_BEACON';
33
+ playerId: PlayerId;
34
+ } | {
35
+ type: 'DECLARE_TREATY';
36
+ playerId: PlayerId;
37
+ } | {
38
+ type: 'FORFEIT_IMPULSE';
39
+ playerId: PlayerId;
40
+ } | {
41
+ type: 'INVOKE_Q_FLASH';
42
+ playerId: PlayerId;
43
+ effect: QFlashEffectKind;
44
+ } | {
45
+ type: 'RESOLVE_Q_GAMBLE';
46
+ playerId: PlayerId;
47
+ keepIndex: 0 | 1;
48
+ } | {
49
+ type: 'END_ROUND';
50
+ winnerId: PlayerId | null;
51
+ };
52
+ export type ActionResult = {
53
+ ok: true;
54
+ state: import('./game-state.js').GameState;
55
+ } | {
56
+ ok: false;
57
+ violation: ActionViolation;
58
+ };
59
+ export type ActionViolation = 'NOT_YOUR_TURN' | 'GAME_NOT_ACTIVE' | 'ROUND_NOT_PLAYING' | 'COORDINATE_NOT_IN_HAND' | 'INVALID_ROUTE' | 'SHIELDS_UP' | 'NAVIGATION_HALTED' | 'RED_ALERT_REQUIRED' | 'FRACTURE_REQUIRES_STABILIZER' | 'EMPTY_UNCHARTED' | 'TREATY_NOT_REQUIRED' | 'RED_ALERT_NOT_ACTIVE' | 'Q_FLASH_NOT_PENDING' | 'Q_GAMBLE_NOT_PENDING' | 'Q_FLASH_UNAVAILABLE' | 'BEACON_NOT_ALLOWED' | 'BEACON_ALREADY_ACTIVE' | 'MUST_DRAW_FIRST' | 'RED_ALERT_COVER_AVAILABLE' | 'PASS_NOT_ALLOWED' | 'IMPULSE_FORFEIT_NOT_ALLOWED';
60
+ export interface LegalMove {
61
+ coordinate: Coordinate;
62
+ route: ChartRoute;
63
+ }
64
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/lib/types/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,8CAA8C;AAC9C,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,aAAa,CAAC,EAAE,QAAQ,CAAC;IAAC,WAAW,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAE9E,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,wBAAwB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,CAAC;AAErD,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,iBAAiB,EAAE,SAAS,CAAA;CAAE,GACxD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC;AAE9C,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,iBAAiB,GACjB,mBAAmB,GACnB,wBAAwB,GACxB,eAAe,GACf,YAAY,GACZ,mBAAmB,GACnB,oBAAoB,GACpB,8BAA8B,GAC9B,iBAAiB,GACjB,qBAAqB,GACrB,sBAAsB,GACtB,qBAAqB,GACrB,sBAAsB,GACtB,qBAAqB,GACrB,oBAAoB,GACpB,uBAAuB,GACvB,iBAAiB,GACjB,2BAA2B,GAC3B,kBAAkB,GAClB,6BAA6B,CAAC;AAElC,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;CACnB"}
@@ -0,0 +1,29 @@
1
+ import { PlacedCoordinate } from './coordinate.js';
2
+ import { RoundState } from './game-state.js';
3
+ /**
4
+ * Subspace Fracture (Chicken Foot) — fleet navigation halts until three
5
+ * stabilizing coordinates branch from the fracture double.
6
+ */
7
+ export interface SubspaceFracture {
8
+ readonly active: boolean;
9
+ readonly anchor: PlacedCoordinate;
10
+ readonly stabilizers: readonly PlacedCoordinate[];
11
+ readonly requiredValue: number;
12
+ }
13
+ /** Red Alert — a double must be covered before the turn can advance. */
14
+ export interface RedAlert {
15
+ readonly active: boolean;
16
+ readonly anchor: PlacedCoordinate;
17
+ readonly responsiblePlayerId: string | null;
18
+ /** Warp trail hosting the uncovered double (ignored when neutralZone is true). */
19
+ readonly trailPlayerId: string;
20
+ /** Uncovered double was charted on the Neutral Zone. */
21
+ readonly neutralZone?: boolean;
22
+ }
23
+ export declare function stabilizersPlaced(fracture: SubspaceFracture): 0 | 1 | 2 | 3;
24
+ export declare function isFractureResolved(fracture: SubspaceFracture | null): boolean;
25
+ export declare function isNavigationHaltedByFracture(fracture: SubspaceFracture | null): boolean;
26
+ export declare function isRedAlertBlocking(redAlert: RedAlert | null, playerId: string): boolean;
27
+ /** Active Red Alert that still requires a cover tile (excludes dead doubles). */
28
+ export declare function isTrueRedAlert(round: RoundState): boolean;
29
+ //# sourceMappingURL=anomalies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anomalies.d.ts","sourceRoot":"","sources":["../../../src/lib/types/anomalies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAClD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,wEAAwE;AACxE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,kFAAkF;IAClF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,wDAAwD;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,GACzB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAEf;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAE7E;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAChC,OAAO,CAET;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,GAAG,IAAI,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAIT;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAMzD"}
@@ -0,0 +1,22 @@
1
+ /** A domino tile (Navigational Coordinate), canonical low–high. */
2
+ export interface Coordinate {
3
+ readonly low: number;
4
+ readonly high: number;
5
+ }
6
+ /** A coordinate placed on a trail or in the fracture. */
7
+ export interface PlacedCoordinate {
8
+ readonly coordinate: Coordinate;
9
+ /** Index within the parent trail or branch. */
10
+ readonly index: number;
11
+ /** Pip value open for the next connection along this trail. */
12
+ readonly openValue: number;
13
+ }
14
+ export declare function coordinateKey({ low, high }: Coordinate): string;
15
+ export declare function isDouble({ low, high }: Coordinate): boolean;
16
+ export declare function coordinatePipValue({ low, high }: Coordinate): number;
17
+ export declare function normalizeCoordinate(a: number, b: number): Coordinate;
18
+ export declare function coordinatesEqual(a: Coordinate, b: Coordinate): boolean;
19
+ export declare function coordinateMatchesValue({ low, high }: Coordinate, value: number): boolean;
20
+ /** Open end after connecting `coordinate` to `connectingValue`. */
21
+ export declare function openValueAfterConnection(coordinate: Coordinate, connectingValue: number): number | null;
22
+ //# sourceMappingURL=coordinate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate.d.ts","sourceRoot":"","sources":["../../../src/lib/types/coordinate.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,UAAU,GAAG,MAAM,CAE/D;AAED,wBAAgB,QAAQ,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,UAAU,GAAG,OAAO,CAE3D;AAED,wBAAgB,kBAAkB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,UAAU,GAAG,MAAM,CAEpE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAEpE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAEtE;AAED,wBAAgB,sBAAsB,CACpC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,UAAU,EACzB,KAAK,EAAE,MAAM,GACZ,OAAO,CAET;AAED,mEAAmE;AACnE,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,MAAM,GACtB,MAAM,GAAG,IAAI,CAQf"}
@@ -0,0 +1,73 @@
1
+ import { Coordinate } from './coordinate.js';
2
+ import { GameObjective } from './objective.js';
3
+ import { PlayerId } from './player.js';
4
+ import { NeutralZone, Spacedock, WarpTrail } from './trails.js';
5
+ import { RedAlert, SubspaceFracture } from './anomalies.js';
6
+ import { QGamblePending, QRoundEffects } from './q-continuum.js';
7
+ import { ChartRoute } from './actions.js';
8
+ export type GamePhase = 'lobby' | 'active' | 'round-end' | 'complete';
9
+ export type RoundPhase = 'setup' | 'playing' | 'ended';
10
+ export interface TableState {
11
+ readonly spacedock: Spacedock;
12
+ readonly warpTrails: Readonly<Record<PlayerId, WarpTrail>>;
13
+ readonly neutralZone: NeutralZone;
14
+ readonly subspaceFracture: SubspaceFracture | null;
15
+ readonly redAlert: RedAlert | null;
16
+ }
17
+ export interface RoundState {
18
+ readonly roundNumber: number;
19
+ readonly spacedockValue: number;
20
+ readonly phase: RoundPhase;
21
+ readonly activePlayerId: PlayerId;
22
+ readonly turnOrder: readonly PlayerId[];
23
+ readonly table: TableState;
24
+ readonly unchartedSectors: readonly Coordinate[];
25
+ readonly hands: Readonly<Record<PlayerId, readonly Coordinate[]>>;
26
+ readonly treatyDeclarationRequired: boolean;
27
+ readonly treatyDeclared: boolean;
28
+ readonly roundWinnerId: PlayerId | null;
29
+ /** Captain who must invoke a Q-Flash after charting 0-0. */
30
+ readonly qPendingInvoker: PlayerId | null;
31
+ /** Active Q-Flash mechanical effects for this round. */
32
+ readonly qEffects: QRoundEffects | null;
33
+ /** Awaiting keep/discard after Q's gamble. */
34
+ readonly qGamblePending: QGamblePending | null;
35
+ /** After a draw, this tile must be charted immediately if playable. */
36
+ readonly mandatoryPlay: {
37
+ readonly playerId: PlayerId;
38
+ readonly coordinate: Coordinate;
39
+ } | null;
40
+ /** Win deferred until a pending Q-Flash resolves. */
41
+ readonly pendingRoundWin: {
42
+ readonly playerId: PlayerId;
43
+ readonly routeKind: ChartRoute['kind'];
44
+ } | null;
45
+ /** Sector ended with an empty draw pile and no legal charts (no domino winner). */
46
+ readonly roundBlocked: boolean;
47
+ }
48
+ export interface GameState {
49
+ readonly id: string;
50
+ readonly phase: GamePhase;
51
+ readonly captains: readonly import('./player.js').Captain[];
52
+ readonly round: RoundState | null;
53
+ readonly completedRounds: number;
54
+ readonly modules: import('./modules.js').GameModules;
55
+ /** Fleet victory condition — penalty campaign vs first captain out. */
56
+ readonly objective: GameObjective;
57
+ }
58
+ export interface CreateGameInput {
59
+ readonly id: string;
60
+ readonly captains: readonly {
61
+ id: string;
62
+ displayName: string;
63
+ }[];
64
+ readonly modules?: import('./modules.js').GameModuleConfig;
65
+ readonly objective?: GameObjective;
66
+ }
67
+ export interface CreateRoundInput {
68
+ readonly roundNumber: number;
69
+ readonly captains: readonly import('./player.js').Captain[];
70
+ readonly shuffledCoordinates: readonly Coordinate[];
71
+ readonly roundStarterId?: PlayerId;
72
+ }
73
+ //# sourceMappingURL=game-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game-state.d.ts","sourceRoot":"","sources":["../../../src/lib/types/game-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { QFlashEffect } from './q-continuum.js';
2
+ /** Module Alpha: The Q-Continuum — 0-0 triggers reality-bending rule changes. */
3
+ export interface QContinuumModule {
4
+ readonly enabled: boolean;
5
+ /** Active Q-Flash effect for the current round, if any. */
6
+ readonly activeFlash: QFlash | null;
7
+ }
8
+ export interface QFlash {
9
+ readonly invokedBy: string;
10
+ readonly effect: QFlashEffect;
11
+ }
12
+ /** Module Beta: The Salamander Penalty — holding 12-12 at round end costs 24 (round 2+). */
13
+ export interface SalamanderPenaltyModule {
14
+ readonly enabled: boolean;
15
+ }
16
+ /** Subspace Fracture (chicken foot) — doubles halt the fleet until three stabilizers branch off. */
17
+ export interface SubspaceFractureModule {
18
+ readonly enabled: boolean;
19
+ }
20
+ export interface GameModules {
21
+ readonly qContinuum: QContinuumModule;
22
+ readonly salamanderPenalty: SalamanderPenaltyModule;
23
+ readonly subspaceFracture: SubspaceFractureModule;
24
+ }
25
+ export declare const DEFAULT_MODULES: GameModules;
26
+ export interface GameModuleConfig {
27
+ qContinuum?: boolean;
28
+ salamanderPenalty?: boolean;
29
+ subspaceFracture?: boolean;
30
+ }
31
+ export declare function resolveModules(config?: GameModuleConfig): GameModules;
32
+ //# sourceMappingURL=modules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../../../src/lib/types/modules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED,4FAA4F;AAC5F,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,oGAAoG;AACpG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,iBAAiB,EAAE,uBAAuB,CAAC;IACpD,QAAQ,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;CACnD;AAED,eAAO,MAAM,eAAe,EAAE,WAI7B,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,MAAM,GAAE,gBAAqB,GAAG,WAAW,CAazE"}
@@ -0,0 +1,5 @@
1
+ /** How the fleet decides the victor — matches house rules at the table. */
2
+ export type GameObjective = 'penalty' | 'go-out';
3
+ export declare const DEFAULT_GAME_OBJECTIVE: GameObjective;
4
+ export declare const GAME_OBJECTIVE_LABELS: Record<GameObjective, string>;
5
+ //# sourceMappingURL=objective.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objective.d.ts","sourceRoot":"","sources":["../../../src/lib/types/objective.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEjD,eAAO,MAAM,sBAAsB,EAAE,aAAyB,CAAC;AAE/D,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAG/D,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** Distress Beacon — other captains may chart on this warp trail while active. */
2
+ export interface DistressBeacon {
3
+ readonly active: boolean;
4
+ }
5
+ export interface Captain {
6
+ readonly id: string;
7
+ readonly displayName: string;
8
+ /** Cumulative penalty score across completed rounds. */
9
+ readonly penaltyScore: number;
10
+ }
11
+ export type PlayerId = Captain['id'];
12
+ //# sourceMappingURL=player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../../../src/lib/types/player.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { Coordinate } from './coordinate.js';
2
+ import { Captain, PlayerId } from './player.js';
3
+ import { GameModules } from './modules.js';
4
+ import { RoundState } from './game-state.js';
5
+ /** Catalog of reality-bending Q-Flash effects (Module Alpha). */
6
+ export type QFlashEffectKind = 'reverse-turn-order' | 'skip-lowest-penalty' | 'peek-uncharted' | 'temporal-inversion' | 'distress-amplification' | 'fracture-immunity' | 'salamander-swap' | 'treaty-echo' | 'q-gamble';
7
+ export interface QFlashEffect {
8
+ readonly kind: QFlashEffectKind;
9
+ readonly targetPlayerId?: PlayerId;
10
+ readonly peek?: Readonly<{
11
+ index: number;
12
+ coordinate: Coordinate;
13
+ }>;
14
+ }
15
+ export interface QRoundEffects {
16
+ readonly reverseTurnOrder: boolean;
17
+ /** Reverse turn order until the next double is charted. */
18
+ readonly temporalInversion: boolean;
19
+ /** All warp trails are open without a Distress Beacon. */
20
+ readonly openAllTrails: boolean;
21
+ /** The next double on an own trail will not open Subspace Fracture. */
22
+ readonly suppressNextFracture: boolean;
23
+ /** Captains who lose their next helm activation once. */
24
+ readonly skipNextTurnFor: readonly PlayerId[];
25
+ readonly peekedSector: Readonly<{
26
+ index: number;
27
+ coordinate: Coordinate;
28
+ visibleTo: PlayerId;
29
+ }> | null;
30
+ /** At round scoring, 12-12 penalty transfers to the highest-penalty captain. */
31
+ readonly salamanderSwap: boolean;
32
+ /** Any round win requires dropping to impulse before scoring. */
33
+ readonly treatyEcho: boolean;
34
+ }
35
+ export interface QGamblePending {
36
+ readonly playerId: PlayerId;
37
+ readonly options: readonly [Coordinate, Coordinate];
38
+ }
39
+ export interface QFlashCatalogEntry {
40
+ readonly kind: QFlashEffectKind;
41
+ readonly label: string;
42
+ readonly description: string;
43
+ readonly requiresSalamander?: boolean;
44
+ }
45
+ export declare const Q_FLASH_CATALOG: readonly QFlashCatalogEntry[];
46
+ export declare const EMPTY_Q_ROUND_EFFECTS: QRoundEffects;
47
+ export declare function describeQFlashEffect(effect: QFlashEffect, names: Readonly<Record<string, string>>): string;
48
+ export declare function getAvailableQFlashEffects(round: RoundState, modules: GameModules, captains: readonly Captain[]): QFlashEffectKind[];
49
+ export declare function isQResolutionPending(round: RoundState): boolean;
50
+ //# sourceMappingURL=q-continuum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"q-continuum.d.ts","sourceRoot":"","sources":["../../../src/lib/types/q-continuum.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,iEAAiE;AACjE,MAAM,MAAM,gBAAgB,GACxB,oBAAoB,GACpB,qBAAqB,GACrB,gBAAgB,GAChB,oBAAoB,GACpB,wBAAwB,GACxB,mBAAmB,GACnB,iBAAiB,GACjB,aAAa,GACb,UAAU,CAAC;AAEf,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,0DAA0D;IAC1D,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,uEAAuE;IACvE,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,yDAAyD;IACzD,QAAQ,CAAC,eAAe,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC9C,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,UAAU,CAAC;QACvB,SAAS,EAAE,QAAQ,CAAC;KACrB,CAAC,GAAG,IAAI,CAAC;IACV,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,kBAAkB,EAsDxD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,aASnC,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACtC,MAAM,CAWR;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,gBAAgB,EAAE,CAgBpB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE/D"}
@@ -0,0 +1,20 @@
1
+ import { PlacedCoordinate } from './coordinate.js';
2
+ import { DistressBeacon } from './player.js';
3
+ /** A captain's personal line of coordinates (Warp Trail). */
4
+ export interface WarpTrail {
5
+ readonly playerId: string;
6
+ readonly tiles: readonly PlacedCoordinate[];
7
+ readonly distressBeacon: DistressBeacon;
8
+ }
9
+ /** The communal Neutral Zone, open to all captains. */
10
+ export interface NeutralZone {
11
+ readonly tiles: readonly PlacedCoordinate[];
12
+ }
13
+ /** Central Spacedock — the round's starting double tile. */
14
+ export interface Spacedock {
15
+ /** Pip value of the establishing double (12, 11, 10, …). */
16
+ readonly value: number;
17
+ readonly placedBy: string;
18
+ }
19
+ export declare function isTrailOpenToOthers(trail: WarpTrail): boolean;
20
+ //# sourceMappingURL=trails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trails.d.ts","sourceRoot":"","sources":["../../../src/lib/types/trails.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,6DAA6D;AAC7D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CACzC;AAED,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC7C;AAED,4DAA4D;AAC5D,MAAM,WAAW,SAAS;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAE7D"}
@@ -0,0 +1,3 @@
1
+ /** Player-facing text for engine violation codes. */
2
+ export declare function formatViolation(violation: string): string;
3
+ //# sourceMappingURL=format-violation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-violation.d.ts","sourceRoot":"","sources":["../../../src/lib/violations/format-violation.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOzD"}
@@ -0,0 +1,22 @@
1
+ export * from './types/coordinate.js';
2
+ export * from './types/player.js';
3
+ export * from './types/trails.js';
4
+ export * from './types/anomalies.js';
5
+ export * from './types/modules.js';
6
+ export * from './types/objective.js';
7
+ export * from './types/game-state.js';
8
+ export * from './types/actions.js';
9
+ export * from './constants/setup.js';
10
+ export * from './domino/coordinates.js';
11
+ export * from './table/table-state.js';
12
+ export * from './setup/create-game.js';
13
+ export * from './engine/apply-action.js';
14
+ export * from './engine/legal-moves.js';
15
+ export * from './engine/beacon.js';
16
+ export * from './engine/scoring.js';
17
+ export * from './engine/q-continuum.js';
18
+ export * from './types/q-continuum.js';
19
+ export * from './ai/index.js';
20
+ export * from './fixtures/create-demo-game.js';
21
+ export * from './violations/format-violation.js';
22
+ //# sourceMappingURL=warp12-lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warp12-lib.d.ts","sourceRoot":"","sources":["../../src/lib/warp12-lib.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "warp12-engine",
3
+ "version": "0.1.0",
4
+ "description": "Warp 12 game engine — rules, state machine, Warp AI, and advisor explanations",
5
+ "license": "MIT",
6
+ "author": "Jessica Mulein",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "main": "./dist/index.js",
10
+ "module": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ "./package.json": "./package.json",
14
+ ".": {
15
+ "@warp12/source": "./src/index.ts",
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js",
18
+ "default": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "keywords": [
26
+ "warp12",
27
+ "mexican-train",
28
+ "dominoes",
29
+ "game-engine",
30
+ "board-game"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/Digital-Defiance/Warp12.git",
35
+ "directory": "libs/engine"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public",
39
+ "registry": "https://registry.npmjs.org/"
40
+ },
41
+ "scripts": {
42
+ "prepublishOnly": "cd ../.. && yarn build:engine && yarn test:engine"
43
+ },
44
+ "peerDependencies": {
45
+ "doubletwelve": ">=0.3.0"
46
+ },
47
+ "devDependencies": {
48
+ "doubletwelve": "workspace:*"
49
+ }
50
+ }