@omnitronix/happy-panda-game-engine 0.0.2 → 0.0.4

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 (94) hide show
  1. package/README.md +584 -120
  2. package/dist/__tests__/bonus-sequence.test.d.ts +7 -0
  3. package/dist/__tests__/bonus-sequence.test.d.ts.map +1 -0
  4. package/dist/__tests__/cherry-frequency.test.d.ts +8 -0
  5. package/dist/__tests__/cherry-frequency.test.d.ts.map +1 -0
  6. package/dist/__tests__/counter-manager.test.d.ts +7 -0
  7. package/dist/__tests__/counter-manager.test.d.ts.map +1 -0
  8. package/dist/__tests__/cpp-parity.test.d.ts +39 -0
  9. package/dist/__tests__/cpp-parity.test.d.ts.map +1 -0
  10. package/dist/__tests__/happy-panda-engine.test.d.ts +7 -0
  11. package/dist/__tests__/happy-panda-engine.test.d.ts.map +1 -0
  12. package/dist/__tests__/jackpot-manager.test.d.ts +8 -0
  13. package/dist/__tests__/jackpot-manager.test.d.ts.map +1 -0
  14. package/dist/__tests__/jackpot-trigger-trace.test.d.ts +6 -0
  15. package/dist/__tests__/jackpot-trigger-trace.test.d.ts.map +1 -0
  16. package/dist/__tests__/rtp-1million.test.d.ts +8 -0
  17. package/dist/__tests__/rtp-1million.test.d.ts.map +1 -0
  18. package/dist/__tests__/rtp-analysis.test.d.ts +8 -0
  19. package/dist/__tests__/rtp-analysis.test.d.ts.map +1 -0
  20. package/dist/__tests__/rtp-diagnostic.test.d.ts +6 -0
  21. package/dist/__tests__/rtp-diagnostic.test.d.ts.map +1 -0
  22. package/dist/__tests__/rtp-simulation.test.d.ts +8 -0
  23. package/dist/__tests__/rtp-simulation.test.d.ts.map +1 -0
  24. package/dist/__tests__/special-wins.test.d.ts +7 -0
  25. package/dist/__tests__/special-wins.test.d.ts.map +1 -0
  26. package/dist/__tests__/spin-generator.test.d.ts +7 -0
  27. package/dist/__tests__/spin-generator.test.d.ts.map +1 -0
  28. package/dist/__tests__/spin-handler.test.d.ts +7 -0
  29. package/dist/__tests__/spin-handler.test.d.ts.map +1 -0
  30. package/dist/__tests__/symbol-distribution.test.d.ts +6 -0
  31. package/dist/__tests__/symbol-distribution.test.d.ts.map +1 -0
  32. package/dist/__tests__/weighted-random.test.d.ts +7 -0
  33. package/dist/__tests__/weighted-random.test.d.ts.map +1 -0
  34. package/dist/__tests__/win-evaluator.test.d.ts +7 -0
  35. package/dist/__tests__/win-evaluator.test.d.ts.map +1 -0
  36. package/dist/config/happy-panda.config.d.ts +212 -0
  37. package/dist/config/happy-panda.config.d.ts.map +1 -0
  38. package/dist/config/index.d.ts +5 -0
  39. package/dist/config/index.d.ts.map +1 -0
  40. package/dist/domain/index.d.ts +5 -0
  41. package/dist/domain/index.d.ts.map +1 -0
  42. package/dist/domain/types.d.ts +205 -0
  43. package/dist/domain/types.d.ts.map +1 -0
  44. package/dist/engine/happy-panda-engine.d.ts +50 -0
  45. package/dist/engine/happy-panda-engine.d.ts.map +1 -0
  46. package/dist/engine/index.d.ts +5 -0
  47. package/dist/engine/index.d.ts.map +1 -0
  48. package/dist/happy-panda-v1.game-engine.d.ts +63 -0
  49. package/dist/happy-panda-v1.game-engine.d.ts.map +1 -0
  50. package/dist/happy-panda-v1.game-engine.js +37 -39
  51. package/dist/happy-panda-v1.game-engine.js.map +1 -1
  52. package/dist/index.d.ts +19 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +7 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/logic/handlers/index.d.ts +5 -0
  57. package/dist/logic/handlers/index.d.ts.map +1 -0
  58. package/dist/logic/handlers/spin-handler.d.ts +54 -0
  59. package/dist/logic/handlers/spin-handler.d.ts.map +1 -0
  60. package/dist/logic/index.d.ts +6 -0
  61. package/dist/logic/index.d.ts.map +1 -0
  62. package/dist/logic/services/counter-manager.d.ts +60 -0
  63. package/dist/logic/services/counter-manager.d.ts.map +1 -0
  64. package/dist/logic/services/index.d.ts +7 -0
  65. package/dist/logic/services/index.d.ts.map +1 -0
  66. package/dist/logic/services/jackpot-manager.d.ts +59 -0
  67. package/dist/logic/services/jackpot-manager.d.ts.map +1 -0
  68. package/dist/logic/services/win-evaluator.d.ts +49 -0
  69. package/dist/logic/services/win-evaluator.d.ts.map +1 -0
  70. package/dist/rng/dummy-rng-client.d.ts +39 -0
  71. package/dist/rng/dummy-rng-client.d.ts.map +1 -0
  72. package/dist/rng/dummy-rng-client.js +77 -0
  73. package/dist/rng/dummy-rng-client.js.map +1 -0
  74. package/dist/rng/index.d.ts +10 -0
  75. package/dist/rng/index.d.ts.map +1 -0
  76. package/dist/rng/index.js +5 -0
  77. package/dist/rng/index.js.map +1 -1
  78. package/dist/rng/rng-client.factory.d.ts +33 -0
  79. package/dist/rng/rng-client.factory.d.ts.map +1 -0
  80. package/dist/rng/rng-client.factory.js +57 -0
  81. package/dist/rng/rng-client.factory.js.map +1 -0
  82. package/dist/rng/rng-client.interface.d.ts +51 -0
  83. package/dist/rng/rng-client.interface.d.ts.map +1 -0
  84. package/dist/rng/rng-client.interface.js +9 -0
  85. package/dist/rng/rng-client.interface.js.map +1 -0
  86. package/dist/rng/rng-service.d.ts +93 -0
  87. package/dist/rng/rng-service.d.ts.map +1 -0
  88. package/dist/rng/rng-service.js +124 -0
  89. package/dist/rng/rng-service.js.map +1 -0
  90. package/dist/rng/spin-generator.d.ts +31 -0
  91. package/dist/rng/spin-generator.d.ts.map +1 -0
  92. package/dist/rng/weighted-random.d.ts +30 -0
  93. package/dist/rng/weighted-random.d.ts.map +1 -0
  94. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spin-handler.d.ts","sourceRoot":"","sources":["../../../src/logic/handlers/spin-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAEL,QAAQ,EAET,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,IAAI,EACJ,aAAa,EACb,SAAS,EACT,aAAa,EACb,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAoB5B,MAAM,WAAW,UAAU;IACzB,qBAAqB;IACrB,IAAI,EAAE,IAAI,CAAC;IACX,6BAA6B;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,cAAc,EAAE,QAAQ,GAAG,IAAI,CAAC;IAChC,+CAA+C;IAC/C,eAAe,EAAE,OAAO,CAAC;CAC1B;AAqBD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,UAAU,CAAC,CA2KrB;AAMD,wBAAwB;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,iDAAiD;AACjD,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAUtF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,SAAS,CAsCX;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,SAAS,CAiBX"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Logic module exports
