@omnitronix/happy-panda-game-engine 0.0.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 (71) hide show
  1. package/README.md +212 -0
  2. package/dist/__tests__/bonus-sequence.test.js +337 -0
  3. package/dist/__tests__/bonus-sequence.test.js.map +1 -0
  4. package/dist/__tests__/cherry-frequency.test.js +128 -0
  5. package/dist/__tests__/cherry-frequency.test.js.map +1 -0
  6. package/dist/__tests__/counter-manager.test.js +316 -0
  7. package/dist/__tests__/counter-manager.test.js.map +1 -0
  8. package/dist/__tests__/cpp-parity.test.js +368 -0
  9. package/dist/__tests__/cpp-parity.test.js.map +1 -0
  10. package/dist/__tests__/fixtures/cpp-parity-vectors.json +438 -0
  11. package/dist/__tests__/happy-panda-engine.test.js +367 -0
  12. package/dist/__tests__/happy-panda-engine.test.js.map +1 -0
  13. package/dist/__tests__/jackpot-manager.test.js +313 -0
  14. package/dist/__tests__/jackpot-manager.test.js.map +1 -0
  15. package/dist/__tests__/jackpot-trigger-trace.test.js +146 -0
  16. package/dist/__tests__/jackpot-trigger-trace.test.js.map +1 -0
  17. package/dist/__tests__/rtp-1million.test.js +156 -0
  18. package/dist/__tests__/rtp-1million.test.js.map +1 -0
  19. package/dist/__tests__/rtp-analysis.test.js +138 -0
  20. package/dist/__tests__/rtp-analysis.test.js.map +1 -0
  21. package/dist/__tests__/rtp-diagnostic.test.js +126 -0
  22. package/dist/__tests__/rtp-diagnostic.test.js.map +1 -0
  23. package/dist/__tests__/rtp-simulation.test.js +409 -0
  24. package/dist/__tests__/rtp-simulation.test.js.map +1 -0
  25. package/dist/__tests__/special-wins.test.js +179 -0
  26. package/dist/__tests__/special-wins.test.js.map +1 -0
  27. package/dist/__tests__/spin-generator.test.js +250 -0
  28. package/dist/__tests__/spin-generator.test.js.map +1 -0
  29. package/dist/__tests__/spin-handler.test.js +210 -0
  30. package/dist/__tests__/spin-handler.test.js.map +1 -0
  31. package/dist/__tests__/symbol-distribution.test.js +119 -0
  32. package/dist/__tests__/symbol-distribution.test.js.map +1 -0
  33. package/dist/__tests__/weighted-random.test.js +165 -0
  34. package/dist/__tests__/weighted-random.test.js.map +1 -0
  35. package/dist/__tests__/win-evaluator.test.js +254 -0
  36. package/dist/__tests__/win-evaluator.test.js.map +1 -0
  37. package/dist/config/happy-panda.config.js +714 -0
  38. package/dist/config/happy-panda.config.js.map +1 -0
  39. package/dist/config/index.js +21 -0
  40. package/dist/config/index.js.map +1 -0
  41. package/dist/domain/index.js +21 -0
  42. package/dist/domain/index.js.map +1 -0
  43. package/dist/domain/types.js +28 -0
  44. package/dist/domain/types.js.map +1 -0
  45. package/dist/engine/happy-panda-engine.js +197 -0
  46. package/dist/engine/happy-panda-engine.js.map +1 -0
  47. package/dist/engine/index.js +21 -0
  48. package/dist/engine/index.js.map +1 -0
  49. package/dist/index.js +34 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/logic/handlers/index.js +21 -0
  52. package/dist/logic/handlers/index.js.map +1 -0
  53. package/dist/logic/handlers/spin-handler.js +256 -0
  54. package/dist/logic/handlers/spin-handler.js.map +1 -0
  55. package/dist/logic/index.js +22 -0
  56. package/dist/logic/index.js.map +1 -0
  57. package/dist/logic/services/counter-manager.js +265 -0
  58. package/dist/logic/services/counter-manager.js.map +1 -0
  59. package/dist/logic/services/index.js +23 -0
  60. package/dist/logic/services/index.js.map +1 -0
  61. package/dist/logic/services/jackpot-manager.js +142 -0
  62. package/dist/logic/services/jackpot-manager.js.map +1 -0
  63. package/dist/logic/services/win-evaluator.js +470 -0
  64. package/dist/logic/services/win-evaluator.js.map +1 -0
  65. package/dist/rng/index.js +22 -0
  66. package/dist/rng/index.js.map +1 -0
  67. package/dist/rng/spin-generator.js +341 -0
  68. package/dist/rng/spin-generator.js.map +1 -0
  69. package/dist/rng/weighted-random.js +58 -0
  70. package/dist/rng/weighted-random.js.map +1 -0
  71. package/package.json +49 -0
