@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.
- package/README.md +732 -0
- package/dist/__tests__/bonus-sequence.test.d.ts +7 -0
- package/dist/__tests__/bonus-sequence.test.d.ts.map +1 -0
- package/dist/__tests__/bonus-sequence.test.js +381 -0
- package/dist/__tests__/bonus-sequence.test.js.map +1 -0
- package/dist/__tests__/cherry-frequency.test.d.ts +8 -0
- package/dist/__tests__/cherry-frequency.test.d.ts.map +1 -0
- package/dist/__tests__/cherry-frequency.test.js +128 -0
- package/dist/__tests__/cherry-frequency.test.js.map +1 -0
- package/dist/__tests__/comprehensive.test.d.ts +16 -0
- package/dist/__tests__/comprehensive.test.d.ts.map +1 -0
- package/dist/__tests__/comprehensive.test.js +491 -0
- package/dist/__tests__/comprehensive.test.js.map +1 -0
- package/dist/__tests__/counter-manager.test.d.ts +7 -0
- package/dist/__tests__/counter-manager.test.d.ts.map +1 -0
- package/dist/__tests__/counter-manager.test.js +317 -0
- package/dist/__tests__/counter-manager.test.js.map +1 -0
- package/dist/__tests__/coverage-boost.test.d.ts +13 -0
- package/dist/__tests__/coverage-boost.test.d.ts.map +1 -0
- package/dist/__tests__/coverage-boost.test.js +606 -0
- package/dist/__tests__/coverage-boost.test.js.map +1 -0
- package/dist/__tests__/cpp-parity.test.d.ts +39 -0
- package/dist/__tests__/cpp-parity.test.d.ts.map +1 -0
- package/dist/__tests__/cpp-parity.test.js +392 -0
- package/dist/__tests__/cpp-parity.test.js.map +1 -0
- package/dist/__tests__/debug-trigger-bonus.test.d.ts +8 -0
- package/dist/__tests__/debug-trigger-bonus.test.d.ts.map +1 -0
- package/dist/__tests__/debug-trigger-bonus.test.js +359 -0
- package/dist/__tests__/debug-trigger-bonus.test.js.map +1 -0
- package/dist/__tests__/fixtures/cpp-parity-vectors.json +457 -0
- package/dist/__tests__/gdd-validation-1000.test.d.ts +14 -0
- package/dist/__tests__/gdd-validation-1000.test.d.ts.map +1 -0
- package/dist/__tests__/gdd-validation-1000.test.js +418 -0
- package/dist/__tests__/gdd-validation-1000.test.js.map +1 -0
- package/dist/__tests__/happy-panda-engine.test.d.ts +7 -0
- package/dist/__tests__/happy-panda-engine.test.d.ts.map +1 -0
- package/dist/__tests__/happy-panda-engine.test.js +414 -0
- package/dist/__tests__/happy-panda-engine.test.js.map +1 -0
- package/dist/__tests__/jackpot-manager.test.d.ts +8 -0
- package/dist/__tests__/jackpot-manager.test.d.ts.map +1 -0
- package/dist/__tests__/jackpot-manager.test.js +313 -0
- package/dist/__tests__/jackpot-manager.test.js.map +1 -0
- package/dist/__tests__/jackpot-trigger-trace.test.d.ts +6 -0
- package/dist/__tests__/jackpot-trigger-trace.test.d.ts.map +1 -0
- package/dist/__tests__/jackpot-trigger-trace.test.js +146 -0
- package/dist/__tests__/jackpot-trigger-trace.test.js.map +1 -0
- package/dist/__tests__/rng-gli19-compliance.test.d.ts +21 -0
- package/dist/__tests__/rng-gli19-compliance.test.d.ts.map +1 -0
- package/dist/__tests__/rng-gli19-compliance.test.js +480 -0
- package/dist/__tests__/rng-gli19-compliance.test.js.map +1 -0
- package/dist/__tests__/rng-seed-security.test.d.ts +19 -0
- package/dist/__tests__/rng-seed-security.test.d.ts.map +1 -0
- package/dist/__tests__/rng-seed-security.test.js +518 -0
- package/dist/__tests__/rng-seed-security.test.js.map +1 -0
- package/dist/__tests__/rng-seed-type.test.d.ts +16 -0
- package/dist/__tests__/rng-seed-type.test.d.ts.map +1 -0
- package/dist/__tests__/rng-seed-type.test.js +285 -0
- package/dist/__tests__/rng-seed-type.test.js.map +1 -0
- package/dist/__tests__/rng-stress-boundary.test.d.ts +15 -0
- package/dist/__tests__/rng-stress-boundary.test.d.ts.map +1 -0
- package/dist/__tests__/rng-stress-boundary.test.js +590 -0
- package/dist/__tests__/rng-stress-boundary.test.js.map +1 -0
- package/dist/__tests__/rtp-1million.test.d.ts +8 -0
- package/dist/__tests__/rtp-1million.test.d.ts.map +1 -0
- package/dist/__tests__/rtp-1million.test.js +156 -0
- package/dist/__tests__/rtp-1million.test.js.map +1 -0
- package/dist/__tests__/rtp-analysis.test.d.ts +8 -0
- package/dist/__tests__/rtp-analysis.test.d.ts.map +1 -0
- package/dist/__tests__/rtp-analysis.test.js +138 -0
- package/dist/__tests__/rtp-analysis.test.js.map +1 -0
- package/dist/__tests__/rtp-diagnostic.test.d.ts +6 -0
- package/dist/__tests__/rtp-diagnostic.test.d.ts.map +1 -0
- package/dist/__tests__/rtp-diagnostic.test.js +141 -0
- package/dist/__tests__/rtp-diagnostic.test.js.map +1 -0
- package/dist/__tests__/rtp-simulation.test.d.ts +8 -0
- package/dist/__tests__/rtp-simulation.test.d.ts.map +1 -0
- package/dist/__tests__/rtp-simulation.test.js +411 -0
- package/dist/__tests__/rtp-simulation.test.js.map +1 -0
- package/dist/__tests__/special-wins.test.d.ts +7 -0
- package/dist/__tests__/special-wins.test.d.ts.map +1 -0
- package/dist/__tests__/special-wins.test.js +179 -0
- package/dist/__tests__/special-wins.test.js.map +1 -0
- package/dist/__tests__/spin-generator.test.d.ts +7 -0
- package/dist/__tests__/spin-generator.test.d.ts.map +1 -0
- package/dist/__tests__/spin-generator.test.js +297 -0
- package/dist/__tests__/spin-generator.test.js.map +1 -0
- package/dist/__tests__/spin-handler.test.d.ts +7 -0
- package/dist/__tests__/spin-handler.test.d.ts.map +1 -0
- package/dist/__tests__/spin-handler.test.js +210 -0
- package/dist/__tests__/spin-handler.test.js.map +1 -0
- package/dist/__tests__/symbol-distribution.test.d.ts +6 -0
- package/dist/__tests__/symbol-distribution.test.d.ts.map +1 -0
- package/dist/__tests__/symbol-distribution.test.js +119 -0
- package/dist/__tests__/symbol-distribution.test.js.map +1 -0
- package/dist/__tests__/test-protocol-10000-spin.test.d.ts +14 -0
- package/dist/__tests__/test-protocol-10000-spin.test.d.ts.map +1 -0
- package/dist/__tests__/test-protocol-10000-spin.test.js +359 -0
- package/dist/__tests__/test-protocol-10000-spin.test.js.map +1 -0
- package/dist/__tests__/weighted-random.test.d.ts +7 -0
- package/dist/__tests__/weighted-random.test.d.ts.map +1 -0
- package/dist/__tests__/weighted-random.test.js +165 -0
- package/dist/__tests__/weighted-random.test.js.map +1 -0
- package/dist/__tests__/win-evaluator.test.d.ts +7 -0
- package/dist/__tests__/win-evaluator.test.d.ts.map +1 -0
- package/dist/__tests__/win-evaluator.test.js +264 -0
- package/dist/__tests__/win-evaluator.test.js.map +1 -0
- package/dist/config/happy-panda.config.d.ts +217 -0
- package/dist/config/happy-panda.config.d.ts.map +1 -0
- package/dist/config/happy-panda.config.js +721 -0
- package/dist/config/happy-panda.config.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +21 -0
- package/dist/config/index.js.map +1 -0
- package/dist/debug/debug-command-definitions.d.ts +38 -0
- package/dist/debug/debug-command-definitions.d.ts.map +1 -0
- package/dist/debug/debug-command-definitions.js +80 -0
- package/dist/debug/debug-command-definitions.js.map +1 -0
- package/dist/domain/debug-trigger-bonus-command.d.ts +17 -0
- package/dist/domain/debug-trigger-bonus-command.d.ts.map +1 -0
- package/dist/domain/debug-trigger-bonus-command.js +3 -0
- package/dist/domain/debug-trigger-bonus-command.js.map +1 -0
- package/dist/domain/index.d.ts +5 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +21 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/types.d.ts +228 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +30 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/engine/happy-panda-engine.d.ts +64 -0
- package/dist/engine/happy-panda-engine.d.ts.map +1 -0
- package/dist/engine/happy-panda-engine.js +324 -0
- package/dist/engine/happy-panda-engine.js.map +1 -0
- package/dist/engine/index.d.ts +5 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +21 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/game-engine.interface.d.ts +19 -0
- package/dist/game-engine.interface.d.ts.map +1 -0
- package/dist/game-engine.interface.js +9 -0
- package/dist/game-engine.interface.js.map +1 -0
- package/dist/happy-panda-v1.game-engine.d.ts +60 -0
- package/dist/happy-panda-v1.game-engine.d.ts.map +1 -0
- package/dist/happy-panda-v1.game-engine.js +524 -0
- package/dist/happy-panda-v1.game-engine.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/logic/handlers/index.d.ts +5 -0
- package/dist/logic/handlers/index.d.ts.map +1 -0
- package/dist/logic/handlers/index.js +21 -0
- package/dist/logic/handlers/index.js.map +1 -0
- package/dist/logic/handlers/spin-handler.d.ts +58 -0
- package/dist/logic/handlers/spin-handler.d.ts.map +1 -0
- package/dist/logic/handlers/spin-handler.js +265 -0
- package/dist/logic/handlers/spin-handler.js.map +1 -0
- package/dist/logic/index.d.ts +6 -0
- package/dist/logic/index.d.ts.map +1 -0
- package/dist/logic/index.js +22 -0
- package/dist/logic/index.js.map +1 -0
- package/dist/logic/services/counter-manager.d.ts +60 -0
- package/dist/logic/services/counter-manager.d.ts.map +1 -0
- package/dist/logic/services/counter-manager.js +268 -0
- package/dist/logic/services/counter-manager.js.map +1 -0
- package/dist/logic/services/index.d.ts +7 -0
- package/dist/logic/services/index.d.ts.map +1 -0
- package/dist/logic/services/index.js +23 -0
- package/dist/logic/services/index.js.map +1 -0
- package/dist/logic/services/jackpot-manager.d.ts +59 -0
- package/dist/logic/services/jackpot-manager.d.ts.map +1 -0
- package/dist/logic/services/jackpot-manager.js +142 -0
- package/dist/logic/services/jackpot-manager.js.map +1 -0
- package/dist/logic/services/win-evaluator.d.ts +51 -0
- package/dist/logic/services/win-evaluator.d.ts.map +1 -0
- package/dist/logic/services/win-evaluator.js +463 -0
- package/dist/logic/services/win-evaluator.js.map +1 -0
- package/dist/rng/dummy-rng-client.d.ts +39 -0
- package/dist/rng/dummy-rng-client.d.ts.map +1 -0
- package/dist/rng/dummy-rng-client.js +77 -0
- package/dist/rng/dummy-rng-client.js.map +1 -0
- package/dist/rng/index.d.ts +10 -0
- package/dist/rng/index.d.ts.map +1 -0
- package/dist/rng/index.js +27 -0
- package/dist/rng/index.js.map +1 -0
- package/dist/rng/rng-client.factory.d.ts +33 -0
- package/dist/rng/rng-client.factory.d.ts.map +1 -0
- package/dist/rng/rng-client.factory.js +57 -0
- package/dist/rng/rng-client.factory.js.map +1 -0
- package/dist/rng/rng-client.interface.d.ts +51 -0
- package/dist/rng/rng-client.interface.d.ts.map +1 -0
- package/dist/rng/rng-client.interface.js +9 -0
- package/dist/rng/rng-client.interface.js.map +1 -0
- package/dist/rng/rng-service.d.ts +93 -0
- package/dist/rng/rng-service.d.ts.map +1 -0
- package/dist/rng/rng-service.js +124 -0
- package/dist/rng/rng-service.js.map +1 -0
- package/dist/rng/spin-generator.d.ts +32 -0
- package/dist/rng/spin-generator.d.ts.map +1 -0
- package/dist/rng/spin-generator.js +338 -0
- package/dist/rng/spin-generator.js.map +1 -0
- package/dist/rng/weighted-random.d.ts +30 -0
- package/dist/rng/weighted-random.d.ts.map +1 -0
- package/dist/rng/weighted-random.js +58 -0
- package/dist/rng/weighted-random.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Counter Manager Service
|
|
4
|
+
*
|
|
5
|
+
* Manages bonus counters and trigger detection.
|
|
6
|
+
* Each bonus type has a counter that decrements on specific events.
|
|
7
|
+
* When a counter reaches 0, the bonus is triggered.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createInitialCounters = createInitialCounters;
|
|
11
|
+
exports.createEmptyPendingBonuses = createEmptyPendingBonuses;
|
|
12
|
+
exports.randomizeBambooTwinsCounter = randomizeBambooTwinsCounter;
|
|
13
|
+
exports.randomizeCameraCounter = randomizeCameraCounter;
|
|
14
|
+
exports.updateCounters = updateCounters;
|
|
15
|
+
exports.getNextBonusType = getNextBonusType;
|
|
16
|
+
exports.consumeBonus = consumeBonus;
|
|
17
|
+
exports.hasPendingBonus = hasPendingBonus;
|
|
18
|
+
const happy_panda_config_1 = require("../../config/happy-panda.config");
|
|
19
|
+
const weighted_random_1 = require("../../rng/weighted-random");
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// COUNTER INITIALIZATION
|
|
22
|
+
// =============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Create initial bonus counters.
|
|
25
|
+
*/
|
|
26
|
+
function createInitialCounters() {
|
|
27
|
+
return {
|
|
28
|
+
bambooTriplets: happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.COUNTER_INIT,
|
|
29
|
+
bambooTwins: happy_panda_config_1.BONUS_BAMBOO_TWINS.COUNTER_INIT[1], // Default to 9, will be randomized
|
|
30
|
+
camera: happy_panda_config_1.BONUS_CAMERA.COUNTER_INIT[1], // Default to 5, will be randomized
|
|
31
|
+
fireworks: happy_panda_config_1.BONUS_FIREWORKS.COUNTER_INIT,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create empty pending bonuses.
|
|
36
|
+
*/
|
|
37
|
+
function createEmptyPendingBonuses() {
|
|
38
|
+
return {
|
|
39
|
+
bambooTriplets: 0,
|
|
40
|
+
bambooTwins: 0,
|
|
41
|
+
camera: 0,
|
|
42
|
+
fireworks: 0,
|
|
43
|
+
centerBamboo: 0,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Randomize Bamboo Twins counter initial value (6 or 9).
|
|
48
|
+
*/
|
|
49
|
+
async function randomizeBambooTwinsCounter(gameDirection, rng) {
|
|
50
|
+
const weights = happy_panda_config_1.BONUS_BAMBOO_TWINS.COUNTER_INIT_WEIGHTS[gameDirection];
|
|
51
|
+
const idx = await (0, weighted_random_1.selectWeightedIndex)(weights, rng);
|
|
52
|
+
return happy_panda_config_1.BONUS_BAMBOO_TWINS.COUNTER_INIT[idx];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Randomize Camera counter initial value (3 or 5).
|
|
56
|
+
*/
|
|
57
|
+
async function randomizeCameraCounter(gameDirection, rng) {
|
|
58
|
+
const weights = happy_panda_config_1.BONUS_CAMERA.COUNTER_INIT_WEIGHTS[gameDirection];
|
|
59
|
+
const idx = await (0, weighted_random_1.selectWeightedIndex)(weights, rng);
|
|
60
|
+
return happy_panda_config_1.BONUS_CAMERA.COUNTER_INIT[idx];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Update counters based on spin results.
|
|
64
|
+
* Only applies during paid_spin and respin_cherry.
|
|
65
|
+
*/
|
|
66
|
+
async function updateCounters(currentCounters, currentPending, lineWins, grid, gameDirection, spinType, totalWin, rng) {
|
|
67
|
+
// Only update counters during paid spins and respins
|
|
68
|
+
if (spinType !== happy_panda_config_1.SpinType.BASE_GAME_SPIN && spinType !== happy_panda_config_1.SpinType.RESPIN_CENTER_BAMBOO) {
|
|
69
|
+
return {
|
|
70
|
+
counters: { ...currentCounters },
|
|
71
|
+
pendingBonuses: { ...currentPending },
|
|
72
|
+
triggeredBambooTriplets: false,
|
|
73
|
+
triggeredBambooTwins: false,
|
|
74
|
+
triggeredCamera: false,
|
|
75
|
+
triggeredFireworks: false,
|
|
76
|
+
triggeredRespin: 0,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const counters = { ...currentCounters };
|
|
80
|
+
const pendingBonuses = { ...currentPending };
|
|
81
|
+
let triggeredBambooTriplets = false;
|
|
82
|
+
let triggeredBambooTwins = false;
|
|
83
|
+
let triggeredCamera = false;
|
|
84
|
+
let triggeredFireworks = false;
|
|
85
|
+
let triggeredRespin = 0;
|
|
86
|
+
// Count specific line win patterns
|
|
87
|
+
let bambooTripleCount = 0; // 3x Bamboo wins (only first 8 lines)
|
|
88
|
+
let bambooPairCount = 0; // 2x Bamboo wins
|
|
89
|
+
let cameraTripleCount = 0; // 3x Camera wins
|
|
90
|
+
let fireworksTripleCount = 0; // 3x Fireworks wins
|
|
91
|
+
for (const win of lineWins) {
|
|
92
|
+
// Only first 8 lines count for Bamboo Triplets, Camera, and Fireworks triggers (per C++ math model)
|
|
93
|
+
const isFirst8Lines = win.lineIndex < 8;
|
|
94
|
+
if (win.symbol === happy_panda_config_1.Symbol.BAMBOO || win.symbol === happy_panda_config_1.Symbol.GOLDEN_BAMBOO) {
|
|
95
|
+
if (win.matchLength === 3 && isFirst8Lines) {
|
|
96
|
+
// C++ BEHAVIOR: During RESPIN_CENTER_BAMBOO, C++ only regenerates corners.
|
|
97
|
+
// Center row (line 1) edges (0,1) and (2,1) are preserved from paid_spin.
|
|
98
|
+
// Since the triggering paid_spin had only 1 bamboo at center, these edges are NOT bamboo.
|
|
99
|
+
// Line 1 can NEVER form 3x bamboo during respin. Other lines may still form 3x bamboo
|
|
100
|
+
// through corner positions which are regenerated.
|
|
101
|
+
const isCenterRow = win.lineIndex === 1;
|
|
102
|
+
if (spinType === happy_panda_config_1.SpinType.RESPIN_CENTER_BAMBOO && isCenterRow) {
|
|
103
|
+
// Skip line 1 - center row edges are preserved non-bamboo in C++
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
bambooTripleCount++;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (win.matchLength === 2) {
|
|
110
|
+
// Bamboo pairs count on ALL lines for Bamboo Twins bonus
|
|
111
|
+
bambooPairCount++;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (win.symbol === happy_panda_config_1.Symbol.CAMERA && win.matchLength === 3 && isFirst8Lines) {
|
|
115
|
+
// Camera bonus only counts first 8 lines
|
|
116
|
+
cameraTripleCount++;
|
|
117
|
+
}
|
|
118
|
+
else if (win.symbol === happy_panda_config_1.Symbol.FIREWORKS_ROCKETS && win.matchLength === 3 && isFirst8Lines) {
|
|
119
|
+
// Fireworks bonus only counts first 8 lines
|
|
120
|
+
fireworksTripleCount++;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// BAMBOO TRIPLETS BONUS: Triggered by 3x Bamboo on first 8 lines
|
|
124
|
+
// C++ BonusJackpotDecision: decrements counter_bonus_jackpot once per qualifying SPIN
|
|
125
|
+
// (not per line). When counter reaches 0, awards 1 bonus occurrence.
|
|
126
|
+
// Each occurrence = BONUS_BAMBOO_TRIPLETS.SPINS (3) free spins.
|
|
127
|
+
if (bambooTripleCount > 0) {
|
|
128
|
+
counters.bambooTriplets--;
|
|
129
|
+
if (counters.bambooTriplets <= 0) {
|
|
130
|
+
pendingBonuses.bambooTriplets += 1; // 1 bonus occurrence per trigger
|
|
131
|
+
triggeredBambooTriplets = true;
|
|
132
|
+
counters.bambooTriplets = happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.COUNTER_INIT;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// BAMBOO TWINS BONUS: Triggered when counter reaches 0
|
|
136
|
+
// Decremented by 2x Bamboo pairs on any line
|
|
137
|
+
// Per C++ math model: process each pair individually, trigger can occur multiple times
|
|
138
|
+
for (let i = 0; i < bambooPairCount; i++) {
|
|
139
|
+
counters.bambooTwins--;
|
|
140
|
+
if (counters.bambooTwins <= 0) {
|
|
141
|
+
pendingBonuses.bambooTwins++;
|
|
142
|
+
triggeredBambooTwins = true;
|
|
143
|
+
// Reset counter with random value before processing next pair
|
|
144
|
+
counters.bambooTwins = await randomizeBambooTwinsCounter(gameDirection, rng);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// CAMERA BONUS: Triggered when counter reaches 0
|
|
148
|
+
// Decremented by 3x Camera wins - process each win individually
|
|
149
|
+
for (let i = 0; i < cameraTripleCount; i++) {
|
|
150
|
+
counters.camera--;
|
|
151
|
+
if (counters.camera <= 0) {
|
|
152
|
+
pendingBonuses.camera++;
|
|
153
|
+
triggeredCamera = true;
|
|
154
|
+
// Reset counter with random value before processing next win
|
|
155
|
+
counters.camera = await randomizeCameraCounter(gameDirection, rng);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// FIREWORKS BONUS: Triggered when counter reaches 0
|
|
159
|
+
// Decremented by 3x Fireworks wins - process each win individually
|
|
160
|
+
for (let i = 0; i < fireworksTripleCount; i++) {
|
|
161
|
+
counters.fireworks--;
|
|
162
|
+
if (counters.fireworks <= 0) {
|
|
163
|
+
pendingBonuses.fireworks++;
|
|
164
|
+
triggeredFireworks = true;
|
|
165
|
+
// Reset counter before processing next win
|
|
166
|
+
counters.fireworks = happy_panda_config_1.BONUS_FIREWORKS.COUNTER_INIT;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// CENTER BAMBOO RESPIN: Only on paid spins, no other wins
|
|
170
|
+
if (spinType === happy_panda_config_1.SpinType.BASE_GAME_SPIN && totalWin === 0) {
|
|
171
|
+
const centerSymbol = grid[1][1];
|
|
172
|
+
if (happy_panda_config_1.BAMBOO_SYMBOLS.includes(centerSymbol)) {
|
|
173
|
+
// Check if it's the ONLY bamboo on the screen
|
|
174
|
+
let bambooCount = 0;
|
|
175
|
+
for (let reel = 0; reel < 3; reel++) {
|
|
176
|
+
for (let row = 0; row < 3; row++) {
|
|
177
|
+
if (happy_panda_config_1.BAMBOO_SYMBOLS.includes(grid[reel][row])) {
|
|
178
|
+
bambooCount++;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (bambooCount === 1) {
|
|
183
|
+
// Award respins: 1 for Bamboo, 2 for Golden Bamboo
|
|
184
|
+
triggeredRespin = centerSymbol === happy_panda_config_1.Symbol.GOLDEN_BAMBOO ? 2 : 1;
|
|
185
|
+
pendingBonuses.centerBamboo += triggeredRespin;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
counters,
|
|
191
|
+
pendingBonuses,
|
|
192
|
+
triggeredBambooTriplets,
|
|
193
|
+
triggeredBambooTwins,
|
|
194
|
+
triggeredCamera,
|
|
195
|
+
triggeredFireworks,
|
|
196
|
+
triggeredRespin,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get the next bonus type to execute (priority order).
|
|
201
|
+
* Returns null if no bonuses pending.
|
|
202
|
+
*/
|
|
203
|
+
function getNextBonusType(pending) {
|
|
204
|
+
// Priority: BambooTriplets > BambooTwins > Camera > Fireworks > CenterBamboo
|
|
205
|
+
if (pending.bambooTriplets > 0)
|
|
206
|
+
return 'bambooTriplets';
|
|
207
|
+
if (pending.bambooTwins > 0)
|
|
208
|
+
return 'bambooTwins';
|
|
209
|
+
if (pending.camera > 0)
|
|
210
|
+
return 'camera';
|
|
211
|
+
if (pending.fireworks > 0)
|
|
212
|
+
return 'fireworks';
|
|
213
|
+
if (pending.centerBamboo > 0)
|
|
214
|
+
return 'centerBamboo';
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Consume one bonus from pending.
|
|
219
|
+
* Returns updated pending and number of spins for that bonus.
|
|
220
|
+
*/
|
|
221
|
+
function consumeBonus(pending, bonusType) {
|
|
222
|
+
const updated = { ...pending };
|
|
223
|
+
let spins = 0;
|
|
224
|
+
switch (bonusType) {
|
|
225
|
+
case 'bambooTriplets':
|
|
226
|
+
if (updated.bambooTriplets > 0) {
|
|
227
|
+
updated.bambooTriplets--;
|
|
228
|
+
spins = happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.SPINS;
|
|
229
|
+
}
|
|
230
|
+
break;
|
|
231
|
+
case 'bambooTwins':
|
|
232
|
+
if (updated.bambooTwins > 0) {
|
|
233
|
+
updated.bambooTwins--;
|
|
234
|
+
spins = happy_panda_config_1.BONUS_BAMBOO_TWINS.SPINS;
|
|
235
|
+
}
|
|
236
|
+
break;
|
|
237
|
+
case 'camera':
|
|
238
|
+
if (updated.camera > 0) {
|
|
239
|
+
updated.camera--;
|
|
240
|
+
spins = happy_panda_config_1.BONUS_CAMERA.SPINS;
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
case 'fireworks':
|
|
244
|
+
if (updated.fireworks > 0) {
|
|
245
|
+
updated.fireworks--;
|
|
246
|
+
spins = happy_panda_config_1.BONUS_FIREWORKS.SPINS;
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
case 'centerBamboo':
|
|
250
|
+
if (updated.centerBamboo > 0) {
|
|
251
|
+
spins = updated.centerBamboo;
|
|
252
|
+
updated.centerBamboo = 0;
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
return { pending: updated, spins };
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Check if any bonus is pending.
|
|
260
|
+
*/
|
|
261
|
+
function hasPendingBonus(pending) {
|
|
262
|
+
return (pending.bambooTriplets > 0 ||
|
|
263
|
+
pending.bambooTwins > 0 ||
|
|
264
|
+
pending.camera > 0 ||
|
|
265
|
+
pending.fireworks > 0 ||
|
|
266
|
+
pending.centerBamboo > 0);
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=counter-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counter-manager.js","sourceRoot":"","sources":["../../../src/logic/services/counter-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/logic/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
* Logic services exports
|
|
19
|
+
*/
|
|
20
|
+
__exportStar(require("./win-evaluator"), exports);
|
|
21
|
+
__exportStar(require("./counter-manager"), exports);
|
|
22
|
+
__exportStar(require("./jackpot-manager"), exports);
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/logic/services/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,kDAAgC;AAChC,oDAAkC;AAClC,oDAAkC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jackpot Manager Service
|
|
3
|
+
*
|
|
4
|
+
* Manages progressive jackpot and pool jackpot values.
|
|
5
|
+
*
|
|
6
|
+
* Progressive Jackpot (Bonus Jackpot):
|
|
7
|
+
* - Starts at 100 x bet_game
|
|
8
|
+
* - On losing paid spins: 3/13 chance to increase by 1-2 x bet_stake
|
|
9
|
+
* - Max: 1000 x bet_game
|
|
10
|
+
* - Paid when Jackpot Bonus triggered
|
|
11
|
+
*
|
|
12
|
+
* Pool Jackpot:
|
|
13
|
+
* - Starts at 0
|
|
14
|
+
* - Increases when Red Panda/Golden Panda in center with no wins
|
|
15
|
+
* - Max: 250 x bet_game
|
|
16
|
+
* - Paid when Camera Bonus triggered
|
|
17
|
+
*/
|
|
18
|
+
import { SpinType } from '../../config/happy-panda.config';
|
|
19
|
+
import { Grid, GameDirection, JackpotState, RngProvider } from '../../domain/types';
|
|
20
|
+
/**
|
|
21
|
+
* Create initial jackpot state.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createInitialJackpots(betGame: number): JackpotState;
|
|
24
|
+
/**
|
|
25
|
+
* Update progressive jackpot value on losing paid spin.
|
|
26
|
+
* 3/13 probability to increase.
|
|
27
|
+
*/
|
|
28
|
+
export declare function updateProgressiveJackpot(currentValue: number, gameDirection: GameDirection, betGame: number, betStake: number, spinType: SpinType, totalWin: number, rng: RngProvider): Promise<number>;
|
|
29
|
+
/**
|
|
30
|
+
* Pay out progressive jackpot and reset.
|
|
31
|
+
*/
|
|
32
|
+
export declare function payProgressiveJackpot(currentValue: number, betGame: number): {
|
|
33
|
+
payout: number;
|
|
34
|
+
newValue: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Update pool jackpot value.
|
|
38
|
+
* Increases when Red Panda/Golden Panda in center position with no wins.
|
|
39
|
+
* IMPORTANT: Must be the ONLY Panda on the entire screen (per C++ math model).
|
|
40
|
+
*/
|
|
41
|
+
export declare function updatePoolJackpot(currentValue: number, grid: Grid, gameDirection: GameDirection, betGame: number, betStake: number, spinType: SpinType, totalWin: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* Pay out pool jackpot and reset.
|
|
44
|
+
*/
|
|
45
|
+
export declare function payPoolJackpot(currentValue: number, betGame: number): {
|
|
46
|
+
payout: number;
|
|
47
|
+
newValue: number;
|
|
48
|
+
};
|
|
49
|
+
/** Result of jackpot updates */
|
|
50
|
+
export interface JackpotUpdateResult {
|
|
51
|
+
jackpots: JackpotState;
|
|
52
|
+
progressiveJackpotIncreased: boolean;
|
|
53
|
+
poolJackpotIncreased: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Update both jackpot values after a spin.
|
|
57
|
+
*/
|
|
58
|
+
export declare function updateJackpots(currentJackpots: JackpotState, grid: Grid, gameDirection: GameDirection, betGame: number, betStake: number, spinType: SpinType, totalWin: number, rng: RngProvider): Promise<JackpotUpdateResult>;
|
|
59
|
+
//# sourceMappingURL=jackpot-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jackpot-manager.d.ts","sourceRoot":"","sources":["../../../src/logic/services/jackpot-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAEL,QAAQ,EAIT,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOpF;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAKnE;AAMD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAItC;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAsCR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAItC;AAMD,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,YAAY,CAAC;IACvB,2BAA2B,EAAE,OAAO,CAAC;IACrC,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,eAAe,EAAE,YAAY,EAC7B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,mBAAmB,CAAC,CAgC9B"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Jackpot Manager Service
|
|
4
|
+
*
|
|
5
|
+
* Manages progressive jackpot and pool jackpot values.
|
|
6
|
+
*
|
|
7
|
+
* Progressive Jackpot (Bonus Jackpot):
|
|
8
|
+
* - Starts at 100 x bet_game
|
|
9
|
+
* - On losing paid spins: 3/13 chance to increase by 1-2 x bet_stake
|
|
10
|
+
* - Max: 1000 x bet_game
|
|
11
|
+
* - Paid when Jackpot Bonus triggered
|
|
12
|
+
*
|
|
13
|
+
* Pool Jackpot:
|
|
14
|
+
* - Starts at 0
|
|
15
|
+
* - Increases when Red Panda/Golden Panda in center with no wins
|
|
16
|
+
* - Max: 250 x bet_game
|
|
17
|
+
* - Paid when Camera Bonus triggered
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.createInitialJackpots = createInitialJackpots;
|
|
21
|
+
exports.updateProgressiveJackpot = updateProgressiveJackpot;
|
|
22
|
+
exports.payProgressiveJackpot = payProgressiveJackpot;
|
|
23
|
+
exports.updatePoolJackpot = updatePoolJackpot;
|
|
24
|
+
exports.payPoolJackpot = payPoolJackpot;
|
|
25
|
+
exports.updateJackpots = updateJackpots;
|
|
26
|
+
const happy_panda_config_1 = require("../../config/happy-panda.config");
|
|
27
|
+
const weighted_random_1 = require("../../rng/weighted-random");
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// JACKPOT INITIALIZATION
|
|
30
|
+
// =============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* Create initial jackpot state.
|
|
33
|
+
*/
|
|
34
|
+
function createInitialJackpots(betGame) {
|
|
35
|
+
return {
|
|
36
|
+
bonusJackpotValue: happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.INIT * betGame,
|
|
37
|
+
poolJackpotValue: happy_panda_config_1.POOL_JACKPOT.INIT * betGame,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// =============================================================================
|
|
41
|
+
// PROGRESSIVE JACKPOT
|
|
42
|
+
// =============================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Update progressive jackpot value on losing paid spin.
|
|
45
|
+
* 3/13 probability to increase.
|
|
46
|
+
*/
|
|
47
|
+
async function updateProgressiveJackpot(currentValue, gameDirection, betGame, betStake, spinType, totalWin, rng) {
|
|
48
|
+
// Only on paid spins with no win
|
|
49
|
+
if (spinType !== happy_panda_config_1.SpinType.BASE_GAME_SPIN || totalWin > 0) {
|
|
50
|
+
return currentValue;
|
|
51
|
+
}
|
|
52
|
+
// Check if should increase (3/13 probability)
|
|
53
|
+
const [yesWeight, noWeight] = happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.INCREMENT_WEIGHTS[gameDirection];
|
|
54
|
+
const shouldIncrease = await (0, weighted_random_1.weightedBoolean)(yesWeight, noWeight, rng);
|
|
55
|
+
if (!shouldIncrease) {
|
|
56
|
+
return currentValue;
|
|
57
|
+
}
|
|
58
|
+
// Increase by increment value
|
|
59
|
+
const increment = happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.INCREMENT_VALUE[gameDirection] * betStake;
|
|
60
|
+
let newValue = currentValue + increment;
|
|
61
|
+
// Cap at maximum
|
|
62
|
+
const maxValue = happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.MAX * betGame;
|
|
63
|
+
if (newValue > maxValue) {
|
|
64
|
+
newValue = maxValue;
|
|
65
|
+
}
|
|
66
|
+
return newValue;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Pay out progressive jackpot and reset.
|
|
70
|
+
*/
|
|
71
|
+
function payProgressiveJackpot(currentValue, betGame) {
|
|
72
|
+
const payout = currentValue;
|
|
73
|
+
const newValue = happy_panda_config_1.BONUS_BAMBOO_TRIPLETS.INIT * betGame;
|
|
74
|
+
return { payout, newValue };
|
|
75
|
+
}
|
|
76
|
+
// =============================================================================
|
|
77
|
+
// POOL JACKPOT
|
|
78
|
+
// =============================================================================
|
|
79
|
+
/**
|
|
80
|
+
* Update pool jackpot value.
|
|
81
|
+
* Increases when Red Panda/Golden Panda in center position with no wins.
|
|
82
|
+
* IMPORTANT: Must be the ONLY Panda on the entire screen (per C++ math model).
|
|
83
|
+
*/
|
|
84
|
+
function updatePoolJackpot(currentValue, grid, gameDirection, betGame, betStake, spinType, totalWin) {
|
|
85
|
+
// Only on paid spins with no win
|
|
86
|
+
if (spinType !== happy_panda_config_1.SpinType.BASE_GAME_SPIN || totalWin > 0) {
|
|
87
|
+
return currentValue;
|
|
88
|
+
}
|
|
89
|
+
// Check center position (1,1)
|
|
90
|
+
const centerSymbol = grid[1][1];
|
|
91
|
+
if (!happy_panda_config_1.PANDA_SYMBOLS.includes(centerSymbol)) {
|
|
92
|
+
return currentValue;
|
|
93
|
+
}
|
|
94
|
+
// Count ALL Pandas on the screen - must be exactly 1
|
|
95
|
+
let pandaCount = 0;
|
|
96
|
+
for (let reel = 0; reel < 3; reel++) {
|
|
97
|
+
for (let row = 0; row < 3; row++) {
|
|
98
|
+
if (happy_panda_config_1.PANDA_SYMBOLS.includes(grid[reel][row])) {
|
|
99
|
+
pandaCount++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (pandaCount !== 1) {
|
|
104
|
+
return currentValue; // Only single Panda can trigger pool increment
|
|
105
|
+
}
|
|
106
|
+
// Determine increment based on symbol
|
|
107
|
+
const incrementIdx = centerSymbol === happy_panda_config_1.Symbol.GOLDEN_PANDA ? 0 : 1;
|
|
108
|
+
const increment = happy_panda_config_1.POOL_JACKPOT.INCREMENT[gameDirection][incrementIdx] * betStake;
|
|
109
|
+
let newValue = currentValue + increment;
|
|
110
|
+
// Cap at maximum
|
|
111
|
+
const maxValue = happy_panda_config_1.POOL_JACKPOT.MAX * betGame;
|
|
112
|
+
if (newValue > maxValue) {
|
|
113
|
+
newValue = maxValue;
|
|
114
|
+
}
|
|
115
|
+
return newValue;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Pay out pool jackpot and reset.
|
|
119
|
+
*/
|
|
120
|
+
function payPoolJackpot(currentValue, betGame) {
|
|
121
|
+
const payout = currentValue;
|
|
122
|
+
const newValue = happy_panda_config_1.POOL_JACKPOT.INIT * betGame;
|
|
123
|
+
return { payout, newValue };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Update both jackpot values after a spin.
|
|
127
|
+
*/
|
|
128
|
+
async function updateJackpots(currentJackpots, grid, gameDirection, betGame, betStake, spinType, totalWin, rng) {
|
|
129
|
+
const oldProgressiveValue = currentJackpots.bonusJackpotValue;
|
|
130
|
+
const oldPoolValue = currentJackpots.poolJackpotValue;
|
|
131
|
+
const newProgressiveValue = await updateProgressiveJackpot(oldProgressiveValue, gameDirection, betGame, betStake, spinType, totalWin, rng);
|
|
132
|
+
const newPoolValue = updatePoolJackpot(oldPoolValue, grid, gameDirection, betGame, betStake, spinType, totalWin);
|
|
133
|
+
return {
|
|
134
|
+
jackpots: {
|
|
135
|
+
bonusJackpotValue: newProgressiveValue,
|
|
136
|
+
poolJackpotValue: newPoolValue,
|
|
137
|
+
},
|
|
138
|
+
progressiveJackpotIncreased: newProgressiveValue > oldProgressiveValue,
|
|
139
|
+
poolJackpotIncreased: newPoolValue > oldPoolValue,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=jackpot-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jackpot-manager.js","sourceRoot":"","sources":["../../../src/logic/services/jackpot-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Win Evaluator Service
|
|
3
|
+
*
|
|
4
|
+
* Evaluates wins on a 3x3 grid. Per C++ math model (lines 2731-2735):
|
|
5
|
+
* 1. Wall wins (3x3 screen fills)
|
|
6
|
+
* 2. Scatter wins (Red Panda/Golden Panda) - wall wins suppress scatter wins
|
|
7
|
+
* 3. Line wins - always evaluated independently (NEVER suppressed)
|
|
8
|
+
* 4. Special wins (bonus-specific)
|
|
9
|
+
*
|
|
10
|
+
* Wall and line wins are both added to player_current_win independently.
|
|
11
|
+
*/
|
|
12
|
+
import { SpinType } from '../../config/happy-panda.config';
|
|
13
|
+
import { Grid, GameDirection, LineWin, WallWin, ScatterWin, SpecialWin, SpinWinResult } from '../../domain/types';
|
|
14
|
+
/**
|
|
15
|
+
* Evaluate wall (3x3) wins.
|
|
16
|
+
* Wall wins require all 9 positions to be the same symbol or valid mix.
|
|
17
|
+
*/
|
|
18
|
+
export declare function evaluateWallWin(grid: Grid, betGame: number): WallWin | null;
|
|
19
|
+
/**
|
|
20
|
+
* Evaluate Red Panda/Golden Panda scatter wins.
|
|
21
|
+
* C++ can award TWO scatter wins:
|
|
22
|
+
* 1. Golden Panda only scatter (if GOLDEN_PANDA >= 2, doubled if no regular Pandas)
|
|
23
|
+
* 2. Total count scatter (if total >= 2 AND at least 1 regular Red Panda)
|
|
24
|
+
* Plus +bet_game bonus if exactly 1 Golden Panda
|
|
25
|
+
*/
|
|
26
|
+
export declare function evaluateScatterWins(grid: Grid, betGame: number): ScatterWin[];
|
|
27
|
+
/**
|
|
28
|
+
* Evaluate all line wins.
|
|
29
|
+
*/
|
|
30
|
+
export declare function evaluateLineWins(grid: Grid, gameDirection: GameDirection, betStake: number): LineWin[];
|
|
31
|
+
/**
|
|
32
|
+
* Evaluate panda piece line wins (Bamboo Triplets Bonus).
|
|
33
|
+
* Dancing Panda pieces on lines pay special multiplier.
|
|
34
|
+
*/
|
|
35
|
+
export declare function evaluatePandaPieceWins(grid: Grid, gameDirection: GameDirection, betStake: number): SpecialWin[];
|
|
36
|
+
/**
|
|
37
|
+
* Evaluate camera scatter wins (Camera Bonus).
|
|
38
|
+
* Each camera pays as scatter during bonus.
|
|
39
|
+
*/
|
|
40
|
+
export declare function evaluateCameraScatterWins(grid: Grid, gameDirection: GameDirection, betStake: number): SpecialWin | null;
|
|
41
|
+
/**
|
|
42
|
+
* Evaluate hat scatter wins (Fireworks Bonus).
|
|
43
|
+
* Each hat pays as scatter during bonus.
|
|
44
|
+
*/
|
|
45
|
+
export declare function evaluateHatScatterWins(grid: Grid, gameDirection: GameDirection, betStake: number): SpecialWin | null;
|
|
46
|
+
/**
|
|
47
|
+
* Evaluate all wins for a spin.
|
|
48
|
+
* Implements correct priority: Wall > Scatter > Lines
|
|
49
|
+
*/
|
|
50
|
+
export declare function evaluateSpin(grid: Grid, gameDirection: GameDirection, betStake: number, betGame: number, spinType: SpinType): SpinWinResult;
|
|
51
|
+
//# sourceMappingURL=win-evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"win-evaluator.d.ts","sourceRoot":"","sources":["../../../src/logic/services/win-evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,QAAQ,EAiBT,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,IAAI,EACJ,aAAa,EAEb,OAAO,EACP,OAAO,EACP,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,oBAAoB,CAAC;AAqE5B;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,GACd,OAAO,GAAG,IAAI,CAmEhB;AAMD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,GACd,UAAU,EAAE,CAsDd;AAmGD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,OAAO,EAAE,CAYX;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,EAAE,CAmCd;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,IAAI,CAcnB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,IAAI,CAcnB;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GACjB,aAAa,CAgFf"}
|