@omnitronix/happy-panda-game-engine 0.5.1

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 (207) hide show
  1. package/README.md +732 -0
  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__/bonus-sequence.test.js +381 -0
  5. package/dist/__tests__/bonus-sequence.test.js.map +1 -0
  6. package/dist/__tests__/cherry-frequency.test.d.ts +8 -0
  7. package/dist/__tests__/cherry-frequency.test.d.ts.map +1 -0
  8. package/dist/__tests__/cherry-frequency.test.js +128 -0
  9. package/dist/__tests__/cherry-frequency.test.js.map +1 -0
  10. package/dist/__tests__/comprehensive.test.d.ts +16 -0
  11. package/dist/__tests__/comprehensive.test.d.ts.map +1 -0
  12. package/dist/__tests__/comprehensive.test.js +491 -0
  13. package/dist/__tests__/comprehensive.test.js.map +1 -0
  14. package/dist/__tests__/counter-manager.test.d.ts +7 -0
  15. package/dist/__tests__/counter-manager.test.d.ts.map +1 -0
  16. package/dist/__tests__/counter-manager.test.js +317 -0
  17. package/dist/__tests__/counter-manager.test.js.map +1 -0
  18. package/dist/__tests__/coverage-boost.test.d.ts +13 -0
  19. package/dist/__tests__/coverage-boost.test.d.ts.map +1 -0
  20. package/dist/__tests__/coverage-boost.test.js +606 -0
  21. package/dist/__tests__/coverage-boost.test.js.map +1 -0
  22. package/dist/__tests__/cpp-parity.test.d.ts +39 -0
  23. package/dist/__tests__/cpp-parity.test.d.ts.map +1 -0
  24. package/dist/__tests__/cpp-parity.test.js +392 -0
  25. package/dist/__tests__/cpp-parity.test.js.map +1 -0
  26. package/dist/__tests__/debug-trigger-bonus.test.d.ts +8 -0
  27. package/dist/__tests__/debug-trigger-bonus.test.d.ts.map +1 -0
  28. package/dist/__tests__/debug-trigger-bonus.test.js +359 -0
  29. package/dist/__tests__/debug-trigger-bonus.test.js.map +1 -0
  30. package/dist/__tests__/fixtures/cpp-parity-vectors.json +457 -0
  31. package/dist/__tests__/gdd-validation-1000.test.d.ts +14 -0
  32. package/dist/__tests__/gdd-validation-1000.test.d.ts.map +1 -0
  33. package/dist/__tests__/gdd-validation-1000.test.js +418 -0
  34. package/dist/__tests__/gdd-validation-1000.test.js.map +1 -0
  35. package/dist/__tests__/happy-panda-engine.test.d.ts +7 -0
  36. package/dist/__tests__/happy-panda-engine.test.d.ts.map +1 -0
  37. package/dist/__tests__/happy-panda-engine.test.js +414 -0
  38. package/dist/__tests__/happy-panda-engine.test.js.map +1 -0
  39. package/dist/__tests__/jackpot-manager.test.d.ts +8 -0
  40. package/dist/__tests__/jackpot-manager.test.d.ts.map +1 -0
  41. package/dist/__tests__/jackpot-manager.test.js +313 -0
  42. package/dist/__tests__/jackpot-manager.test.js.map +1 -0
  43. package/dist/__tests__/jackpot-trigger-trace.test.d.ts +6 -0
  44. package/dist/__tests__/jackpot-trigger-trace.test.d.ts.map +1 -0
  45. package/dist/__tests__/jackpot-trigger-trace.test.js +146 -0
  46. package/dist/__tests__/jackpot-trigger-trace.test.js.map +1 -0
  47. package/dist/__tests__/rng-gli19-compliance.test.d.ts +21 -0
  48. package/dist/__tests__/rng-gli19-compliance.test.d.ts.map +1 -0
  49. package/dist/__tests__/rng-gli19-compliance.test.js +480 -0
  50. package/dist/__tests__/rng-gli19-compliance.test.js.map +1 -0
  51. package/dist/__tests__/rng-seed-security.test.d.ts +19 -0
  52. package/dist/__tests__/rng-seed-security.test.d.ts.map +1 -0
  53. package/dist/__tests__/rng-seed-security.test.js +518 -0
  54. package/dist/__tests__/rng-seed-security.test.js.map +1 -0
  55. package/dist/__tests__/rng-seed-type.test.d.ts +16 -0
  56. package/dist/__tests__/rng-seed-type.test.d.ts.map +1 -0
  57. package/dist/__tests__/rng-seed-type.test.js +285 -0
  58. package/dist/__tests__/rng-seed-type.test.js.map +1 -0
  59. package/dist/__tests__/rng-stress-boundary.test.d.ts +15 -0
  60. package/dist/__tests__/rng-stress-boundary.test.d.ts.map +1 -0
  61. package/dist/__tests__/rng-stress-boundary.test.js +590 -0
  62. package/dist/__tests__/rng-stress-boundary.test.js.map +1 -0
  63. package/dist/__tests__/rtp-1million.test.d.ts +8 -0
  64. package/dist/__tests__/rtp-1million.test.d.ts.map +1 -0
  65. package/dist/__tests__/rtp-1million.test.js +156 -0
  66. package/dist/__tests__/rtp-1million.test.js.map +1 -0
  67. package/dist/__tests__/rtp-analysis.test.d.ts +8 -0
  68. package/dist/__tests__/rtp-analysis.test.d.ts.map +1 -0
  69. package/dist/__tests__/rtp-analysis.test.js +138 -0
  70. package/dist/__tests__/rtp-analysis.test.js.map +1 -0
  71. package/dist/__tests__/rtp-diagnostic.test.d.ts +6 -0
  72. package/dist/__tests__/rtp-diagnostic.test.d.ts.map +1 -0
  73. package/dist/__tests__/rtp-diagnostic.test.js +141 -0
  74. package/dist/__tests__/rtp-diagnostic.test.js.map +1 -0
  75. package/dist/__tests__/rtp-simulation.test.d.ts +8 -0
  76. package/dist/__tests__/rtp-simulation.test.d.ts.map +1 -0
  77. package/dist/__tests__/rtp-simulation.test.js +411 -0
  78. package/dist/__tests__/rtp-simulation.test.js.map +1 -0
  79. package/dist/__tests__/special-wins.test.d.ts +7 -0
  80. package/dist/__tests__/special-wins.test.d.ts.map +1 -0
  81. package/dist/__tests__/special-wins.test.js +179 -0
  82. package/dist/__tests__/special-wins.test.js.map +1 -0
  83. package/dist/__tests__/spin-generator.test.d.ts +7 -0
  84. package/dist/__tests__/spin-generator.test.d.ts.map +1 -0
  85. package/dist/__tests__/spin-generator.test.js +297 -0
  86. package/dist/__tests__/spin-generator.test.js.map +1 -0
  87. package/dist/__tests__/spin-handler.test.d.ts +7 -0
  88. package/dist/__tests__/spin-handler.test.d.ts.map +1 -0
  89. package/dist/__tests__/spin-handler.test.js +210 -0
  90. package/dist/__tests__/spin-handler.test.js.map +1 -0
  91. package/dist/__tests__/symbol-distribution.test.d.ts +6 -0
  92. package/dist/__tests__/symbol-distribution.test.d.ts.map +1 -0
  93. package/dist/__tests__/symbol-distribution.test.js +119 -0
  94. package/dist/__tests__/symbol-distribution.test.js.map +1 -0
  95. package/dist/__tests__/test-protocol-10000-spin.test.d.ts +14 -0
  96. package/dist/__tests__/test-protocol-10000-spin.test.d.ts.map +1 -0
  97. package/dist/__tests__/test-protocol-10000-spin.test.js +359 -0
  98. package/dist/__tests__/test-protocol-10000-spin.test.js.map +1 -0
  99. package/dist/__tests__/weighted-random.test.d.ts +7 -0
  100. package/dist/__tests__/weighted-random.test.d.ts.map +1 -0
  101. package/dist/__tests__/weighted-random.test.js +165 -0
  102. package/dist/__tests__/weighted-random.test.js.map +1 -0
  103. package/dist/__tests__/win-evaluator.test.d.ts +7 -0
  104. package/dist/__tests__/win-evaluator.test.d.ts.map +1 -0
  105. package/dist/__tests__/win-evaluator.test.js +264 -0
  106. package/dist/__tests__/win-evaluator.test.js.map +1 -0
  107. package/dist/config/happy-panda.config.d.ts +217 -0
  108. package/dist/config/happy-panda.config.d.ts.map +1 -0
  109. package/dist/config/happy-panda.config.js +721 -0
  110. package/dist/config/happy-panda.config.js.map +1 -0
  111. package/dist/config/index.d.ts +5 -0
  112. package/dist/config/index.d.ts.map +1 -0
  113. package/dist/config/index.js +21 -0
  114. package/dist/config/index.js.map +1 -0
  115. package/dist/debug/debug-command-definitions.d.ts +38 -0
  116. package/dist/debug/debug-command-definitions.d.ts.map +1 -0
  117. package/dist/debug/debug-command-definitions.js +80 -0
  118. package/dist/debug/debug-command-definitions.js.map +1 -0
  119. package/dist/domain/debug-trigger-bonus-command.d.ts +17 -0
  120. package/dist/domain/debug-trigger-bonus-command.d.ts.map +1 -0
  121. package/dist/domain/debug-trigger-bonus-command.js +3 -0
  122. package/dist/domain/debug-trigger-bonus-command.js.map +1 -0
  123. package/dist/domain/index.d.ts +5 -0
  124. package/dist/domain/index.d.ts.map +1 -0
  125. package/dist/domain/index.js +21 -0
  126. package/dist/domain/index.js.map +1 -0
  127. package/dist/domain/types.d.ts +228 -0
  128. package/dist/domain/types.d.ts.map +1 -0
  129. package/dist/domain/types.js +30 -0
  130. package/dist/domain/types.js.map +1 -0
  131. package/dist/engine/happy-panda-engine.d.ts +64 -0
  132. package/dist/engine/happy-panda-engine.d.ts.map +1 -0
  133. package/dist/engine/happy-panda-engine.js +324 -0
  134. package/dist/engine/happy-panda-engine.js.map +1 -0
  135. package/dist/engine/index.d.ts +5 -0
  136. package/dist/engine/index.d.ts.map +1 -0
  137. package/dist/engine/index.js +21 -0
  138. package/dist/engine/index.js.map +1 -0
  139. package/dist/game-engine.interface.d.ts +19 -0
  140. package/dist/game-engine.interface.d.ts.map +1 -0
  141. package/dist/game-engine.interface.js +9 -0
  142. package/dist/game-engine.interface.js.map +1 -0
  143. package/dist/happy-panda-v1.game-engine.d.ts +60 -0
  144. package/dist/happy-panda-v1.game-engine.d.ts.map +1 -0
  145. package/dist/happy-panda-v1.game-engine.js +524 -0
  146. package/dist/happy-panda-v1.game-engine.js.map +1 -0
  147. package/dist/index.d.ts +22 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +59 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/logic/handlers/index.d.ts +5 -0
  152. package/dist/logic/handlers/index.d.ts.map +1 -0
  153. package/dist/logic/handlers/index.js +21 -0
  154. package/dist/logic/handlers/index.js.map +1 -0
  155. package/dist/logic/handlers/spin-handler.d.ts +58 -0
  156. package/dist/logic/handlers/spin-handler.d.ts.map +1 -0
  157. package/dist/logic/handlers/spin-handler.js +265 -0
  158. package/dist/logic/handlers/spin-handler.js.map +1 -0
  159. package/dist/logic/index.d.ts +6 -0
  160. package/dist/logic/index.d.ts.map +1 -0
  161. package/dist/logic/index.js +22 -0
  162. package/dist/logic/index.js.map +1 -0
  163. package/dist/logic/services/counter-manager.d.ts +60 -0
  164. package/dist/logic/services/counter-manager.d.ts.map +1 -0
  165. package/dist/logic/services/counter-manager.js +268 -0
  166. package/dist/logic/services/counter-manager.js.map +1 -0
  167. package/dist/logic/services/index.d.ts +7 -0
  168. package/dist/logic/services/index.d.ts.map +1 -0
  169. package/dist/logic/services/index.js +23 -0
  170. package/dist/logic/services/index.js.map +1 -0
  171. package/dist/logic/services/jackpot-manager.d.ts +59 -0
  172. package/dist/logic/services/jackpot-manager.d.ts.map +1 -0
  173. package/dist/logic/services/jackpot-manager.js +142 -0
  174. package/dist/logic/services/jackpot-manager.js.map +1 -0
  175. package/dist/logic/services/win-evaluator.d.ts +51 -0
  176. package/dist/logic/services/win-evaluator.d.ts.map +1 -0
  177. package/dist/logic/services/win-evaluator.js +463 -0
  178. package/dist/logic/services/win-evaluator.js.map +1 -0
  179. package/dist/rng/dummy-rng-client.d.ts +39 -0
  180. package/dist/rng/dummy-rng-client.d.ts.map +1 -0
  181. package/dist/rng/dummy-rng-client.js +77 -0
  182. package/dist/rng/dummy-rng-client.js.map +1 -0
  183. package/dist/rng/index.d.ts +10 -0
  184. package/dist/rng/index.d.ts.map +1 -0
  185. package/dist/rng/index.js +27 -0
  186. package/dist/rng/index.js.map +1 -0
  187. package/dist/rng/rng-client.factory.d.ts +33 -0
  188. package/dist/rng/rng-client.factory.d.ts.map +1 -0
  189. package/dist/rng/rng-client.factory.js +57 -0
  190. package/dist/rng/rng-client.factory.js.map +1 -0
  191. package/dist/rng/rng-client.interface.d.ts +51 -0
  192. package/dist/rng/rng-client.interface.d.ts.map +1 -0
  193. package/dist/rng/rng-client.interface.js +9 -0
  194. package/dist/rng/rng-client.interface.js.map +1 -0
  195. package/dist/rng/rng-service.d.ts +93 -0
  196. package/dist/rng/rng-service.d.ts.map +1 -0
  197. package/dist/rng/rng-service.js +124 -0
  198. package/dist/rng/rng-service.js.map +1 -0
  199. package/dist/rng/spin-generator.d.ts +32 -0
  200. package/dist/rng/spin-generator.d.ts.map +1 -0
  201. package/dist/rng/spin-generator.js +338 -0
  202. package/dist/rng/spin-generator.js.map +1 -0
  203. package/dist/rng/weighted-random.d.ts +30 -0
  204. package/dist/rng/weighted-random.d.ts.map +1 -0
  205. package/dist/rng/weighted-random.js +58 -0
  206. package/dist/rng/weighted-random.js.map +1 -0
  207. package/package.json +59 -0