3
+ */
4
+ export * from './services';
5
+ export * from './handlers';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logic/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Counter Manager Service
3
+ *
4
+ * Manages bonus counters and trigger detection.
5
+ * Each bonus type has a counter that decrements on specific events.
6
+ * When a counter reaches 0, the bonus is triggered.
7
+ */
8
+ import { SpinType } from '../../config/happy-panda.config';
9
+ import { Grid, GameDirection, BonusCounters, PendingBonuses, LineWin, RngProvider } from '../../domain/types';
10
+ /**
11
+ * Create initial bonus counters.
12
+ */
13
+ export declare function createInitialCounters(): BonusCounters;
14
+ /**
15
+ * Create empty pending bonuses.
16
+ */
17
+ export declare function createEmptyPendingBonuses(): PendingBonuses;
18
+ /**
19
+ * Randomize cherry counter initial value (6 or 9).
20
+ */
21
+ export declare function randomizeCherryCounter(gameDirection: GameDirection, rng: RngProvider): Promise<number>;
22
+ /**
23
+ * Randomize bell counter initial value (3 or 5).
24
+ */
25
+ export declare function randomizeBellCounter(gameDirection: GameDirection, rng: RngProvider): Promise<number>;
26
+ /** Result of counter update */
27
+ export interface CounterUpdateResult {
28
+ counters: BonusCounters;
29
+ pendingBonuses: PendingBonuses;
30
+ triggeredJackpot: boolean;
31
+ triggeredCherry: boolean;
32
+ triggeredBell: boolean;
33
+ triggeredBar1: boolean;
34
+ triggeredRespin: number;
35
+ }
36
+ /**
37
+ * Update counters based on spin results.
38
+ * Only applies during paid_spin and respin_cherry.
39
+ */
40
+ export declare function updateCounters(currentCounters: BonusCounters, currentPending: PendingBonuses, lineWins: LineWin[], grid: Grid, gameDirection: GameDirection, spinType: SpinType, totalWin: number, rng: RngProvider): Promise<CounterUpdateResult>;
41
+ /** Bonus type to consume */
42
+ export type BonusType = 'jackpot' | 'cherry' | 'bell' | 'bar1' | 'respin';
43
+ /**
44
+ * Get the next bonus type to execute (priority order).
45
+ * Returns null if no bonuses pending.
46
+ */
47
+ export declare function getNextBonusType(pending: PendingBonuses): BonusType | null;
48
+ /**
49
+ * Consume one bonus from pending.
50
+ * Returns updated pending and number of spins for that bonus.
51
+ */
52
+ export declare function consumeBonus(pending: PendingBonuses, bonusType: BonusType): {
53
+ pending: PendingBonuses;
54
+ spins: number;
55
+ };
56
+ /**
57
+ * Check if any bonus is pending.
58
+ */
59
+ export declare function hasPendingBonus(pending: PendingBonuses): boolean;
60
+ //# sourceMappingURL=counter-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter-manager.d.ts","sourceRoot":"","sources":["../../../src/logic/services/counter-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEL,QAAQ,EAOT,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,IAAI,EACJ,aAAa,EACb,aAAa,EACb,cAAc,EACd,OAAO,EACP,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAO5B;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,aAAa,CAOrD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,cAAc,CAQ1D;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAIjB;AAMD,+BAA+B;AAC/B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,cAAc,EAAE,cAAc,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,eAAe,EAAE,aAAa,EAC9B,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,mBAAmB,CAAC,CAwI9B;AAMD,4BAA4B;AAC5B,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1E;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,CAQ1E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,SAAS,GACnB;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAsC5C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAQhE"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Logic services exports
3
+ */
4
+ export * from './win-evaluator';
5
+ export * from './counter-manager';
6
+ export * from './jackpot-manager';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/logic/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Jackpot Manager Service
3
+ *
4
+ * Manages progressive jackpot and pool jackpot values.
5
+ *
6
+ * Progressive Jackpot (Bonus Jackpot):
7
+ * - Starts at 100 x bet_game
8
+ * - On losing paid spins: 3/13 chance to increase by 1-2 x bet_stake
9
+ * - Max: 1000 x bet_game
10
+ * - Paid when Jackpot Bonus triggered
11
+ *
12
+ * Pool Jackpot:
13
+ * - Starts at 0
14
+ * - Increases when Seven/Super Seven in center with no wins
15
+ * - Max: 250 x bet_game
16
+ * - Paid when Bell Bonus triggered
17
+ */
18
+ import { SpinType } from '../../config/happy-panda.config';
19
+ import { Grid, GameDirection, JackpotState, RngProvider } from '../../domain/types';
20
+ /**
21
+ * Create initial jackpot state.
22
+ */
23
+ export declare function createInitialJackpots(betGame: number): JackpotState;
24
+ /**
25
+ * Update progressive jackpot value on losing paid spin.
26
+ * 3/13 probability to increase.
27
+ */
28
+ export declare function updateProgressiveJackpot(currentValue: number, gameDirection: GameDirection, betGame: number, betStake: number, spinType: SpinType, totalWin: number, rng: RngProvider): Promise<number>;
29
+ /**
30
+ * Pay out progressive jackpot and reset.
31
+ */
32
+ export declare function payProgressiveJackpot(currentValue: number, betGame: number): {
33
+ payout: number;
34
+ newValue: number;
35
+ };
36
+ /**
37
+ * Update pool jackpot value.
38
+ * Increases when Seven/Super Seven in center position with no wins.
39
+ * IMPORTANT: Must be the ONLY Seven on the entire screen (per C++ math model).
40
+ */
41
+ export declare function updatePoolJackpot(currentValue: number, grid: Grid, gameDirection: GameDirection, betGame: number, betStake: number, spinType: SpinType, totalWin: number): number;
42
+ /**
43
+ * Pay out pool jackpot and reset.
44
+ */
45
+ export declare function payPoolJackpot(currentValue: number, betGame: number): {
46
+ payout: number;
47
+ newValue: number;
48
+ };
49
+ /** Result of jackpot updates */
50
+ export interface JackpotUpdateResult {
51
+ jackpots: JackpotState;
52
+ progressiveJackpotIncreased: boolean;
53
+ poolJackpotIncreased: boolean;
54
+ }
55
+ /**
56
+ * Update both jackpot values after a spin.
57
+ */
58
+ export declare function updateJackpots(currentJackpots: JackpotState, grid: Grid, gameDirection: GameDirection, betGame: number, betStake: number, spinType: SpinType, totalWin: number, rng: RngProvider): Promise<JackpotUpdateResult>;
59
+ //# sourceMappingURL=jackpot-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jackpot-manager.d.ts","sourceRoot":"","sources":["../../../src/logic/services/jackpot-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAEL,QAAQ,EAIT,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOpF;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAKnE;AAMD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAItC;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAsCR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAItC;AAMD,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,YAAY,CAAC;IACvB,2BAA2B,EAAE,OAAO,CAAC;IACrC,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,eAAe,EAAE,YAAY,EAC7B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,mBAAmB,CAAC,CAgC9B"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Win Evaluator Service
3
+ *
4
+ * Evaluates wins on a 3x3 grid with correct priority:
5
+ * 1. Wall wins (3x3) - suppress line wins
6
+ * 2. Scatter wins (Seven/Super Seven) - suppress line wins
7
+ * 3. Line wins (only if no wall or scatter)
8
+ * 4. Special wins (bonus-specific)
9
+ */
10
+ import { SpinType } from '../../config/happy-panda.config';
11
+ import { Grid, GameDirection, LineWin, WallWin, ScatterWin, SpecialWin, SpinWinResult } from '../../domain/types';
12
+ /**
13
+ * Evaluate wall (3x3) wins.
14
+ * Wall wins require all 9 positions to be the same symbol or valid mix.
15
+ */
16
+ export declare function evaluateWallWin(grid: Grid, betGame: number): WallWin | null;
17
+ /**
18
+ * Evaluate Seven/Super Seven scatter wins.
19
+ * C++ can award TWO scatter wins:
20
+ * 1. Super Seven only scatter (if SEV_S >= 2, doubled if no regular Sevens)
21
+ * 2. Total count scatter (if total >= 2 AND at least 1 regular Seven)
22
+ * Plus +bet_game bonus if exactly 1 Super Seven
23
+ */
24
+ export declare function evaluateScatterWins(grid: Grid, betGame: number): ScatterWin[];
25
+ /**
26
+ * Evaluate all line wins.
27
+ */
28
+ export declare function evaluateLineWins(grid: Grid, gameDirection: GameDirection, betStake: number): LineWin[];
29
+ /**
30
+ * Evaluate cherry piece line wins (Jackpot Bonus).
31
+ * Cherry pieces on lines pay special multiplier.
32
+ */
33
+ export declare function evaluateCherryPieceWins(grid: Grid, gameDirection: GameDirection, betStake: number): SpecialWin[];
34
+ /**
35
+ * Evaluate bell scatter wins (Bell Bonus).
36
+ * Each bell pays as scatter during bonus.
37
+ */
38
+ export declare function evaluateBellScatterWins(grid: Grid, gameDirection: GameDirection, betStake: number): SpecialWin | null;
39
+ /**
40
+ * Evaluate super bar scatter wins (Bar1 Bonus).
41
+ * Each super bar pays as scatter during bonus.
42
+ */
43
+ export declare function evaluateSuperBarScatterWins(grid: Grid, gameDirection: GameDirection, betStake: number): SpecialWin | null;
44
+ /**
45
+ * Evaluate all wins for a spin.
46
+ * Implements correct priority: Wall > Scatter > Lines
47
+ */
48
+ export declare function evaluateSpin(grid: Grid, gameDirection: GameDirection, betStake: number, betGame: number, spinType: SpinType): SpinWinResult;
49
+ //# sourceMappingURL=win-evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"win-evaluator.d.ts","sourceRoot":"","sources":["../../../src/logic/services/win-evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,QAAQ,EAiBT,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,IAAI,EACJ,aAAa,EAEb,OAAO,EACP,OAAO,EACP,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,oBAAoB,CAAC;AAqE5B;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,GACd,OAAO,GAAG,IAAI,CAmEhB;AAMD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,GACd,UAAU,EAAE,CAsDd;AAmGD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,OAAO,EAAE,CAYX;AAMD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,EAAE,CAmCd;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,IAAI,CAcnB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,IAAI,CAcnB;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GACjB,aAAa,CAyFf"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Dummy RNG Client
3
+ *
4
+ * Local RNG client for development and testing.
5
+ * Uses Math.random() for all operations.
6
+ * Returns seed value of 0 (non-cryptographic, for testing only).
7
+ */
8
+ import { IRngClient, RngSingleResponse, RngBatchResponse } from './rng-client.interface';
9
+ export declare class DummyRngClient implements IRngClient {
10
+ /**
11
+ * Generate a single random integer in range [min, max]
12
+ */
13
+ getSingleNumber(min: number, max: number, _seed?: number): Promise<RngSingleResponse>;
14
+ /**
15
+ * Generate multiple random integers in range [min, max]
16
+ */
17
+ getBatchNumbers(min: number, max: number, count: number, _seed?: number): Promise<number[]>;
18
+ /**
19
+ * Generate multiple random integers with individual seeds
20
+ */
21
+ getBatchNumbersWithSeeds(min: number, max: number, count: number, _seed?: number): Promise<RngSingleResponse[]>;
22
+ /**
23
+ * Generate a single random float in range [0, 1)
24
+ */
25
+ getSingleFloat(_seed?: number): Promise<RngSingleResponse>;
26
+ /**
27
+ * Generate multiple random floats in range [0, 1)
28
+ */
29
+ getBatchFloats(count: number, _seed?: number): Promise<RngBatchResponse>;
30
+ /**
31
+ * Alternative method for single random number
32
+ */
33
+ getRandomNumber(min: number, max: number, _seed?: number): Promise<RngSingleResponse>;
34
+ /**
35
+ * Alternative method for single random float
36
+ */
37
+ getRandomFloat(_seed?: number): Promise<RngSingleResponse>;
38
+ }
39
+ //# sourceMappingURL=dummy-rng-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dummy-rng-client.d.ts","sourceRoot":"","sources":["../../src/rng/dummy-rng-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,cAAe,YAAW,UAAU;IAC/C;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC;IAM7B;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC;IASpB;;OAEG;IACG,wBAAwB,CAC5B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAY/B;;OAEG;IACG,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIhE;;OAEG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;OAEG;IACG,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGjE"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * Dummy RNG Client
4
+ *
5
+ * Local RNG client for development and testing.
6
+ * Uses Math.random() for all operations.
7
+ * Returns seed value of 0 (non-cryptographic, for testing only).
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.DummyRngClient = void 0;
11
+ class DummyRngClient {
12
+ /**
13
+ * Generate a single random integer in range [min, max]
14
+ */
15
+ async getSingleNumber(min, max, _seed) {
16
+ const randomValue = Math.random();
17
+ const result = Math.floor(randomValue * (max - min + 1)) + min;
18
+ return { value: result, seed: 0 };
19
+ }
20
+ /**
21
+ * Generate multiple random integers in range [min, max]
22
+ */
23
+ async getBatchNumbers(min, max, count, _seed) {
24
+ const results = [];
25
+ for (let i = 0; i < count; i++) {
26
+ const randomValue = Math.random();
27
+ results.push(Math.floor(randomValue * (max - min + 1)) + min);
28
+ }
29
+ return results;
30
+ }
31
+ /**
32
+ * Generate multiple random integers with individual seeds
33
+ */
34
+ async getBatchNumbersWithSeeds(min, max, count, _seed) {
35
+ const results = [];
36
+ for (let i = 0; i < count; i++) {
37
+ const randomValue = Math.random();
38
+ results.push({
39
+ value: Math.floor(randomValue * (max - min + 1)) + min,
40
+ seed: 0,
41
+ });
42
+ }
43
+ return results;
44
+ }
45
+ /**
46
+ * Generate a single random float in range [0, 1)
47
+ */
48
+ async getSingleFloat(_seed) {
49
+ return { value: Math.random(), seed: 0 };
50
+ }
51
+ /**
52
+ * Generate multiple random floats in range [0, 1)
53
+ */
54
+ async getBatchFloats(count, _seed) {
55
+ const values = [];
56
+ const seeds = [];
57
+ for (let i = 0; i < count; i++) {
58
+ values.push(Math.random());
59
+ seeds.push(0);
60
+ }
61
+ return { values, seeds };
62
+ }
63
+ /**
64
+ * Alternative method for single random number
65
+ */
66
+ async getRandomNumber(min, max, _seed) {
67
+ return this.getSingleNumber(min, max, _seed);
68
+ }
69
+ /**
70
+ * Alternative method for single random float
71
+ */
72
+ async getRandomFloat(_seed) {
73
+ return this.getSingleFloat(_seed);
74
+ }
75
+ }
76
+ exports.DummyRngClient = DummyRngClient;
77
+ //# sourceMappingURL=dummy-rng-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dummy-rng-client.js","sourceRoot":"","sources":["../../src/rng/dummy-rng-client.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAQH,MAAa,cAAc;IACzB;;OAEG;IACH,KAAK,CAAC,eAAe,CACnB,GAAW,EACX,GAAW,EACX,KAAc;QAEd,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CACnB,GAAW,EACX,GAAW,EACX,KAAa,EACb,KAAc;QAEd,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,wBAAwB,CAC5B,GAAW,EACX,GAAW,EACX,KAAa,EACb,KAAc;QAEd,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG;gBACtD,IAAI,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,KAAc;QACjC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,KAAc;QAEd,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CACnB,GAAW,EACX,GAAW,EACX,KAAc;QAEd,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,KAAc;QACjC,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;CACF;AA3FD,wCA2FC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * RNG module exports
3
+ */
4
+ export * from './weighted-random';
5
+ export * from './spin-generator';
6
+ export * from './rng-client.interface';
7
+ export * from './dummy-rng-client';
8
+ export * from './rng-client.factory';
9
+ export * from './rng-service';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC"}
package/dist/rng/index.js CHANGED
@@ -19,4 +19,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
19
  */
