@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,324 @@
1
+ "use strict";
2
+ /**
3
+ * Happy Panda Game Engine
4
+ *
5
+ * Main engine class that provides the public API for the game.
6
+ * Implements the command pattern used by other Omnitronix game engines.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.HappyPandaEngine = void 0;
10
+ const types_1 = require("../domain/types");
11
+ const happy_panda_config_1 = require("../config/happy-panda.config");
12
+ const spin_handler_1 = require("../logic/handlers/spin-handler");
13
+ const counter_manager_1 = require("../logic/services/counter-manager");
14
+ // =============================================================================
15
+ // ENGINE CLASS
16
+ // =============================================================================
17
+ class HappyPandaEngine {
18
+ constructor(rngProvider) {
19
+ this.rng = rngProvider;
20
+ }
21
+ // ===========================================================================
22
+ // COMMAND HANDLING
23
+ // ===========================================================================
24
+ /**
25
+ * Handle a game command.
26
+ */
27
+ async handleCommand(command, currentState) {
28
+ switch (command.command) {
29
+ case types_1.CommandType.INIT_SESSION_STATE:
30
+ return this.handleInitSession(command);
31
+ case types_1.CommandType.SPIN:
32
+ if (!currentState) {
33
+ throw new Error('No session state for SPIN command');
34
+ }
35
+ return this.handleSpin(currentState);
36
+ case types_1.CommandType.GET_SYMBOLS:
37
+ return this.handleGetSymbols(currentState);
38
+ default:
39
+ throw new Error(`Unknown command: ${command.command}`);
40
+ }
41
+ }
42
+ // ===========================================================================
43
+ // INIT SESSION
44
+ // ===========================================================================
45
+ async handleInitSession(request) {
46
+ const gameState = (0, spin_handler_1.createInitialState)(request.gameDirection, request.betStake);
47
+ const sessionState = this.createSessionState(request.sessionId, gameState);
48
+ const publicState = this.extractPublicState(gameState);
49
+ return {
50
+ response: publicState,
51
+ state: sessionState,
52
+ };
53
+ }
54
+ // ===========================================================================
55
+ // SPIN
56
+ // ===========================================================================
57
+ async handleSpin(currentSession) {
58
+ const gameState = this.reconstructGameState(currentSession);
59
+ // Execute spin
60
+ const result = await (0, spin_handler_1.executeSpin)(gameState, this.rng);
61
+ // Build triggered bonus info if a bonus was triggered
62
+ let triggeredBonus;
63
+ if (result.bonusTriggered !== null) {
64
+ triggeredBonus = {
65
+ bonusId: `bonus-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`,
66
+ bonusType: this.spinTypeToBonusType(result.bonusTriggered),
67
+ betAmount: gameState.betGame,
68
+ };
69
+ }
70
+ // Build response
71
+ const executedType = result.executedSpinType;
72
+ const nextType = result.state.nextSpinType;
73
+ const response = {
74
+ // Game-specific fields
75
+ spinType: executedType,
76
+ screen: result.screen,
77
+ wins: result.wins,
78
+ jackpotWon: result.jackpotWon,
79
+ poolJackpotWon: result.poolJackpotWon,
80
+ triggeredBonus,
81
+ isBonusComplete: result.isBonusComplete,
82
+ playerWinning: result.playerWinning,
83
+ nextSpinType: nextType,
84
+ // BaseOutcome standardized fields
85
+ actionType: executedType,
86
+ nextActionType: nextType,
87
+ roundPhase: executedType === happy_panda_config_1.SpinType.BASE_GAME_SPIN ? 'BASE' : 'BONUS',
88
+ isRoundComplete: result.isBonusComplete,
89
+ };
90
+ // Update session state
91
+ const newSession = this.createSessionState(currentSession.sessionId, result.state);
92
+ return {
93
+ response,
94
+ state: newSession,
95
+ };
96
+ }
97
+ // ===========================================================================
98
+ // GET SYMBOLS
99
+ // ===========================================================================
100
+ async handleGetSymbols(currentSession) {
101
+ // Return symbol definitions
102
+ const symbols = Object.entries(happy_panda_config_1.Symbol)
103
+ .filter(([key]) => isNaN(Number(key)))
104
+ .map(([name, value]) => ({ name, value }));
105
+ return {
106
+ response: { symbols },
107
+ state: currentSession || this.createEmptySession(),
108
+ };
109
+ }
110
+ // ===========================================================================
111
+ // STATE MANAGEMENT
112
+ // ===========================================================================
113
+ /**
114
+ * Extract public state from game state.
115
+ */
116
+ extractPublicState(state) {
117
+ return {
118
+ gameDirection: state.gameDirection,
119
+ betStake: state.betStake,
120
+ betGame: state.betGame,
121
+ currentSpinType: state.currentSpinType,
122
+ spinsRemaining: state.spinsRemaining,
123
+ screen: state.screen,
124
+ bonusJackpotValue: state.jackpots.bonusJackpotValue,
125
+ poolJackpotValue: state.jackpots.poolJackpotValue,
126
+ hasPendingBonus: (0, counter_manager_1.hasPendingBonus)(state.pendingBonuses),
127
+ additionalData: {
128
+ counters: state.counters,
129
+ },
130
+ };
131
+ }
132
+ /**
133
+ * Extract private state from game state.
134
+ * Converts internal counter-based pendingBonuses to RGS-compatible array format.
135
+ */
136
+ extractPrivateState(state) {
137
+ // Convert counter-based pending bonuses to RGS-compatible array format
138
+ const pendingBonusesArray = this.convertPendingBonusesToArray(state.pendingBonuses, state.betGame);
139
+ // Determine if there's an active bonus (currently in a bonus round)
140
+ let activeBonus;
141
+ if (state.currentSpinType !== happy_panda_config_1.SpinType.BASE_GAME_SPIN && state.spinsRemaining > 0) {
142
+ activeBonus = {
143
+ bonusId: `active-${state.currentSpinType}-${Date.now()}`,
144
+ bonusType: this.spinTypeToBonusType(state.currentSpinType),
145
+ betAmount: state.betGame,
146
+ };
147
+ }
148
+ return {
149
+ counters: state.counters,
150
+ internalPendingBonuses: state.pendingBonuses,
151
+ nextSpinType: state.nextSpinType,
152
+ accumulatedBonusWins: state.accumulatedBonusWins,
153
+ centerBambooSymbol: state.centerBambooSymbol,
154
+ pendingBonuses: pendingBonusesArray,
155
+ activeBonus,
156
+ };
157
+ }
158
+ /**
159
+ * Convert counter-based pending bonuses to RGS-compatible array format.
160
+ */
161
+ convertPendingBonusesToArray(pending, betAmount) {
162
+ const bonuses = [];
163
+ const timestamp = Date.now();
164
+ // Add bonuses in priority order (bambooTriplets > bambooTwins > camera > fireworks > centerBamboo)
165
+ for (let i = 0; i < pending.bambooTriplets; i++) {
166
+ bonuses.push({
167
+ bonusId: `pending-bambooTriplets-${timestamp}-${i}`,
168
+ bonusType: 'BONUS_BAMBOO_TRIPLETS',
169
+ betAmount,
170
+ });
171
+ }
172
+ for (let i = 0; i < pending.bambooTwins; i++) {
173
+ bonuses.push({
174
+ bonusId: `pending-bambooTwins-${timestamp}-${i}`,
175
+ bonusType: 'BONUS_BAMBOO_TWINS',
176
+ betAmount,
177
+ });
178
+ }
179
+ for (let i = 0; i < pending.camera; i++) {
180
+ bonuses.push({
181
+ bonusId: `pending-camera-${timestamp}-${i}`,
182
+ bonusType: 'BONUS_CAMERA',
183
+ betAmount,
184
+ });
185
+ }
186
+ for (let i = 0; i < pending.fireworks; i++) {
187
+ bonuses.push({
188
+ bonusId: `pending-fireworks-${timestamp}-${i}`,
189
+ bonusType: 'BONUS_FIREWORKS',
190
+ betAmount,
191
+ });
192
+ }
193
+ for (let i = 0; i < pending.centerBamboo; i++) {
194
+ bonuses.push({
195
+ bonusId: `pending-centerBamboo-${timestamp}-${i}`,
196
+ bonusType: 'RESPIN_CENTER_BAMBOO',
197
+ betAmount,
198
+ });
199
+ }
200
+ return bonuses;
201
+ }
202
+ /**
203
+ * Convert SpinType to bonus type string for RGS.
204
+ * Now that SpinType is a string enum, this is a simple cast.
205
+ */
206
+ spinTypeToBonusType(spinType) {
207
+ return spinType;
208
+ }
209
+ /**
210
+ * Create session state from game state.
211
+ */
212
+ createSessionState(sessionId, state) {
213
+ return {
214
+ sessionId,
215
+ publicState: this.extractPublicState(state),
216
+ privateState: this.extractPrivateState(state),
217
+ createdAt: new Date(),
218
+ updatedAt: new Date(),
219
+ };
220
+ }
221
+ /**
222
+ * Reconstruct game state from session state.
223
+ */
224
+ reconstructGameState(session) {
225
+ const pub = session.publicState;
226
+ const priv = session.privateState;
227
+ // Use internalPendingBonuses (counter format) for game logic
228
+ // Fall back to converting from array format if internalPendingBonuses is not present (legacy state)
229
+ const pendingBonuses = priv.internalPendingBonuses ??
230
+ this.convertArrayToPendingBonuses(priv.pendingBonuses);
231
+ return {
232
+ gameDirection: pub.gameDirection,
233
+ betStake: pub.betStake,
234
+ betGame: pub.betGame,
235
+ currentSpinType: pub.currentSpinType,
236
+ nextSpinType: priv.nextSpinType,
237
+ spinsRemaining: pub.spinsRemaining,
238
+ counters: priv.counters,
239
+ pendingBonuses,
240
+ jackpots: {
241
+ bonusJackpotValue: pub.bonusJackpotValue,
242
+ poolJackpotValue: pub.poolJackpotValue,
243
+ },
244
+ screen: pub.screen,
245
+ accumulatedBonusWins: priv.accumulatedBonusWins,
246
+ centerBambooSymbol: priv.centerBambooSymbol,
247
+ };
248
+ }
249
+ /**
250
+ * Convert RGS-compatible array back to counter-based format (for legacy state compatibility).
251
+ */
252
+ convertArrayToPendingBonuses(bonuses) {
253
+ const result = {
254
+ bambooTriplets: 0,
255
+ bambooTwins: 0,
256
+ camera: 0,
257
+ fireworks: 0,
258
+ centerBamboo: 0,
259
+ };
260
+ if (!bonuses || !Array.isArray(bonuses)) {
261
+ return result;
262
+ }
263
+ for (const bonus of bonuses) {
264
+ switch (bonus.bonusType) {
265
+ case 'BONUS_BAMBOO_TRIPLETS':
266
+ result.bambooTriplets++;
267
+ break;
268
+ case 'BONUS_BAMBOO_TWINS':
269
+ result.bambooTwins++;
270
+ break;
271
+ case 'BONUS_CAMERA':
272
+ result.camera++;
273
+ break;
274
+ case 'BONUS_FIREWORKS':
275
+ result.fireworks++;
276
+ break;
277
+ case 'RESPIN_CENTER_BAMBOO':
278
+ result.centerBamboo++;
279
+ break;
280
+ }
281
+ }
282
+ return result;
283
+ }
284
+ /**
285
+ * Create empty session for commands that don't need state.
286
+ */
287
+ createEmptySession() {
288
+ return {
289
+ sessionId: '',
290
+ publicState: this.extractPublicState((0, spin_handler_1.createInitialState)(types_1.GameDirection.SINGLE, 1)),
291
+ privateState: {
292
+ counters: { bambooTriplets: 1, bambooTwins: 9, camera: 5, fireworks: 1 },
293
+ internalPendingBonuses: { bambooTriplets: 0, bambooTwins: 0, camera: 0, fireworks: 0, centerBamboo: 0 },
294
+ nextSpinType: happy_panda_config_1.SpinType.BASE_GAME_SPIN,
295
+ accumulatedBonusWins: 0,
296
+ centerBambooSymbol: null,
297
+ pendingBonuses: [],
298
+ activeBonus: undefined,
299
+ },
300
+ createdAt: new Date(),
301
+ updatedAt: new Date(),
302
+ };
303
+ }
304
+ // ===========================================================================
305
+ // UTILITY METHODS
306
+ // ===========================================================================
307
+ /**
308
+ * Update bet settings (only when no bonus pending).
309
+ */
310
+ updateBet(session, gameDirection, betStake) {
311
+ const gameState = this.reconstructGameState(session);
312
+ const updatedState = (0, spin_handler_1.updateBet)(gameState, gameDirection, betStake);
313
+ return this.createSessionState(session.sessionId, updatedState);
314
+ }
315
+ /**
316
+ * Check if player can change bet.
317
+ */
318
+ canChangeBet(session) {
319
+ return (session.publicState.currentSpinType === happy_panda_config_1.SpinType.BASE_GAME_SPIN &&
320
+ !session.publicState.hasPendingBonus);
321
+ }
322
+ }
323
+ exports.HappyPandaEngine = HappyPandaEngine;
324
+ //# sourceMappingURL=happy-panda-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"happy-panda-engine.js","sourceRoot":"","sources":["../../src/engine/happy-panda-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Engine module exports
3
+ */
4
+ export * from './happy-panda-engine';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * Engine module exports
19
+ */
20
+ __exportStar(require("./happy-panda-engine"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,uDAAqC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Game Engine Interface Types
3
+ *
4
+ * Re-exports types from @omnitronix/game-engine-contract for use by consumers.
5
+ * Defines Happy Panda-specific configuration types.
6
+ */
7
+ import type { ILogger as ILoggerType } from '@omnitronix/game-engine-contract';
8
+ export { GameEngine, GameEngineInfo, } from '@omnitronix/game-engine-contract';
9
+ export { GameActionCommand, CommandProcessingResult, } from '@omnitronix/game-engine-contract';
10
+ export { RngOutcome, RngOutcomeRecord, } from '@omnitronix/game-engine-contract';
11
+ export { ILogger } from '@omnitronix/game-engine-contract';
12
+ /**
13
+ * Configuration options for HappyPandaV1GameEngine
14
+ */
15
+ export interface HappyPandaV1GameEngineConfig {
16
+ logger?: ILoggerType;
17
+ metrics?: unknown;
18
+ }
19
+ //# sourceMappingURL=game-engine.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game-engine.interface.d.ts","sourceRoot":"","sources":["../src/game-engine.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAG/E,OAAO,EACL,UAAU,EACV,cAAc,GACf,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,UAAU,EACV,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * Game Engine Interface Types
4
+ *
5
+ * Re-exports types from @omnitronix/game-engine-contract for use by consumers.
6
+ * Defines Happy Panda-specific configuration types.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ //# sourceMappingURL=game-engine.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game-engine.interface.js","sourceRoot":"","sources":["../src/game-engine.interface.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * HappyPandaV1GameEngine
3
+ *
4
+ * Wrapper class that adapts HappyPandaEngine to the standard GameEngine interface
5
+ * expected by the game-engine-service infrastructure.
6
+ *
7
+ * Uses the proper RNG infrastructure matching Heroes of Aether and Bonny's Fortune:
8
+ * - RngClientFactory for environment-based client selection
9
+ * - RngService for audit trail tracking
10
+ * - Full RNG outcome reporting for compliance
11
+ */
12
+ import { DebugIntrospectable, DebugCommandDefinition } from '@omnitronix/game-engine-contract';
13
+ import { SlotGameHandler, BetConfig as SdkBetConfig, SlotState as SdkSlotState, SpinResult as SdkSpinResult, BonusTrigger as SdkBonusTrigger, BonusResult as SdkBonusResult, GameTypeConfig } from '@omnitronix/game-engine-sdk';
14
+ import { PublicState, PrivateState } from './domain/types';
15
+ import { GameEngine, GameEngineInfo, GameActionCommand, CommandProcessingResult, HappyPandaV1GameEngineConfig, RngOutcome, RngOutcomeRecord } from './game-engine.interface';
16
+ export type { GameEngine, GameEngineInfo, GameActionCommand, CommandProcessingResult, HappyPandaV1GameEngineConfig, RngOutcome, RngOutcomeRecord, };
17
+ /**
18
+ * Happy Panda V1 Game Engine
19
+ *
20
+ * Implements the standard GameEngine interface for use with game-engine-service.
21
+ * Uses proper RNG infrastructure with full audit trail support.
22
+ */
23
+ export declare class HappyPandaV1GameEngine extends SlotGameHandler implements GameEngine<PublicState, PrivateState, unknown>, DebugIntrospectable {
24
+ /**
25
+ * SDK GameTypeConfig declaration.
26
+ *
27
+ * Declares this engine as a slot game with immediate result delivery
28
+ * and token-encoded state management.
29
+ */
30
+ static readonly gameTypeConfig: GameTypeConfig;
31
+ private readonly gameCode;
32
+ private readonly version;
33
+ private readonly rtp;
34
+ private readonly gameType;
35
+ private readonly gameName;
36
+ private readonly provider;
37
+ private readonly rngService;
38
+ private readonly rngAdapter;
39
+ private readonly engine;
40
+ constructor(config?: HappyPandaV1GameEngineConfig);
41
+ /**
42
+ * Implements SlotGameHandler.spin().
43
+ *
44
+ * Delegates to the internal HappyPandaEngine SPIN command and maps
45
+ * the result to the SDK SpinResult contract.
46
+ */
47
+ spin(bet: SdkBetConfig, state: SdkSlotState): Promise<SdkSpinResult>;
48
+ /**
49
+ * Implements SlotGameHandler.startBonus().
50
+ *
51
+ * Delegates to the internal HappyPandaEngine by executing all bonus
52
+ * spins in a loop (precomputed-queue strategy) and returns a
53
+ * BonusResult with attached delivery strategy metadata.
54
+ */
55
+ startBonus(trigger: SdkBonusTrigger, state: SdkSlotState): Promise<SdkBonusResult>;
56
+ getGameEngineInfo(): GameEngineInfo;
57
+ getDebugCommandDefinitions(): DebugCommandDefinition[];
58
+ processCommand(publicState: PublicState | null, privateState: PrivateState | null, command: GameActionCommand): Promise<CommandProcessingResult<PublicState, PrivateState, unknown>>;
59
+ }
60
+ //# sourceMappingURL=happy-panda-v1.game-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"happy-panda-v1.game-engine.d.ts","sourceRoot":"","sources":["../src/happy-panda-v1.game-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,eAAe,EACf,SAAS,IAAI,YAAY,EACzB,SAAS,IAAI,YAAY,EACzB,UAAU,IAAI,aAAa,EAC3B,YAAY,IAAI,eAAe,EAC/B,WAAW,IAAI,cAAc,EAC7B,cAAc,EAGf,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAGL,WAAW,EACX,YAAY,EAKb,MAAM,gBAAgB,CAAC;AAKxB,OAAO,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,4BAA4B,EAC5B,UAAU,EACV,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EACV,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,4BAA4B,EAC5B,UAAU,EACV,gBAAgB,GACjB,CAAC;AAuCF;;;;;GAKG;AACH,qBAAa,sBACX,SAAQ,eACR,YAAW,UAAU,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,mBAAmB;IAE9E;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAW5C;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IAEzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAE9B,MAAM,GAAE,4BAAiC;IAkBrD;;;;;OAKG;IACG,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA4C1E;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAsEjF,iBAAiB,IAAI,cAAc;IAWnC,0BAA0B,IAAI,sBAAsB,EAAE;IAIhD,cAAc,CACzB,WAAW,EAAE,WAAW,GAAG,IAAI,EAC/B,YAAY,EAAE,YAAY,GAAG,IAAI,EACjC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,uBAAuB,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;CAkXxE"}