@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,463 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Win Evaluator Service
|
|
4
|
+
*
|
|
5
|
+
* Evaluates wins on a 3x3 grid. Per C++ math model (lines 2731-2735):
|
|
6
|
+
* 1. Wall wins (3x3 screen fills)
|
|
7
|
+
* 2. Scatter wins (Red Panda/Golden Panda) - wall wins suppress scatter wins
|
|
8
|
+
* 3. Line wins - always evaluated independently (NEVER suppressed)
|
|
9
|
+
* 4. Special wins (bonus-specific)
|
|
10
|
+
*
|
|
11
|
+
* Wall and line wins are both added to player_current_win independently.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.evaluateWallWin = evaluateWallWin;
|
|
15
|
+
exports.evaluateScatterWins = evaluateScatterWins;
|
|
16
|
+
exports.evaluateLineWins = evaluateLineWins;
|
|
17
|
+
exports.evaluatePandaPieceWins = evaluatePandaPieceWins;
|
|
18
|
+
exports.evaluateCameraScatterWins = evaluateCameraScatterWins;
|
|
19
|
+
exports.evaluateHatScatterWins = evaluateHatScatterWins;
|
|
20
|
+
exports.evaluateSpin = evaluateSpin;
|
|
21
|
+
const happy_panda_config_1 = require("../../config/happy-panda.config");
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// HELPER FUNCTIONS
|
|
24
|
+
// =============================================================================
|
|
25
|
+
/** Get symbol at position */
|
|
26
|
+
function getSymbol(grid, reel, row) {
|
|
27
|
+
return grid[reel][row];
|
|
28
|
+
}
|
|
29
|
+
/** Get all positions where a symbol appears */
|
|
30
|
+
function findSymbolPositions(grid, symbol) {
|
|
31
|
+
const positions = [];
|
|
32
|
+
for (let reel = 0; reel < happy_panda_config_1.GRID.REELS; reel++) {
|
|
33
|
+
for (let row = 0; row < happy_panda_config_1.GRID.ROWS; row++) {
|
|
34
|
+
if (grid[reel][row] === symbol) {
|
|
35
|
+
positions.push({ reel, row });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return positions;
|
|
40
|
+
}
|
|
41
|
+
/** Count symbol occurrences */
|
|
42
|
+
function countSymbol(grid, symbol) {
|
|
43
|
+
return findSymbolPositions(grid, symbol).length;
|
|
44
|
+
}
|
|
45
|
+
/** Count symbols in a group */
|
|
46
|
+
function countSymbolGroup(grid, symbols) {
|
|
47
|
+
let count = 0;
|
|
48
|
+
for (let reel = 0; reel < happy_panda_config_1.GRID.REELS; reel++) {
|
|
49
|
+
for (let row = 0; row < happy_panda_config_1.GRID.ROWS; row++) {
|
|
50
|
+
if (symbols.includes(grid[reel][row])) {
|
|
51
|
+
count++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return count;
|
|
56
|
+
}
|
|
57
|
+
/** Get all 9 positions */
|
|
58
|
+
function getAllPositions() {
|
|
59
|
+
const positions = [];
|
|
60
|
+
for (let reel = 0; reel < happy_panda_config_1.GRID.REELS; reel++) {
|
|
61
|
+
for (let row = 0; row < happy_panda_config_1.GRID.ROWS; row++) {
|
|
62
|
+
positions.push({ reel, row });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return positions;
|
|
66
|
+
}
|
|
67
|
+
// =============================================================================
|
|
68
|
+
// WALL WIN EVALUATION
|
|
69
|
+
// =============================================================================
|
|
70
|
+
/** Wall win symbols in order of evaluation */
|
|
71
|
+
const WALL_SYMBOLS = [
|
|
72
|
+
happy_panda_config_1.Symbol.SLOT_MACHINE,
|
|
73
|
+
happy_panda_config_1.Symbol.CITY,
|
|
74
|
+
happy_panda_config_1.Symbol.FIREWORKS_ROCKETS,
|
|
75
|
+
happy_panda_config_1.Symbol.BACKPACK,
|
|
76
|
+
happy_panda_config_1.Symbol.CAMERA,
|
|
77
|
+
happy_panda_config_1.Symbol.FOOD_BOWL,
|
|
78
|
+
happy_panda_config_1.Symbol.CUP,
|
|
79
|
+
happy_panda_config_1.Symbol.BAMBOO, // Includes Golden Bamboo in the mix
|
|
80
|
+
];
|
|
81
|
+
/**
|
|
82
|
+
* Evaluate wall (3x3) wins.
|
|
83
|
+
* Wall wins require all 9 positions to be the same symbol or valid mix.
|
|
84
|
+
*/
|
|
85
|
+
function evaluateWallWin(grid, betGame) {
|
|
86
|
+
// Check single-symbol walls
|
|
87
|
+
for (let i = 0; i < WALL_SYMBOLS.length; i++) {
|
|
88
|
+
const symbol = WALL_SYMBOLS[i];
|
|
89
|
+
let count;
|
|
90
|
+
if (symbol === happy_panda_config_1.Symbol.BAMBOO) {
|
|
91
|
+
// Bamboo wall includes Golden Bamboo
|
|
92
|
+
count = countSymbolGroup(grid, happy_panda_config_1.BAMBOO_SYMBOLS);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
count = countSymbol(grid, symbol);
|
|
96
|
+
}
|
|
97
|
+
if (count === 9) {
|
|
98
|
+
// Wall type index mapping to WALL_MULTIPLIERS
|
|
99
|
+
let wallTypeIdx;
|
|
100
|
+
switch (symbol) {
|
|
101
|
+
case happy_panda_config_1.Symbol.SLOT_MACHINE:
|
|
102
|
+
wallTypeIdx = 0;
|
|
103
|
+
break;
|
|
104
|
+
case happy_panda_config_1.Symbol.CITY:
|
|
105
|
+
wallTypeIdx = 1;
|
|
106
|
+
break;
|
|
107
|
+
case happy_panda_config_1.Symbol.FIREWORKS_ROCKETS:
|
|
108
|
+
wallTypeIdx = 2;
|
|
109
|
+
break;
|
|
110
|
+
case happy_panda_config_1.Symbol.BACKPACK:
|
|
111
|
+
wallTypeIdx = 3;
|
|
112
|
+
break;
|
|
113
|
+
case happy_panda_config_1.Symbol.CAMERA:
|
|
114
|
+
wallTypeIdx = 4;
|
|
115
|
+
break;
|
|
116
|
+
case happy_panda_config_1.Symbol.FOOD_BOWL:
|
|
117
|
+
wallTypeIdx = 5;
|
|
118
|
+
break;
|
|
119
|
+
case happy_panda_config_1.Symbol.CUP:
|
|
120
|
+
wallTypeIdx = 6;
|
|
121
|
+
break;
|
|
122
|
+
case happy_panda_config_1.Symbol.BAMBOO:
|
|
123
|
+
wallTypeIdx = 7;
|
|
124
|
+
break;
|
|
125
|
+
default: continue;
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
wallType: happy_panda_config_1.ScreenWinType.SCREEN_SLOT_MACHINE + wallTypeIdx,
|
|
129
|
+
payout: happy_panda_config_1.WALL_MULTIPLIERS[wallTypeIdx] * betGame,
|
|
130
|
+
positions: getAllPositions(),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Check Bar Mix wall (mix of Slot Machine, City, Fireworks, Hat per C++ math model)
|
|
135
|
+
const barCount = countSymbolGroup(grid, happy_panda_config_1.BAR_MIX_SYMBOLS);
|
|
136
|
+
if (barCount === 9) {
|
|
137
|
+
return {
|
|
138
|
+
wallType: happy_panda_config_1.ScreenWinType.SCREEN_BAR_MIX,
|
|
139
|
+
payout: happy_panda_config_1.WALL_MULTIPLIERS[8] * betGame, // Bar Mix = 50x
|
|
140
|
+
positions: getAllPositions(),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Check Fruit Mix wall (Backpack, Food Bowl, Cup, Bamboo, Golden Bamboo)
|
|
144
|
+
const fruitCount = countSymbolGroup(grid, happy_panda_config_1.FRUIT_STYLE_SYMBOLS);
|
|
145
|
+
if (fruitCount === 9) {
|
|
146
|
+
return {
|
|
147
|
+
wallType: happy_panda_config_1.ScreenWinType.SCREEN_FRUIT_MIX,
|
|
148
|
+
payout: happy_panda_config_1.WALL_MULTIPLIERS[9] * betGame, // Fruit Mix = 15x
|
|
149
|
+
positions: getAllPositions(),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// Check Badge Mix wall (bonus only)
|
|
153
|
+
const badgeCount = countSymbolGroup(grid, happy_panda_config_1.BADGE_SYMBOLS);
|
|
154
|
+
if (badgeCount === 9) {
|
|
155
|
+
return {
|
|
156
|
+
wallType: happy_panda_config_1.ScreenWinType.SCREEN_BADGE_MIX,
|
|
157
|
+
payout: happy_panda_config_1.WALL_MULTIPLIERS[10] * betGame, // Badge Mix = 50x
|
|
158
|
+
positions: getAllPositions(),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
// =============================================================================
|
|
164
|
+
// SCATTER WIN EVALUATION
|
|
165
|
+
// =============================================================================
|
|
166
|
+
/**
|
|
167
|
+
* Evaluate Red Panda/Golden Panda scatter wins.
|
|
168
|
+
* C++ can award TWO scatter wins:
|
|
169
|
+
* 1. Golden Panda only scatter (if GOLDEN_PANDA >= 2, doubled if no regular Pandas)
|
|
170
|
+
* 2. Total count scatter (if total >= 2 AND at least 1 regular Red Panda)
|
|
171
|
+
* Plus +bet_game bonus if exactly 1 Golden Panda
|
|
172
|
+
*/
|
|
173
|
+
function evaluateScatterWins(grid, betGame) {
|
|
174
|
+
const wins = [];
|
|
175
|
+
const goldenPandaCount = countSymbol(grid, happy_panda_config_1.Symbol.GOLDEN_PANDA);
|
|
176
|
+
const redPandaCount = countSymbol(grid, happy_panda_config_1.Symbol.RED_PANDA);
|
|
177
|
+
const totalCount = goldenPandaCount + redPandaCount;
|
|
178
|
+
const goldenPandaPositions = findSymbolPositions(grid, happy_panda_config_1.Symbol.GOLDEN_PANDA);
|
|
179
|
+
const redPandaPositions = findSymbolPositions(grid, happy_panda_config_1.Symbol.RED_PANDA);
|
|
180
|
+
const allPositions = [...goldenPandaPositions, ...redPandaPositions];
|
|
181
|
+
// First check: Golden Panda only scatter (C++ lines 119-136)
|
|
182
|
+
if (goldenPandaCount >= happy_panda_config_1.PANDA_MIN_COUNT) {
|
|
183
|
+
const multiplierIdx = 9 - goldenPandaCount;
|
|
184
|
+
if (multiplierIdx >= 0 && multiplierIdx < happy_panda_config_1.PANDA_SCATTER_MULTIPLIERS.length) {
|
|
185
|
+
let payout = happy_panda_config_1.PANDA_SCATTER_MULTIPLIERS[multiplierIdx] * betGame;
|
|
186
|
+
// Double if NO regular Red Pandas (C++ lines 130-133)
|
|
187
|
+
if (redPandaCount === 0) {
|
|
188
|
+
payout *= happy_panda_config_1.GOLDEN_PANDA_MULTIPLIER;
|
|
189
|
+
}
|
|
190
|
+
wins.push({
|
|
191
|
+
symbol: happy_panda_config_1.Symbol.GOLDEN_PANDA,
|
|
192
|
+
count: goldenPandaCount,
|
|
193
|
+
payout,
|
|
194
|
+
positions: goldenPandaPositions,
|
|
195
|
+
isSuperSevenOnly: redPandaCount === 0, // Keep field name for compatibility
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Second check: Total count scatter (C++ lines 139-157)
|
|
200
|
+
// Only if there's at least 1 regular Red Panda
|
|
201
|
+
if (totalCount >= happy_panda_config_1.PANDA_MIN_COUNT && redPandaCount > 0) {
|
|
202
|
+
const multiplierIdx = 9 - totalCount;
|
|
203
|
+
if (multiplierIdx >= 0 && multiplierIdx < happy_panda_config_1.PANDA_SCATTER_MULTIPLIERS.length) {
|
|
204
|
+
let payout = happy_panda_config_1.PANDA_SCATTER_MULTIPLIERS[multiplierIdx] * betGame;
|
|
205
|
+
// Add bet_game bonus if exactly 1 Golden Panda (C++ lines 151-154)
|
|
206
|
+
if (goldenPandaCount === 1) {
|
|
207
|
+
payout += betGame;
|
|
208
|
+
}
|
|
209
|
+
wins.push({
|
|
210
|
+
symbol: happy_panda_config_1.Symbol.RED_PANDA,
|
|
211
|
+
count: totalCount,
|
|
212
|
+
payout,
|
|
213
|
+
positions: allPositions,
|
|
214
|
+
isSuperSevenOnly: false,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return wins;
|
|
219
|
+
}
|
|
220
|
+
// =============================================================================
|
|
221
|
+
// LINE WIN EVALUATION
|
|
222
|
+
// =============================================================================
|
|
223
|
+
/**
|
|
224
|
+
* Check if symbols on a line match for a win.
|
|
225
|
+
* Returns match info or null if no match.
|
|
226
|
+
*/
|
|
227
|
+
function evaluateLine(grid, lineIndex, betStake) {
|
|
228
|
+
const lineShape = happy_panda_config_1.LINE_SHAPES[lineIndex];
|
|
229
|
+
const positions = lineShape.map(([reel, row]) => ({ reel, row }));
|
|
230
|
+
const symbols = positions.map(p => getSymbol(grid, p.reel, p.row));
|
|
231
|
+
// Check for 3-of-a-kind first
|
|
232
|
+
const firstSymbol = symbols[0];
|
|
233
|
+
// Bamboo special case: pays for 1, 2, or 3
|
|
234
|
+
if (happy_panda_config_1.BAMBOO_SYMBOLS.includes(firstSymbol)) {
|
|
235
|
+
return evaluateBambooLine(symbols, positions, lineIndex, betStake);
|
|
236
|
+
}
|
|
237
|
+
// Standard 3-of-a-kind
|
|
238
|
+
const allSame = symbols.every(s => s === firstSymbol);
|
|
239
|
+
if (allSame && firstSymbol >= happy_panda_config_1.Symbol.GOLDEN_PANDA && firstSymbol <= happy_panda_config_1.Symbol.CUP) {
|
|
240
|
+
const multiplier = happy_panda_config_1.LINE_MULTIPLIERS[firstSymbol][2]; // x3 column
|
|
241
|
+
if (multiplier > 0) {
|
|
242
|
+
return {
|
|
243
|
+
lineIndex,
|
|
244
|
+
symbol: firstSymbol,
|
|
245
|
+
matchLength: 3,
|
|
246
|
+
payout: multiplier * betStake,
|
|
247
|
+
positions,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Check Bar Mix (Slot Machine, City, Fireworks, Hat per C++ math model)
|
|
252
|
+
const allBars = symbols.every(s => happy_panda_config_1.BAR_MIX_SYMBOLS.includes(s));
|
|
253
|
+
if (allBars) {
|
|
254
|
+
const multiplier = happy_panda_config_1.LINE_MULTIPLIERS[10][2]; // Bar Mix x3 = 10
|
|
255
|
+
return {
|
|
256
|
+
lineIndex,
|
|
257
|
+
symbol: happy_panda_config_1.Symbol.BAR_MIX, // Use BAR_MIX to distinguish from pure Fireworks (for bonus triggers)
|
|
258
|
+
matchLength: 3,
|
|
259
|
+
payout: multiplier * betStake,
|
|
260
|
+
positions,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Evaluate bamboo line win.
|
|
267
|
+
* Bamboo pays for 1, 2, or 3 matches (including Golden Bamboo mix).
|
|
268
|
+
*/
|
|
269
|
+
function evaluateBambooLine(symbols, positions, lineIndex, betStake) {
|
|
270
|
+
let matchLength = 0;
|
|
271
|
+
const winPositions = [];
|
|
272
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
273
|
+
if (happy_panda_config_1.BAMBOO_SYMBOLS.includes(symbols[i])) {
|
|
274
|
+
matchLength++;
|
|
275
|
+
winPositions.push(positions[i]);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
break; // Bamboo must be consecutive from start
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (matchLength === 0) {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
// Bamboo multiplier: x1=2, x2=5, x3=10
|
|
285
|
+
const multiplier = happy_panda_config_1.LINE_MULTIPLIERS[happy_panda_config_1.Symbol.BAMBOO][matchLength - 1];
|
|
286
|
+
if (multiplier === 0) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
lineIndex,
|
|
291
|
+
symbol: happy_panda_config_1.Symbol.BAMBOO,
|
|
292
|
+
matchLength,
|
|
293
|
+
payout: multiplier * betStake,
|
|
294
|
+
positions: winPositions,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Evaluate all line wins.
|
|
299
|
+
*/
|
|
300
|
+
function evaluateLineWins(grid, gameDirection, betStake) {
|
|
301
|
+
const lineCount = happy_panda_config_1.LINES_PER_DIRECTION[gameDirection];
|
|
302
|
+
const wins = [];
|
|
303
|
+
for (let lineIndex = 0; lineIndex < lineCount; lineIndex++) {
|
|
304
|
+
const win = evaluateLine(grid, lineIndex, betStake);
|
|
305
|
+
if (win) {
|
|
306
|
+
wins.push(win);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return wins;
|
|
310
|
+
}
|
|
311
|
+
// =============================================================================
|
|
312
|
+
// SPECIAL WIN EVALUATION (Bonus-specific)
|
|
313
|
+
// =============================================================================
|
|
314
|
+
/**
|
|
315
|
+
* Evaluate panda piece line wins (Bamboo Triplets Bonus).
|
|
316
|
+
* Dancing Panda pieces on lines pay special multiplier.
|
|
317
|
+
*/
|
|
318
|
+
function evaluatePandaPieceWins(grid, gameDirection, betStake) {
|
|
319
|
+
const pandaPieces = [
|
|
320
|
+
happy_panda_config_1.Symbol.PANDA_PIECE_00, happy_panda_config_1.Symbol.PANDA_PIECE_01, happy_panda_config_1.Symbol.PANDA_PIECE_02,
|
|
321
|
+
happy_panda_config_1.Symbol.PANDA_PIECE_10, happy_panda_config_1.Symbol.PANDA_PIECE_11, happy_panda_config_1.Symbol.PANDA_PIECE_12,
|
|
322
|
+
happy_panda_config_1.Symbol.PANDA_PIECE_20, happy_panda_config_1.Symbol.PANDA_PIECE_21, happy_panda_config_1.Symbol.PANDA_PIECE_22,
|
|
323
|
+
];
|
|
324
|
+
// Only check first 8 lines for panda pieces
|
|
325
|
+
const wins = [];
|
|
326
|
+
let totalLinesWithPieces = 0;
|
|
327
|
+
for (let lineIndex = 0; lineIndex < 8; lineIndex++) {
|
|
328
|
+
const lineShape = happy_panda_config_1.LINE_SHAPES[lineIndex];
|
|
329
|
+
const symbols = lineShape.map(([reel, row]) => grid[reel][row]);
|
|
330
|
+
const allPieces = symbols.every(s => pandaPieces.includes(s));
|
|
331
|
+
if (allPieces) {
|
|
332
|
+
totalLinesWithPieces++;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (totalLinesWithPieces > 0) {
|
|
336
|
+
const multiplier = happy_panda_config_1.SPECIAL_WIN_MULTIPLIERS[gameDirection][0];
|
|
337
|
+
// C++ lines 1520-1545: Per-line payment - each winning line adds to screen_win_sum
|
|
338
|
+
// C++ lines 1956-1957: Panda pieces are position-specific (PANDA_PIECE_00 + reel*3 + row)
|
|
339
|
+
// With position-specific pandas, only geometrically valid lines win (~2.66 avg per spin)
|
|
340
|
+
wins.push({
|
|
341
|
+
winType: happy_panda_config_1.ScreenWinType.SCREEN_PANDA_PIECES,
|
|
342
|
+
count: totalLinesWithPieces,
|
|
343
|
+
payout: totalLinesWithPieces * multiplier * betStake, // Per-line payout
|
|
344
|
+
positions: getAllPositions(),
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return wins;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Evaluate camera scatter wins (Camera Bonus).
|
|
351
|
+
* Each camera pays as scatter during bonus.
|
|
352
|
+
*/
|
|
353
|
+
function evaluateCameraScatterWins(grid, gameDirection, betStake) {
|
|
354
|
+
const cameraCount = countSymbol(grid, happy_panda_config_1.Symbol.CAMERA);
|
|
355
|
+
if (cameraCount === 0) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
const multiplier = happy_panda_config_1.SPECIAL_WIN_MULTIPLIERS[gameDirection][1];
|
|
359
|
+
return {
|
|
360
|
+
winType: happy_panda_config_1.ScreenWinType.SCREEN_CAMERA_SCATTER,
|
|
361
|
+
count: cameraCount,
|
|
362
|
+
payout: cameraCount * multiplier * betStake,
|
|
363
|
+
positions: findSymbolPositions(grid, happy_panda_config_1.Symbol.CAMERA),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Evaluate hat scatter wins (Fireworks Bonus).
|
|
368
|
+
* Each hat pays as scatter during bonus.
|
|
369
|
+
*/
|
|
370
|
+
function evaluateHatScatterWins(grid, gameDirection, betStake) {
|
|
371
|
+
const hatCount = countSymbol(grid, happy_panda_config_1.Symbol.HAT);
|
|
372
|
+
if (hatCount === 0) {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
const multiplier = happy_panda_config_1.SPECIAL_WIN_MULTIPLIERS[gameDirection][2];
|
|
376
|
+
return {
|
|
377
|
+
winType: happy_panda_config_1.ScreenWinType.SCREEN_HAT_SCATTER,
|
|
378
|
+
count: hatCount,
|
|
379
|
+
payout: hatCount * multiplier * betStake,
|
|
380
|
+
positions: findSymbolPositions(grid, happy_panda_config_1.Symbol.HAT),
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
// =============================================================================
|
|
384
|
+
// MAIN EVALUATION FUNCTION
|
|
385
|
+
// =============================================================================
|
|
386
|
+
/**
|
|
387
|
+
* Evaluate all wins for a spin.
|
|
388
|
+
* Implements correct priority: Wall > Scatter > Lines
|
|
389
|
+
*/
|
|
390
|
+
function evaluateSpin(grid, gameDirection, betStake, betGame, spinType) {
|
|
391
|
+
const result = {
|
|
392
|
+
lineWins: [],
|
|
393
|
+
wallWin: null,
|
|
394
|
+
scatterWins: [],
|
|
395
|
+
specialWins: [],
|
|
396
|
+
totalPayout: 0,
|
|
397
|
+
};
|
|
398
|
+
// C++ simulation loop (lines 2731-2735, 2762-2766) shows:
|
|
399
|
+
// LineWinsCalculating() -> player_current_win += line_wins_sum
|
|
400
|
+
// ScreenWinsCalculating() -> player_current_win += screen_win_sum
|
|
401
|
+
// BOTH are added independently - line wins are NEVER suppressed.
|
|
402
|
+
//
|
|
403
|
+
// Screen wins priority: Wall wins suppress scatter wins (not line wins)
|
|
404
|
+
// C++ line 1436: if(screen_win_sum==0) checks for scatter
|
|
405
|
+
// Step 1: Check wall wins (3x3)
|
|
406
|
+
// C++ ScreenWinsCalculating(): BONUS_BAMBOO_TRIPLETS and RESPIN_CENTER_BAMBOO skip standard screen wins
|
|
407
|
+
// BONUS_BAMBOO_TRIPLETS has its own special cherry piece evaluation
|
|
408
|
+
// RESPIN_CENTER_BAMBOO has no screen evaluation
|
|
409
|
+
// Other modes (BASE_GAME_SPIN, BONUS_BAMBOO_TWINS, BONUS_CAMERA, BONUS_FIREWORKS) use standard wall/scatter
|
|
410
|
+
const skipScreenWins = spinType === happy_panda_config_1.SpinType.BONUS_BAMBOO_TRIPLETS || spinType === happy_panda_config_1.SpinType.RESPIN_CENTER_BAMBOO;
|
|
411
|
+
let wallWin = null;
|
|
412
|
+
if (!skipScreenWins) {
|
|
413
|
+
wallWin = evaluateWallWin(grid, betGame);
|
|
414
|
+
if (wallWin) {
|
|
415
|
+
result.wallWin = wallWin;
|
|
416
|
+
result.totalPayout += wallWin.payout;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// Step 2: Check scatter wins (Seven/Super Seven)
|
|
420
|
+
// ONLY if no wall win (C++ line 1436: if screen_win_sum==0)
|
|
421
|
+
// C++ can award up to 2 scatter wins (SEV_S only + total mix)
|
|
422
|
+
// Note: BONUS_BAMBOO_TRIPLETS and RESPIN_CENTER_BAMBOO skip scatter evaluation
|
|
423
|
+
if (!wallWin && !skipScreenWins) {
|
|
424
|
+
const scatterWins = evaluateScatterWins(grid, betGame);
|
|
425
|
+
if (scatterWins.length > 0) {
|
|
426
|
+
result.scatterWins = scatterWins;
|
|
427
|
+
result.totalPayout += scatterWins.reduce((sum, w) => sum + w.payout, 0);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
// Step 3: Line wins
|
|
431
|
+
// C++ lines 2731-2735: LineWinsCalculating() and ScreenWinsCalculating() are independent.
|
|
432
|
+
// Both results are added to player_current_win. Line wins are NEVER suppressed.
|
|
433
|
+
const lineWins = evaluateLineWins(grid, gameDirection, betStake);
|
|
434
|
+
result.lineWins = lineWins;
|
|
435
|
+
result.totalPayout += lineWins.reduce((sum, w) => sum + w.payout, 0);
|
|
436
|
+
// Step 4: Special wins (bonus-specific)
|
|
437
|
+
switch (spinType) {
|
|
438
|
+
case happy_panda_config_1.SpinType.BONUS_BAMBOO_TRIPLETS: {
|
|
439
|
+
const pandaWins = evaluatePandaPieceWins(grid, gameDirection, betStake);
|
|
440
|
+
result.specialWins.push(...pandaWins);
|
|
441
|
+
result.totalPayout += pandaWins.reduce((sum, w) => sum + w.payout, 0);
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
case happy_panda_config_1.SpinType.BONUS_CAMERA: {
|
|
445
|
+
const cameraWin = evaluateCameraScatterWins(grid, gameDirection, betStake);
|
|
446
|
+
if (cameraWin) {
|
|
447
|
+
result.specialWins.push(cameraWin);
|
|
448
|
+
result.totalPayout += cameraWin.payout;
|
|
449
|
+
}
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
case happy_panda_config_1.SpinType.BONUS_FIREWORKS: {
|
|
453
|
+
const hatWin = evaluateHatScatterWins(grid, gameDirection, betStake);
|
|
454
|
+
if (hatWin) {
|
|
455
|
+
result.specialWins.push(hatWin);
|
|
456
|
+
result.totalPayout += hatWin.payout;
|
|
457
|
+
}
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return result;
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=win-evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"win-evaluator.js","sourceRoot":"","sources":["../../../src/logic/services/win-evaluator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dummy RNG Client
|
|
3
|
+
*
|
|
4
|
+
* Local RNG client for development and testing.
|
|
5
|
+
* Uses Math.random() for all operations.
|
|
6
|
+
* Returns seed value of 0 (non-cryptographic, for testing only).
|
|
7
|
+
*/
|
|
8
|
+
import { IRngClient, RngSingleResponse, RngBatchResponse } from './rng-client.interface';
|
|
9
|
+
export declare class DummyRngClient implements IRngClient {
|
|
10
|
+
/**
|
|
11
|
+
* Generate a single random integer in range [min, max]
|
|
12
|
+
*/
|
|
13
|
+
getSingleNumber(min: number, max: number, _seed?: number): Promise<RngSingleResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* Generate multiple random integers in range [min, max]
|
|
16
|
+
*/
|
|
17
|
+
getBatchNumbers(min: number, max: number, count: number, _seed?: number): Promise<number[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Generate multiple random integers with individual seeds
|
|
20
|
+
*/
|
|
21
|
+
getBatchNumbersWithSeeds(min: number, max: number, count: number, _seed?: number): Promise<RngSingleResponse[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Generate a single random float in range [0, 1)
|
|
24
|
+
*/
|
|
25
|
+
getSingleFloat(_seed?: number): Promise<RngSingleResponse>;
|
|
26
|
+
/**
|
|
27
|
+
* Generate multiple random floats in range [0, 1)
|
|
28
|
+
*/
|
|
29
|
+
getBatchFloats(count: number, _seed?: number): Promise<RngBatchResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Alternative method for single random number
|
|
32
|
+
*/
|
|
33
|
+
getRandomNumber(min: number, max: number, _seed?: number): Promise<RngSingleResponse>;
|
|
34
|
+
/**
|
|
35
|
+
* Alternative method for single random float
|
|
36
|
+
*/
|
|
37
|
+
getRandomFloat(_seed?: number): Promise<RngSingleResponse>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=dummy-rng-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dummy-rng-client.d.ts","sourceRoot":"","sources":["../../src/rng/dummy-rng-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,cAAe,YAAW,UAAU;IAC/C;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC;IAM7B;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC;IASpB;;OAEG;IACG,wBAAwB,CAC5B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAY/B;;OAEG;IACG,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIhE;;OAEG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;OAEG;IACG,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGjE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dummy RNG Client
|
|
4
|
+
*
|
|
5
|
+
* Local RNG client for development and testing.
|
|
6
|
+
* Uses Math.random() for all operations.
|
|
7
|
+
* Returns seed value of 0 (non-cryptographic, for testing only).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DummyRngClient = void 0;
|
|
11
|
+
class DummyRngClient {
|
|
12
|
+
/**
|
|
13
|
+
* Generate a single random integer in range [min, max]
|
|
14
|
+
*/
|
|
15
|
+
async getSingleNumber(min, max, _seed) {
|
|
16
|
+
const randomValue = Math.random();
|
|
17
|
+
const result = Math.floor(randomValue * (max - min + 1)) + min;
|
|
18
|
+
return { value: result, seed: 0 };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate multiple random integers in range [min, max]
|
|
22
|
+
*/
|
|
23
|
+
async getBatchNumbers(min, max, count, _seed) {
|
|
24
|
+
const results = [];
|
|
25
|
+
for (let i = 0; i < count; i++) {
|
|
26
|
+
const randomValue = Math.random();
|
|
27
|
+
results.push(Math.floor(randomValue * (max - min + 1)) + min);
|
|
28
|
+
}
|
|
29
|
+
return results;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generate multiple random integers with individual seeds
|
|
33
|
+
*/
|
|
34
|
+
async getBatchNumbersWithSeeds(min, max, count, _seed) {
|
|
35
|
+
const results = [];
|
|
36
|
+
for (let i = 0; i < count; i++) {
|
|
37
|
+
const randomValue = Math.random();
|
|
38
|
+
results.push({
|
|
39
|
+
value: Math.floor(randomValue * (max - min + 1)) + min,
|
|
40
|
+
seed: 0,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return results;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generate a single random float in range [0, 1)
|
|
47
|
+
*/
|
|
48
|
+
async getSingleFloat(_seed) {
|
|
49
|
+
return { value: Math.random(), seed: 0 };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Generate multiple random floats in range [0, 1)
|
|
53
|
+
*/
|
|
54
|
+
async getBatchFloats(count, _seed) {
|
|
55
|
+
const values = [];
|
|
56
|
+
const seeds = [];
|
|
57
|
+
for (let i = 0; i < count; i++) {
|
|
58
|
+
values.push(Math.random());
|
|
59
|
+
seeds.push(0);
|
|
60
|
+
}
|
|
61
|
+
return { values, seeds };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Alternative method for single random number
|
|
65
|
+
*/
|
|
66
|
+
async getRandomNumber(min, max, _seed) {
|
|
67
|
+
return this.getSingleNumber(min, max, _seed);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Alternative method for single random float
|
|
71
|
+
*/
|
|
72
|
+
async getRandomFloat(_seed) {
|
|
73
|
+
return this.getSingleFloat(_seed);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.DummyRngClient = DummyRngClient;
|
|
77
|
+
//# sourceMappingURL=dummy-rng-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dummy-rng-client.js","sourceRoot":"","sources":["../../src/rng/dummy-rng-client.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAQH,MAAa,cAAc;IACzB;;OAEG;IACH,KAAK,CAAC,eAAe,CACnB,GAAW,EACX,GAAW,EACX,KAAc;QAEd,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CACnB,GAAW,EACX,GAAW,EACX,KAAa,EACb,KAAc;QAEd,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,wBAAwB,CAC5B,GAAW,EACX,GAAW,EACX,KAAa,EACb,KAAc;QAEd,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG;gBACtD,IAAI,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,KAAc;QACjC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,KAAc;QAEd,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CACnB,GAAW,EACX,GAAW,EACX,KAAc;QAEd,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,KAAc;QACjC,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;CACF;AA3FD,wCA2FC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RNG module exports
|
|
3
|
+
*/
|
|
4
|
+
export * from './weighted-random';
|
|
5
|
+
export * from './spin-generator';
|
|
6
|
+
export * from './rng-client.interface';
|
|
7
|
+
export * from './dummy-rng-client';
|
|
8
|
+
export * from './rng-client.factory';
|
|
9
|
+
export * from './rng-service';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
* RNG module exports
|
|
19
|
+
*/
|
|
20
|
+
__exportStar(require("./weighted-random"), exports);
|
|
21
|
+
__exportStar(require("./spin-generator"), exports);
|
|
22
|
+
// RNG Service and Client Infrastructure
|
|
23
|
+
__exportStar(require("./rng-client.interface"), exports);
|
|
24
|
+
__exportStar(require("./dummy-rng-client"), exports);
|
|
25
|
+
__exportStar(require("./rng-client.factory"), exports);
|
|
26
|
+
__exportStar(require("./rng-service"), exports);
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,oDAAkC;AAClC,mDAAiC;AAEjC,wCAAwC;AACxC,yDAAuC;AACvC,qDAAmC;AACnC,uDAAqC;AACrC,gDAA8B"}
|