20
20
  __exportStar(require("./weighted-random"), exports);
21
21
  __exportStar(require("./spin-generator"), exports);
22
+ // RNG Service and Client Infrastructure
23
+ __exportStar(require("./rng-client.interface"), exports);
24
+ __exportStar(require("./dummy-rng-client"), exports);
25
+ __exportStar(require("./rng-client.factory"), exports);
26
+ __exportStar(require("./rng-service"), exports);
22
27
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,oDAAkC;AAClC,mDAAiC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,oDAAkC;AAClC,mDAAiC;AAEjC,wCAAwC;AACxC,yDAAuC;AACvC,qDAAmC;AACnC,uDAAqC;AACrC,gDAA8B"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * RNG Client Factory
3
+ *
4
+ * Factory pattern for creating RNG clients based on environment configuration.
5
+ * Matches the pattern used in Heroes of Aether and Bonny's Fortune.
6
+ *
7
+ * Environment Variables:
8
+ * - RNG_CLIENT_MODE: 'local' (DummyRngClient) or 'external' (production RngClient)
9
+ * - RNG_CLIENT_URL: HTTP endpoint for external RNG service
10
+ * - RNG_CLIENT_GRPC_URL: gRPC endpoint for external RNG service
11
+ * - RNG_CLIENT_METHOD: 'grpc' or 'rest'
12
+ * - RNG_CLIENT_POOL_SIZE: Ring buffer pool size (default: 2000)
13
+ */
14
+ import { IRngClient } from './rng-client.interface';
15
+ export interface RngClientConfig {
16
+ serverUrl?: string;
17
+ grpcUrl?: string;
18
+ clientMethod?: 'grpc' | 'rest';
19
+ poolingSize?: number;
20
+ metrics?: unknown;
21
+ }
22
+ export declare class RngClientFactory {
23
+ /**
24
+ * Create an RNG client based on environment configuration.
25
+ *
26
+ * @param config Optional configuration overrides
27
+ * @returns IRngClient instance (DummyRngClient for local, external client for production)
28
+ */
29
+ static create(config?: {
30
+ metrics?: unknown;
31
+ }): IRngClient;
32
+ }
33
+ //# sourceMappingURL=rng-client.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng-client.factory.d.ts","sourceRoot":"","sources":["../../src/rng/rng-client.factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,UAAU;CAqC9D"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * RNG Client Factory
4
+ *
5
+ * Factory pattern for creating RNG clients based on environment configuration.
6
+ * Matches the pattern used in Heroes of Aether and Bonny's Fortune.
7
+ *
8
+ * Environment Variables:
9
+ * - RNG_CLIENT_MODE: 'local' (DummyRngClient) or 'external' (production RngClient)
10
+ * - RNG_CLIENT_URL: HTTP endpoint for external RNG service
11
+ * - RNG_CLIENT_GRPC_URL: gRPC endpoint for external RNG service
12
+ * - RNG_CLIENT_METHOD: 'grpc' or 'rest'
13
+ * - RNG_CLIENT_POOL_SIZE: Ring buffer pool size (default: 2000)
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.RngClientFactory = void 0;
17
+ const dummy_rng_client_1 = require("./dummy-rng-client");
18
+ class RngClientFactory {
19
+ /**
20
+ * Create an RNG client based on environment configuration.
21
+ *
22
+ * @param config Optional configuration overrides
23
+ * @returns IRngClient instance (DummyRngClient for local, external client for production)
24
+ */
25
+ static create(config = {}) {
26
+ const mode = process.env.RNG_CLIENT_MODE || 'external';
27
+ if (mode === 'local') {
28
+ console.log('[RngClientFactory] Creating DummyRngClient (local mode)');
29
+ return new dummy_rng_client_1.DummyRngClient();
30
+ }
31
+ // For external mode, we would use @omnitronix/rng-client-core
32
+ // For now, fall back to DummyRngClient if external client not available
33
+ console.log('[RngClientFactory] External RNG mode requested');
34
+ const rngClientConfig = {
35
+ serverUrl: process.env.RNG_CLIENT_URL,
36
+ grpcUrl: process.env.RNG_CLIENT_GRPC_URL,
37
+ clientMethod: process.env.RNG_CLIENT_METHOD,
38
+ poolingSize: parseInt(process.env.RNG_CLIENT_POOL_SIZE || '2000'),
39
+ metrics: config.metrics,
40
+ };
41
+ // Try to load external RNG client
42
+ try {
43
+ // Dynamic import to avoid hard dependency
44
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
45
+ const { RngClient } = require('@omnitronix/rng-client-core');
46
+ console.log('[RngClientFactory] Creating external RngClient');
47
+ return new RngClient(rngClientConfig);
48
+ }
49
+ catch (error) {
50
+ console.warn('[RngClientFactory] @omnitronix/rng-client-core not available, falling back to DummyRngClient');
51
+ console.warn('[RngClientFactory] Install @omnitronix/rng-client-core for production use');
52
+ return new dummy_rng_client_1.DummyRngClient();
53
+ }
54
+ }
55
+ }
56
+ exports.RngClientFactory = RngClientFactory;
57
+ //# sourceMappingURL=rng-client.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng-client.factory.js","sourceRoot":"","sources":["../../src/rng/rng-client.factory.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAGH,yDAAoD;AAUpD,MAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,SAAgC,EAAE;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,UAAU,CAAC;QAEvD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;YACvE,OAAO,IAAI,iCAAc,EAAE,CAAC;QAC9B,CAAC;QAED,8DAA8D;QAC9D,wEAAwE;QACxE,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAE9D,MAAM,eAAe,GAAoB;YACvC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;YACrC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;YACxC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAoC;YAC9D,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,MAAM,CAAC;YACjE,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;QAEF,kCAAkC;QAClC,IAAI,CAAC;YACH,0CAA0C;YAC1C,8DAA8D;YAC9D,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;YAC9D,OAAO,IAAI,SAAS,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACV,8FAA8F,CAC/F,CAAC;YACF,OAAO,CAAC,IAAI,CACV,2EAA2E,CAC5E,CAAC;YACF,OAAO,IAAI,iCAAc,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;CACF;AA5CD,4CA4CC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * RNG Client Interface
3
+ *
4
+ * Contract for all RNG clients (local and external).
5
+ * Matches the pattern used in Heroes of Aether and Bonny's Fortune.
6
+ */
7
+ export interface RngSingleResponse {
8
+ value: number;
9
+ seed: number;
10
+ }
11
+ export interface RngBatchResponse {
12
+ values: number[];
13
+ seeds: number[];
14
+ }
15
+ /**
16
+ * RNG Client Interface
17
+ *
18
+ * All RNG clients must implement this interface to ensure
19
+ * consistent behavior between local (testing) and external (production) clients.
20
+ */
21
+ export interface IRngClient {
22
+ /**
23
+ * Generate a single random integer in range [min, max]
24
+ */
25
+ getSingleNumber(min: number, max: number, seed?: number): Promise<RngSingleResponse>;
26
+ /**
27
+ * Generate multiple random integers in range [min, max]
28
+ */
29
+ getBatchNumbers(min: number, max: number, count: number, seed?: number): Promise<number[]>;
30
+ /**
31
+ * Generate multiple random integers with individual seeds
32
+ */
33
+ getBatchNumbersWithSeeds(min: number, max: number, count: number, seed?: number): Promise<RngSingleResponse[]>;
34
+ /**
35
+ * Generate a single random float in range [0, 1)
36
+ */
37
+ getSingleFloat(seed?: number): Promise<RngSingleResponse>;
38
+ /**
39
+ * Generate multiple random floats in range [0, 1)
40
+ */
41
+ getBatchFloats(count: number, seed?: number): Promise<RngBatchResponse>;
42
+ /**
43
+ * Alternative method for single random number
44
+ */
45
+ getRandomNumber(min: number, max: number, seed?: number): Promise<RngSingleResponse>;
46
+ /**
47
+ * Alternative method for single random float
48
+ */
49
+ getRandomFloat(seed?: number): Promise<RngSingleResponse>;
50
+ }
51
+ //# sourceMappingURL=rng-client.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng-client.interface.d.ts","sourceRoot":"","sources":["../../src/rng/rng-client.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,eAAe,CACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE9B;;OAEG;IACH,eAAe,CACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAErB;;OAEG;IACH,wBAAwB,CACtB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAEhC;;OAEG;IACH,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE1D;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAExE;;OAEG;IACH,eAAe,CACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE9B;;OAEG;IACH,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC3D"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * RNG Client Interface
4
+ *
5
+ * Contract for all RNG clients (local and external).
6
+ * Matches the pattern used in Heroes of Aether and Bonny's Fortune.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ //# sourceMappingURL=rng-client.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng-client.interface.js","sourceRoot":"","sources":["../../src/rng/rng-client.interface.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * RNG Service
3
+ *
4
+ * Core RNG service with audit trail tracking for compliance.
5
+ * Wraps an IRngClient and tracks all RNG outcomes per command.
6
+ * Matches the pattern used in Heroes of Aether and Bonny's Fortune.
7
+ */
8
+ import { IRngClient } from './rng-client.interface';
9
+ /**
10
+ * RNG outcome record for audit trail
11
+ */
12
+ export interface RngOutcomeRecord {
13
+ result: number;
14
+ seed: number;
15
+ min: number;
16
+ max: number;
17
+ }
18
+ /**
19
+ * RNG outcomes for a single command, keyed by action ID
20
+ */
21
+ export type RngOutcome = {
22
+ [actionId: string]: RngOutcomeRecord;
23
+ };
24
+ /**
25
+ * RNG Service
26
+ *
27
+ * Provides RNG operations with full audit trail tracking.
28
+ * Each command ID can have multiple action IDs, allowing fine-grained tracking
29
+ * of all RNG calls within a single game command.
30
+ */
31
+ export declare class RngService {
32
+ private readonly rngClient;
33
+ private rngOutcomes;
34
+ constructor(rngClient: IRngClient);
35
+ /**
36
+ * Register a command for RNG tracking.
37
+ * Call this at the start of command processing.
38
+ */
39
+ registerCommand(commandId: string): void;
40
+ /**
41
+ * Remove a command's RNG outcomes.
42
+ * Call this after command processing to clean up.
43
+ */
44
+ removeCommand(commandId: string): void;
45
+ /**
46
+ * Check if a command has RNG outcomes
47
+ */
48
+ hasCommandRngOutcome(commandId: string): boolean;
49
+ /**
50
+ * Get the count of RNG outcomes for a command
51
+ */
52
+ getRngOutcomeCountForCommand(commandId: string): number;
53
+ /**
54
+ * Store an RNG outcome for audit trail
55
+ */
56
+ private storeSeedForCommand;
57
+ /**
58
+ * Get cached seed for a command/action (for replay scenarios)
59
+ */
60
+ getSeedForCommand(commandId: string, actionId: string): number | undefined;
61
+ /**
62
+ * Get all RNG outcomes for a command
63
+ */
64
+ getRngOutcomeForCommand(commandId: string): RngOutcome;
65
+ /**
66
+ * Get all RNG outcomes across all commands
67
+ */
68
+ getAllRngOutcome(): {
69
+ [commandId: string]: RngOutcome;
70
+ };
71
+ /**
72
+ * Generate a single random integer in range [min, max]
73
+ * Tracks the outcome for audit trail
74
+ */
75
+ getSingleNumber(min: number, max: number, commandId: string, actionId: string): Promise<{
76
+ value: number;
77
+ seed: number;
78
+ }>;
79
+ /**
80
+ * Generate multiple random integers in range [min, max]
81
+ * Each number is tracked individually with incrementing action IDs
82
+ */
83
+ getBatchNumbers(min: number, max: number, count: number, commandId: string, actionId: string): Promise<{
84
+ value: number;
85
+ seed: number;
86
+ }[]>;
87
+ /**
88
+ * Generate a weighted random selection
89
+ * Returns the index selected based on weights
90
+ */
91
+ getWeightedRandomIndex(weights: number[], commandId: string, actionId: string): Promise<number>;
92
+ }
93
+ //# sourceMappingURL=rng-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng-service.d.ts","sourceRoot":"","sources":["../../src/rng/rng-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAAA;CAAE,CAAC;AAElE;;;;;;GAMG;AACH,qBAAa,UAAU;IAGT,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,OAAO,CAAC,WAAW,CAA2C;gBAEjC,SAAS,EAAE,UAAU;IAElD;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAMxC;;;OAGG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAItC;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIhD;;OAEG;IACH,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAKvD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI1E;;OAEG;IACH,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU;IAItD;;OAEG;IACH,gBAAgB,IAAI;QAAE,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE;IAIvD;;;OAGG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAwB3C;;;OAGG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAgB7C;;;OAGG;IACG,sBAAsB,CAC1B,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;CAmBnB"}