@@ -0,0 +1,313 @@
1
+ "use strict";
2
+ /**
3
+ * Jackpot Manager Tests
4
+ *
5
+ * Tests for progressive and pool jackpot logic.
6
+ * CRITICAL: This is where money comes/goes - must have high coverage.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const jackpot_manager_1 = require("../logic/services/jackpot-manager");
10
+ const happy_panda_config_1 = require("../config/happy-panda.config");
11
+ const types_1 = require("../domain/types");
12
+ // Mock RNG that always returns specified value
13
+ function createMockRng(returnValue = 0) {
14
+ return {
15
+ async random(max) {
16
+ return returnValue % max;
17
+ },
18
+ async randomBatch(count, max) {
19
+ return Array(count).fill(returnValue % max);
20
+ },
21
+ };
22
+ }
23
+ // Helper to create grid with specific center symbol
24
+ function createGridWithCenter(centerSymbol, otherSymbol = happy_panda_config_1.Symbol.MELON) {
25
+ return [
26
+ [otherSymbol, otherSymbol, otherSymbol],
27
+ [otherSymbol, centerSymbol, otherSymbol],
28
+ [otherSymbol, otherSymbol, otherSymbol],
29
+ ];
30
+ }
31
+ describe('Jackpot Manager', () => {
32
+ describe('createInitialJackpots', () => {
33
+ it('should initialize bonus jackpot at 100x betGame', () => {
34
+ const jackpots = (0, jackpot_manager_1.createInitialJackpots)(8);
35
+ expect(jackpots.bonusJackpotValue).toBe(100 * 8);
36
+ });
37
+ it('should initialize pool jackpot at configured init value', () => {
38
+ const jackpots = (0, jackpot_manager_1.createInitialJackpots)(16);
39
+ expect(jackpots.poolJackpotValue).toBe(happy_panda_config_1.POOL_JACKPOT.INIT * 16);
40
+ });
41
+ it('should scale with betGame', () => {
42
+ const jackpots8 = (0, jackpot_manager_1.createInitialJackpots)(8);
43
+ const jackpots80 = (0, jackpot_manager_1.createInitialJackpots)(80);
44
+ expect(jackpots80.bonusJackpotValue).toBe(jackpots8.bonusJackpotValue * 10);
45
+ });
46
+ });
47
+ describe('Progressive Jackpot - updateProgressiveJackpot', () => {
48
+ describe('Spin Type Restrictions', () => {
49
+ it('should NOT increase on winning paid spin', async () => {
50
+ const currentValue = 800;
51
+ const rng = createMockRng(0); // Would increase if allowed
52
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 10, // Has a win
53
+ rng);
54
+ expect(newValue).toBe(currentValue);
55
+ });
56
+ it('should NOT increase during bonus spins', async () => {
57
+ const currentValue = 800;
58
+ const rng = createMockRng(0);
59
+ const bonusTypes = [
60
+ happy_panda_config_1.SpinType.BONUS_JACKPOT,
61
+ happy_panda_config_1.SpinType.BONUS_CHERRY,
62
+ happy_panda_config_1.SpinType.BONUS_BELL,
63
+ happy_panda_config_1.SpinType.BONUS_BAR1,
64
+ happy_panda_config_1.SpinType.RESPIN_CHERRY,
65
+ ];
66
+ for (const spinType of bonusTypes) {
67
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, 8, 1, spinType, 0, rng);
68
+ expect(newValue).toBe(currentValue);
69
+ }
70
+ });
71
+ });
72
+ describe('Probability Logic', () => {
73
+ it('should increase on losing paid spin when RNG allows (3/13 probability)', async () => {
74
+ const currentValue = 800;
75
+ // RNG that triggers the "yes" path
76
+ const rng = createMockRng(0);
77
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, // No win
78
+ rng);
79
+ // Should increase by INCREMENT_VALUE * betStake
80
+ const expectedIncrement = happy_panda_config_1.BONUS_JACKPOT.INCREMENT_VALUE[types_1.GameDirection.SINGLE] * 1;
81
+ expect(newValue).toBe(currentValue + expectedIncrement);
82
+ });
83
+ it('should NOT increase when RNG returns no-increase', async () => {
84
+ const currentValue = 800;
85
+ // RNG that returns value that falls in "no" path
86
+ // Weights are [3, 10] for SINGLE, so values 3-12 should be "no"
87
+ const rng = createMockRng(5);
88
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
89
+ expect(newValue).toBe(currentValue);
90
+ });
91
+ });
92
+ describe('Maximum Cap', () => {
93
+ it('should cap at 1000x betGame', async () => {
94
+ const betGame = 8;
95
+ const maxValue = happy_panda_config_1.BONUS_JACKPOT.MAX * betGame; // 1000 * 8 = 8000
96
+ const currentValue = maxValue - 1; // One below max
97
+ const rng = createMockRng(0); // Will try to increase
98
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, betGame, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
99
+ expect(newValue).toBeLessThanOrEqual(maxValue);
100
+ });
101
+ it('should stay at max if already at max', async () => {
102
+ const betGame = 8;
103
+ const maxValue = happy_panda_config_1.BONUS_JACKPOT.MAX * betGame;
104
+ const rng = createMockRng(0);
105
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(maxValue, types_1.GameDirection.SINGLE, betGame, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
106
+ expect(newValue).toBe(maxValue);
107
+ });
108
+ });
109
+ describe('Bet Stake Scaling', () => {
110
+ it('should scale increment with betStake', async () => {
111
+ const currentValue = 800;
112
+ const rng = createMockRng(0);
113
+ const newValue1 = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, 8, 1, // betStake = 1
114
+ happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
115
+ const increment1 = newValue1 - currentValue;
116
+ // Reset and test with betStake = 5
117
+ const newValue5 = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, 40, 5, // betStake = 5
118
+ happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
119
+ const increment5 = newValue5 - currentValue;
120
+ expect(increment5).toBe(increment1 * 5);
121
+ });
122
+ });
123
+ describe('Game Direction Differences', () => {
124
+ it('should use correct weights for SINGLE mode', async () => {
125
+ const currentValue = 800;
126
+ const rng = createMockRng(0);
127
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
128
+ const expectedIncrement = happy_panda_config_1.BONUS_JACKPOT.INCREMENT_VALUE[types_1.GameDirection.SINGLE] * 1;
129
+ expect(newValue).toBe(currentValue + expectedIncrement);
130
+ });
131
+ it('should use correct weights for BOTH mode', async () => {
132
+ const currentValue = 1600;
133
+ const rng = createMockRng(0);
134
+ const newValue = await (0, jackpot_manager_1.updateProgressiveJackpot)(currentValue, types_1.GameDirection.BOTH, 16, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
135
+ const expectedIncrement = happy_panda_config_1.BONUS_JACKPOT.INCREMENT_VALUE[types_1.GameDirection.BOTH] * 1;
136
+ expect(newValue).toBe(currentValue + expectedIncrement);
137
+ });
138
+ });
139
+ });
140
+ describe('Progressive Jackpot - payProgressiveJackpot', () => {
141
+ it('should return current value as payout', () => {
142
+ const currentValue = 5000;
143
+ const { payout } = (0, jackpot_manager_1.payProgressiveJackpot)(currentValue, 8);
144
+ expect(payout).toBe(5000);
145
+ });
146
+ it('should reset to initial value', () => {
147
+ const currentValue = 5000;
148
+ const betGame = 8;
149
+ const { newValue } = (0, jackpot_manager_1.payProgressiveJackpot)(currentValue, betGame);
150
+ expect(newValue).toBe(happy_panda_config_1.BONUS_JACKPOT.INIT * betGame);
151
+ });
152
+ it('should return both payout and new value', () => {
153
+ const result = (0, jackpot_manager_1.payProgressiveJackpot)(3000, 16);
154
+ expect(result).toHaveProperty('payout');
155
+ expect(result).toHaveProperty('newValue');
156
+ });
157
+ });
158
+ describe('Pool Jackpot - updatePoolJackpot', () => {
159
+ describe('Spin Type Restrictions', () => {
160
+ it('should NOT increase on winning spin', () => {
161
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
162
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 10 // Has a win
163
+ );
164
+ expect(newValue).toBe(0);
165
+ });
166
+ it('should NOT increase during bonus spins', () => {
167
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
168
+ const bonusTypes = [
169
+ happy_panda_config_1.SpinType.BONUS_JACKPOT,
170
+ happy_panda_config_1.SpinType.BONUS_CHERRY,
171
+ happy_panda_config_1.SpinType.BONUS_BELL,
172
+ happy_panda_config_1.SpinType.BONUS_BAR1,
173
+ happy_panda_config_1.SpinType.RESPIN_CHERRY,
174
+ ];
175
+ for (const spinType of bonusTypes) {
176
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, spinType, 0);
177
+ expect(newValue).toBe(0);
178
+ }
179
+ });
180
+ });
181
+ describe('Center Symbol Requirements', () => {
182
+ it('should increase with Seven in center (only Seven on screen)', () => {
183
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
184
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
185
+ const expectedIncrement = happy_panda_config_1.POOL_JACKPOT.INCREMENT[types_1.GameDirection.SINGLE][1] * 1;
186
+ expect(newValue).toBe(expectedIncrement);
187
+ });
188
+ it('should increase with Super Seven in center (only Seven on screen)', () => {
189
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SUPER_SEVEN);
190
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
191
+ const expectedIncrement = happy_panda_config_1.POOL_JACKPOT.INCREMENT[types_1.GameDirection.SINGLE][0] * 1;
192
+ expect(newValue).toBe(expectedIncrement);
193
+ });
194
+ it('should NOT increase with non-Seven in center', () => {
195
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.CHERRY);
196
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
197
+ expect(newValue).toBe(0);
198
+ });
199
+ it('should NOT increase with multiple Sevens on screen', () => {
200
+ const grid = [
201
+ [happy_panda_config_1.Symbol.SEVEN, happy_panda_config_1.Symbol.MELON, happy_panda_config_1.Symbol.PRUNE],
202
+ [happy_panda_config_1.Symbol.ORANGE, happy_panda_config_1.Symbol.SEVEN, happy_panda_config_1.Symbol.BAR3], // Two Sevens
203
+ [happy_panda_config_1.Symbol.BELL, happy_panda_config_1.Symbol.BAR2, happy_panda_config_1.Symbol.BAR1],
204
+ ];
205
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
206
+ expect(newValue).toBe(0);
207
+ });
208
+ it('should NOT increase with Seven NOT in center', () => {
209
+ const grid = [
210
+ [happy_panda_config_1.Symbol.SEVEN, happy_panda_config_1.Symbol.MELON, happy_panda_config_1.Symbol.PRUNE], // Seven at (0,0) not center
211
+ [happy_panda_config_1.Symbol.ORANGE, happy_panda_config_1.Symbol.MELON, happy_panda_config_1.Symbol.BAR3],
212
+ [happy_panda_config_1.Symbol.BELL, happy_panda_config_1.Symbol.BAR2, happy_panda_config_1.Symbol.BAR1],
213
+ ];
214
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
215
+ expect(newValue).toBe(0);
216
+ });
217
+ });
218
+ describe('Maximum Cap', () => {
219
+ it('should cap at 250x betGame', () => {
220
+ const betGame = 8;
221
+ const maxValue = happy_panda_config_1.POOL_JACKPOT.MAX * betGame;
222
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SUPER_SEVEN);
223
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(maxValue - 1, grid, types_1.GameDirection.SINGLE, betGame, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
224
+ expect(newValue).toBeLessThanOrEqual(maxValue);
225
+ });
226
+ it('should stay at max if already at max', () => {
227
+ const betGame = 8;
228
+ const maxValue = happy_panda_config_1.POOL_JACKPOT.MAX * betGame;
229
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SUPER_SEVEN);
230
+ const newValue = (0, jackpot_manager_1.updatePoolJackpot)(maxValue, grid, types_1.GameDirection.SINGLE, betGame, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
231
+ expect(newValue).toBe(maxValue);
232
+ });
233
+ });
234
+ describe('Bet Stake Scaling', () => {
235
+ it('should scale increment with betStake', () => {
236
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
237
+ const newValue1 = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
238
+ const newValue5 = (0, jackpot_manager_1.updatePoolJackpot)(0, grid, types_1.GameDirection.SINGLE, 40, 5, happy_panda_config_1.SpinType.PAID_SPIN, 0);
239
+ expect(newValue5).toBe(newValue1 * 5);
240
+ });
241
+ });
242
+ describe('Super Seven vs Seven Increment', () => {
243
+ it('should give higher increment for Super Seven', () => {
244
+ const gridSeven = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
245
+ const gridSuperSeven = createGridWithCenter(happy_panda_config_1.Symbol.SUPER_SEVEN);
246
+ const valueSeven = (0, jackpot_manager_1.updatePoolJackpot)(0, gridSeven, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
247
+ const valueSuperSeven = (0, jackpot_manager_1.updatePoolJackpot)(0, gridSuperSeven, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0);
248
+ // Super Seven should give higher increment
249
+ expect(valueSuperSeven).toBeGreaterThanOrEqual(valueSeven);
250
+ });
251
+ });
252
+ });
253
+ describe('Pool Jackpot - payPoolJackpot', () => {
254
+ it('should return current value as payout', () => {
255
+ const currentValue = 2000;
256
+ const { payout } = (0, jackpot_manager_1.payPoolJackpot)(currentValue, 8);
257
+ expect(payout).toBe(2000);
258
+ });
259
+ it('should reset to initial value', () => {
260
+ const currentValue = 2000;
261
+ const betGame = 8;
262
+ const { newValue } = (0, jackpot_manager_1.payPoolJackpot)(currentValue, betGame);
263
+ expect(newValue).toBe(happy_panda_config_1.POOL_JACKPOT.INIT * betGame);
264
+ });
265
+ });
266
+ describe('Combined Update - updateJackpots', () => {
267
+ it('should update both jackpots together', async () => {
268
+ const currentJackpots = {
269
+ bonusJackpotValue: 800,
270
+ poolJackpotValue: 0,
271
+ };
272
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
273
+ const rng = createMockRng(0);
274
+ const result = await (0, jackpot_manager_1.updateJackpots)(currentJackpots, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
275
+ expect(result.jackpots).toBeDefined();
276
+ expect(result.jackpots.bonusJackpotValue).toBeDefined();
277
+ expect(result.jackpots.poolJackpotValue).toBeDefined();
278
+ });
279
+ it('should track if progressive increased', async () => {
280
+ const currentJackpots = {
281
+ bonusJackpotValue: 800,
282
+ poolJackpotValue: 0,
283
+ };
284
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.MELON);
285
+ const rng = createMockRng(0);
286
+ const result = await (0, jackpot_manager_1.updateJackpots)(currentJackpots, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
287
+ expect(typeof result.progressiveJackpotIncreased).toBe('boolean');
288
+ });
289
+ it('should track if pool increased', async () => {
290
+ const currentJackpots = {
291
+ bonusJackpotValue: 800,
292
+ poolJackpotValue: 0,
293
+ };
294
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
295
+ const rng = createMockRng(5); // Won't increase progressive
296
+ const result = await (0, jackpot_manager_1.updateJackpots)(currentJackpots, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 0, rng);
297
+ expect(result.poolJackpotIncreased).toBe(true);
298
+ });
299
+ it('should return false for increases when there are wins', async () => {
300
+ const currentJackpots = {
301
+ bonusJackpotValue: 800,
302
+ poolJackpotValue: 100,
303
+ };
304
+ const grid = createGridWithCenter(happy_panda_config_1.Symbol.SEVEN);
305
+ const rng = createMockRng(0);
306
+ const result = await (0, jackpot_manager_1.updateJackpots)(currentJackpots, grid, types_1.GameDirection.SINGLE, 8, 1, happy_panda_config_1.SpinType.PAID_SPIN, 50, // Has wins
307
+ rng);
308
+ expect(result.progressiveJackpotIncreased).toBe(false);
309
+ expect(result.poolJackpotIncreased).toBe(false);
310
+ });
311
+ });
312
+ });
313
+ //# sourceMappingURL=jackpot-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jackpot-manager.test.js","sourceRoot":"","sources":["../../src/__tests__/jackpot-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ /**
3
+ * Jackpot Trigger Trace Test
4
+ * Tracks where BONUS_JACKPOT triggers originate (PAID_SPIN vs RESPIN_CHERRY)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const happy_panda_engine_1 = require("../engine/happy-panda-engine");
8
+ const happy_panda_config_1 = require("../config/happy-panda.config");
9
+ const types_1 = require("../domain/types");
10
+ function createSimulationRng(seed = 12345) {
11
+ let state = seed;
12
+ function nextInt() {
13
+ state = (state * 1664525 + 1013904223) >>> 0;
14
+ return state;
15
+ }
16
+ return {
17
+ async random(max) {
18
+ return nextInt() % max;
19
+ },
20
+ async randomBatch(count, max) {
21
+ const results = [];
22
+ for (let i = 0; i < count; i++) {
23
+ results.push(nextInt() % max);
24
+ }
25
+ return results;
26
+ },
27
+ };
28
+ }
29
+ function count3xCherryLines(grid) {
30
+ let count = 0;
31
+ for (let lineIndex = 0; lineIndex < 8; lineIndex++) {
32
+ const lineShape = happy_panda_config_1.LINE_SHAPES[lineIndex];
33
+ const symbols = lineShape.map(([reel, row]) => grid[reel][row]);
34
+ const allCherry = symbols.every(s => happy_panda_config_1.CHERRY_SYMBOLS.includes(s));
35
+ if (allCherry) {
36
+ count++;
37
+ }
38
+ }
39
+ return count;
40
+ }
41
+ describe('Jackpot Trigger Trace', () => {
42
+ it('should trace BONUS_JACKPOT trigger sources', async () => {
43
+ const rng = createSimulationRng(12345);
44
+ const engine = new happy_panda_engine_1.HappyPandaEngine(rng);
45
+ const targetSpins = 100000;
46
+ const initRequest = {
47
+ command: types_1.CommandType.INIT_SESSION_STATE,
48
+ sessionId: `trace-${Date.now()}`,
49
+ gameDirection: types_1.GameDirection.SINGLE,
50
+ betStake: 1,
51
+ };
52
+ let { state } = await engine.handleCommand(initRequest);
53
+ // Track trigger sources
54
+ let paidSpins = 0;
55
+ let respinCount = 0;
56
+ let paidSpinJackpotTriggers = 0; // Count of trigger events from PAID_SPIN
57
+ let paidSpinCherryLines = 0; // Total cherry triple lines from PAID_SPIN
58
+ let respinJackpotTriggers = 0; // Count of trigger events from RESPIN_CHERRY
59
+ let respinCherryLines = 0; // Total cherry triple lines from RESPIN_CHERRY
60
+ let totalBonusJackpotSpins = 0; // Total BONUS_JACKPOT spins executed
61
+ let totalBonusJackpotWins = 0; // Total wins from BONUS_JACKPOT
62
+ const spinRequest = {
63
+ command: types_1.CommandType.SPIN,
64
+ sessionId: initRequest.sessionId,
65
+ };
66
+ while (paidSpins < targetSpins) {
67
+ const currentSpinType = state.publicState.currentSpinType;
68
+ const isPaidSpin = currentSpinType === happy_panda_config_1.SpinType.PAID_SPIN;
69
+ const isRespin = currentSpinType === happy_panda_config_1.SpinType.RESPIN_CHERRY;
70
+ const isBonusJackpot = currentSpinType === happy_panda_config_1.SpinType.BONUS_JACKPOT;
71
+ if (isPaidSpin) {
72
+ paidSpins++;
73
+ }
74
+ else if (isRespin) {
75
+ respinCount++;
76
+ }
77
+ const spinResult = await engine.handleCommand(spinRequest, state);
78
+ state = spinResult.state;
79
+ const response = spinResult.response;
80
+ // Track BONUS_JACKPOT execution
81
+ if (isBonusJackpot) {
82
+ totalBonusJackpotSpins++;
83
+ totalBonusJackpotWins += response.wins.totalPayout + response.jackpotWon + response.poolJackpotWon;
84
+ }
85
+ // Detect new jackpot triggers (only during PAID_SPIN or RESPIN_CHERRY)
86
+ if ((isPaidSpin || isRespin) && response.bonusTriggered === happy_panda_config_1.SpinType.BONUS_JACKPOT) {
87
+ const grid = response.grid;
88
+ const cherryLines = count3xCherryLines(grid);
89
+ if (isPaidSpin) {
90
+ paidSpinJackpotTriggers++;
91
+ paidSpinCherryLines += cherryLines;
92
+ }
93
+ else if (isRespin) {
94
+ respinJackpotTriggers++;
95
+ respinCherryLines += cherryLines;
96
+ }
97
+ }
98
+ // Progress
99
+ if (paidSpins % 25000 === 0 && isPaidSpin) {
100
+ console.log(` ${(paidSpins / 1000).toFixed(0)}k paid spins: ${respinCount} respins, ` +
101
+ `${paidSpinJackpotTriggers} paid triggers, ${respinJackpotTriggers} respin triggers`);
102
+ }
103
+ }
104
+ console.log('\n========================================');
105
+ console.log('JACKPOT TRIGGER SOURCE ANALYSIS');
106
+ console.log('========================================\n');
107
+ console.log('Spin Counts:');
108
+ console.log(` Paid spins: ${paidSpins.toLocaleString()}`);
109
+ console.log(` Respin cherry: ${respinCount.toLocaleString()}`);
110
+ console.log(` Bonus jackpot spins executed: ${totalBonusJackpotSpins.toLocaleString()}`);
111
+ console.log();
112
+ console.log('Jackpot Triggers from PAID_SPIN:');
113
+ console.log(` Trigger events: ${paidSpinJackpotTriggers}`);
114
+ console.log(` Cherry lines: ${paidSpinCherryLines}`);
115
+ console.log(` Avg lines per trigger: ${paidSpinJackpotTriggers > 0 ? (paidSpinCherryLines / paidSpinJackpotTriggers).toFixed(2) : 'N/A'}`);
116
+ console.log(` Trigger rate: ${((paidSpinJackpotTriggers / paidSpins) * 100).toFixed(4)}%`);
117
+ console.log();
118
+ console.log('Jackpot Triggers from RESPIN_CHERRY:');
119
+ console.log(` Trigger events: ${respinJackpotTriggers}`);
120
+ console.log(` Cherry lines: ${respinCherryLines}`);
121
+ console.log(` Avg lines per trigger: ${respinJackpotTriggers > 0 ? (respinCherryLines / respinJackpotTriggers).toFixed(2) : 'N/A'}`);
122
+ console.log(` Trigger rate from respins: ${((respinJackpotTriggers / respinCount) * 100).toFixed(4)}%`);
123
+ console.log();
124
+ const totalTriggers = paidSpinJackpotTriggers + respinJackpotTriggers;
125
+ const totalLines = paidSpinCherryLines + respinCherryLines;
126
+ console.log('Combined:');
127
+ console.log(` Total trigger events: ${totalTriggers}`);
128
+ console.log(` Total cherry lines: ${totalLines}`);
129
+ console.log(` Bonus spins awarded (should match lines): ${totalLines}`);
130
+ console.log(` Bonus spins executed: ${totalBonusJackpotSpins}`);
131
+ console.log(` Total bonus wins: ${totalBonusJackpotWins.toLocaleString()}`);
132
+ console.log();
133
+ // Expected from C++
134
+ // C++ shows ~936 trigger events per 1M paid spins = 93.6 per 100K
135
+ // Our combined should be close to this
136
+ const cppExpectedTriggers = 93.6;
137
+ const triggerRatio = totalTriggers / cppExpectedTriggers;
138
+ console.log('========================================');
139
+ console.log(`C++ expected triggers (per 100K): ~${cppExpectedTriggers.toFixed(0)}`);
140
+ console.log(`Actual triggers: ${totalTriggers}`);
141
+ console.log(`Ratio: ${triggerRatio.toFixed(2)}x`);
142
+ console.log('========================================\n');
143
+ expect(true).toBe(true);
144
+ }, 300000);
145
+ });
146
+ //# sourceMappingURL=jackpot-trigger-trace.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jackpot-trigger-trace.test.js","sourceRoot":"","sources":["../../src/__tests__/jackpot-trigger-trace.test.ts"],"names":[],"mappings":"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"}