@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,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,31 @@
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
+ * @returns Generated 3x3 grid
20
+ */
21
+ export declare function generateGrid(spinType: SpinType, gameDirection: GameDirection, rng: RngProvider, centerSymbol?: Symbol): Promise<Grid>;
22
+ /**
23
+ * Generate cherry piece grid for jackpot bonus.
24
+ * Each position gets the appropriate piece symbol.
25
+ */
26
+ export declare function generateCherryPieceGrid(): Grid;
27
+ /**
28
+ * Check if grid is a complete cherry piece (jackpot).
29
+ */
30
+ export declare function isCompleteCherryPiece(grid: Grid): boolean;
31
+ //# 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;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,WAAW,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAgJf;AA8ED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAiBzD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Weighted Random Selection Utilities
3
+ *
4
+ * Helper functions for weighted random selection using the RNG provider.
5
+ */
6
+ import { RngProvider } from '../domain/types';
7
+ /**
8
+ * Select an index from an array of weights.
9
+ * @param weights Array of weights (must be positive integers)
10
+ * @param rng RNG provider
11
+ * @returns Selected index
12
+ */
13
+ export declare function selectWeightedIndex(weights: readonly number[], rng: RngProvider): Promise<number>;
14
+ /**
15
+ * Check if a weighted random selection succeeds.
16
+ * @param yesWeight Weight for "yes" outcome
17
+ * @param noWeight Weight for "no" outcome
18
+ * @param rng RNG provider
19
+ * @returns true if "yes" was selected
20
+ */
21
+ export declare function weightedBoolean(yesWeight: number, noWeight: number, rng: RngProvider): Promise<boolean>;
22
+ /**
23
+ * Select multiple weighted indices (with replacement).
24
+ * @param weights Array of weights
25
+ * @param count Number of selections
26
+ * @param rng RNG provider
27
+ * @returns Array of selected indices
28
+ */
29
+ export declare function selectMultipleWeighted(weights: readonly number[], count: number, rng: RngProvider): Promise<number[]>;
30
+ //# sourceMappingURL=weighted-random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weighted-random.d.ts","sourceRoot":"","sources":["../../src/rng/weighted-random.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,EAAE,CAAC,CAMnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnitronix/happy-panda-game-engine",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Happy Panda Game Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",