@@ -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"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * RNG Service
4
+ *
5
+ * Core RNG service with audit trail tracking for compliance.
6
+ * Wraps an IRngClient and tracks all RNG outcomes per command.
7
+ * Matches the pattern used in Heroes of Aether and Bonny's Fortune.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.RngService = void 0;
11
+ /**
12
+ * RNG Service
13
+ *
14
+ * Provides RNG operations with full audit trail tracking.
15
+ * Each command ID can have multiple action IDs, allowing fine-grained tracking
16
+ * of all RNG calls within a single game command.
17
+ */
18
+ class RngService {
19
+ constructor(rngClient) {
20
+ this.rngClient = rngClient;
21
+ this.rngOutcomes = {};
22
+ }
23
+ /**
24
+ * Register a command for RNG tracking.
25
+ * Call this at the start of command processing.
26
+ */
27
+ registerCommand(commandId) {
28
+ if (!this.rngOutcomes[commandId]) {
29
+ this.rngOutcomes[commandId] = {};
30
+ }
31
+ }
32
+ /**
33
+ * Remove a command's RNG outcomes.
34
+ * Call this after command processing to clean up.
35
+ */
36
+ removeCommand(commandId) {
37
+ delete this.rngOutcomes[commandId];
38
+ }
39
+ /**
40
+ * Check if a command has RNG outcomes
41
+ */
42
+ hasCommandRngOutcome(commandId) {
43
+ return !!this.rngOutcomes[commandId];
44
+ }
45
+ /**
46
+ * Get the count of RNG outcomes for a command
47
+ */
48
+ getRngOutcomeCountForCommand(commandId) {
49
+ const outcomes = this.rngOutcomes[commandId];
50
+ return outcomes ? Object.keys(outcomes).length : 0;
51
+ }
52
+ /**
53
+ * Store an RNG outcome for audit trail
54
+ */
55
+ storeSeedForCommand(commandId, actionId, result, seed, min, max) {
56
+ this.registerCommand(commandId);
57
+ this.rngOutcomes[commandId][actionId] = { result, seed, min, max };
58
+ }
59
+ /**
60
+ * Get cached seed for a command/action (for replay scenarios)
61
+ */
62
+ getSeedForCommand(commandId, actionId) {
63
+ return this.rngOutcomes[commandId]?.[actionId]?.seed;
64
+ }
65
+ /**
66
+ * Get all RNG outcomes for a command
67
+ */
68
+ getRngOutcomeForCommand(commandId) {
69
+ return this.rngOutcomes[commandId] || {};
70
+ }
71
+ /**
72
+ * Get all RNG outcomes across all commands
73
+ */
74
+ getAllRngOutcome() {
75
+ return { ...this.rngOutcomes };
76
+ }
77
+ /**
78
+ * Generate a single random integer in range [min, max]
79
+ * Tracks the outcome for audit trail
80
+ */
81
+ async getSingleNumber(min, max, commandId, actionId) {
82
+ // Check if we already have a cached result (for replay)
83
+ const existingSeed = this.getSeedForCommand(commandId, actionId);
84
+ if (existingSeed !== undefined) {
85
+ const existingResult = this.rngOutcomes[commandId][actionId];
86
+ return { value: existingResult.result, seed: existingResult.seed };
87
+ }
88
+ // Generate new random number
89
+ const response = await this.rngClient.getSingleNumber(min, max);
90
+ // Store for audit trail
91
+ this.storeSeedForCommand(commandId, actionId, response.value, response.seed, min, max);
92
+ return response;
93
+ }
94
+ /**
95
+ * Generate multiple random integers in range [min, max]
96
+ * Each number is tracked individually with incrementing action IDs
97
+ */
98
+ async getBatchNumbers(min, max, count, commandId, actionId) {
99
+ const results = [];
100
+ for (let i = 0; i < count; i++) {
101
+ const result = await this.getSingleNumber(min, max, commandId, `${actionId}_${i}`);
102
+ results.push(result);
103
+ }
104
+ return results;
105
+ }
106
+ /**
107
+ * Generate a weighted random selection
108
+ * Returns the index selected based on weights
109
+ */
110
+ async getWeightedRandomIndex(weights, commandId, actionId) {
111
+ const total = weights.reduce((acc, w) => acc + w, 0);
112
+ const { value: rand } = await this.getSingleNumber(0, total - 1, commandId, actionId);
113
+ let cumulative = 0;
114
+ for (let i = 0; i < weights.length; i++) {
115
+ cumulative += weights[i];
116
+ if (rand < cumulative) {
117
+ return i;
118
+ }
119
+ }
120
+ return weights.length - 1;
121
+ }
122
+ }
123
+ exports.RngService = RngService;
124
+ //# sourceMappingURL=rng-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng-service.js","sourceRoot":"","sources":["../../src/rng/rng-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Spin Generator with Symbol Limitation System
3
+ *
4
+ * Generates 3x3 grids with weighted symbol distribution and limitation constraints.
5
+ * Each symbol type has a randomly selected maximum count (2, 4, 7, or 9).
6
+ */
7
+ import { Symbol, SpinType } from '../config/happy-panda.config';
8
+ import { Grid, GameDirection, RngProvider } from '../domain/types';
9
+ /**
10
+ * Generate a grid with weighted symbols and limitation constraints.
11
+ *
12
+ * IMPORTANT: C++ logic requires limitations to be selected FIRST, then
13
+ * 3x3 check only happens if a symbol has limit=9 (max symbols).
14
+ *
15
+ * @param spinType Type of spin
16
+ * @param gameDirection Game direction
17
+ * @param rng RNG provider
18
+ * @param centerSymbol Optional fixed center symbol (for respin)
19
+ * @param previousGrid Optional grid from triggering spin (for RESPIN_CENTER_BAMBOO edge preservation)
20
+ * @returns Generated 3x3 grid
21
+ */
22
+ export declare function generateGrid(spinType: SpinType, gameDirection: GameDirection, rng: RngProvider, centerSymbol?: Symbol, previousGrid?: Grid): Promise<Grid>;
23
+ /**
24
+ * Generate panda piece grid for Bamboo Triplets bonus (Dancing Panda picture).
25
+ * Each position gets the appropriate piece symbol.
26
+ */
27
+ export declare function generatePandaPieceGrid(): Grid;
28
+ /**
29
+ * Check if grid is a complete panda piece (Dancing Panda picture for jackpot).
30
+ */
31
+ export declare function isCompletePandaPiece(grid: Grid): boolean;
32
+ //# sourceMappingURL=spin-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spin-generator.d.ts","sourceRoot":"","sources":["../../src/rng/spin-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,MAAM,EACN,QAAQ,EA+BT,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAqHnE;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,WAAW,EAChB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,IAAI,GAClB,OAAO,CAAC,IAAI,CAAC,CAgJf;AA8ED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAM7C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAiBxD"}