@omnitronix/bonnys-fortune-game-engine 1.3.1 → 1.3.2

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 (146) hide show
  1. package/README.md +15 -15
  2. package/dist/__tests__/bonnys-fortune-v1.game-engine.test.d.ts +1 -0
  3. package/dist/bonnys-fortune-v1.game-engine.d.ts +36 -0
  4. package/dist/bonnys-fortune-v1.game-engine.js +23 -12
  5. package/dist/bonnys-fortune-v1.game-engine.js.map +1 -1
  6. package/dist/config/game-logic-config/file-system.game-logic-config-loader.d.ts +4 -0
  7. package/dist/config/game-logic-config/game-logic-config-loader.d.ts +3 -0
  8. package/dist/config/game-logic-config/game-logic-config.d.ts +2 -0
  9. package/dist/config/game-logic-config/game-logic-config.js +2 -0
  10. package/dist/config/game-logic-config/game-logic-config.js.map +1 -1
  11. package/dist/config/reel-strips-config/file-system.reel-strips-config-loader.d.ts +4 -0
  12. package/dist/config/reel-strips-config/reel-strip-option.dto.d.ts +4 -0
  13. package/dist/config/reel-strips-config/reel-strips-config-loader.d.ts +3 -0
  14. package/dist/config/reel-strips-config/reel-strips-config.dto.d.ts +5 -0
  15. package/dist/config/reel-strips-config/reel.dto.d.ts +5 -0
  16. package/dist/domain/game-round.types.d.ts +9 -0
  17. package/dist/domain/mappers/reel-strips-config.mapper.d.ts +4 -0
  18. package/dist/domain/reel-strip-option.d.ts +7 -0
  19. package/dist/domain/reel-strips-config.d.ts +9 -0
  20. package/dist/domain/reel.d.ts +8 -0
  21. package/dist/domain/types/cheat-trigger-bonus-command.d.ts +5 -0
  22. package/dist/domain/types/{debug-trigger-bonus-command.js → cheat-trigger-bonus-command.js} +1 -1
  23. package/dist/domain/types/cheat-trigger-bonus-command.js.map +1 -0
  24. package/dist/domain/types/cheat-trigger-bonus-request.dto.d.ts +5 -0
  25. package/dist/domain/types/{debug-trigger-bonus-request.dto.js → cheat-trigger-bonus-request.dto.js} +1 -1
  26. package/dist/domain/types/cheat-trigger-bonus-request.dto.js.map +1 -0
  27. package/dist/domain/types/cheat-update-bonus-meter-progress-command.d.ts +5 -0
  28. package/dist/domain/types/{debug-update-bonus-meter-progress-command.js → cheat-update-bonus-meter-progress-command.js} +1 -1
  29. package/dist/domain/types/cheat-update-bonus-meter-progress-command.js.map +1 -0
  30. package/dist/domain/types/cheat-update-bonus-meter-progress-request.dto.d.ts +5 -0
  31. package/dist/domain/types/{debug-update-bonus-meter-progress-request.dto.js → cheat-update-bonus-meter-progress-request.dto.js} +1 -1
  32. package/dist/domain/types/cheat-update-bonus-meter-progress-request.dto.js.map +1 -0
  33. package/dist/domain/types/game-spin-command.d.ts +8 -0
  34. package/dist/domain/types/game-spin-input.dto.d.ts +8 -0
  35. package/dist/domain/types/game-spin-output.dto.d.ts +119 -0
  36. package/dist/domain/types/game-symbols.response.dto.d.ts +10 -0
  37. package/dist/domain/types/reel-strip-option.dto.d.ts +4 -0
  38. package/dist/domain/types/reel-strips-config.dto.d.ts +5 -0
  39. package/dist/domain/types/reel.dto.d.ts +5 -0
  40. package/dist/domain/types/start-bonus-round-command.d.ts +8 -0
  41. package/dist/domain/types/start-bonus-round-input.dto.d.ts +10 -0
  42. package/dist/game-engine.interface.d.ts +41 -0
  43. package/dist/helpers/generate-hash.d.ts +1 -0
  44. package/dist/helpers/number-helper.d.ts +23 -0
  45. package/dist/helpers/optional-boolean-mapper.d.ts +1 -0
  46. package/dist/helpers/uuid-helper.d.ts +3 -0
  47. package/dist/helpers/validation-helper.d.ts +14 -0
  48. package/dist/index.d.ts +2 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/logger/logger.d.ts +22 -0
  51. package/dist/logger/logger.js +4 -5
  52. package/dist/logger/logger.js.map +1 -1
  53. package/dist/logic/bonnys-fortune.game-logic.d.ts +32 -0
  54. package/dist/logic/bonnys-fortune.game-logic.js +15 -11
  55. package/dist/logic/bonnys-fortune.game-logic.js.map +1 -1
  56. package/dist/logic/bonnys-fortune.spin-generator.d.ts +19 -0
  57. package/dist/logic/bonnys-fortune.types.d.ts +170 -0
  58. package/dist/logic/bonnys-fortune.win-calculator.d.ts +10 -0
  59. package/dist/logic/game-logic-config.interface.d.ts +180 -0
  60. package/dist/logic/handlers/base-game.handler.d.ts +15 -0
  61. package/dist/logic/handlers/base-game.handler.js +5 -1
  62. package/dist/logic/handlers/base-game.handler.js.map +1 -1
  63. package/dist/logic/handlers/collect-feature-bonus.handler.d.ts +13 -0
  64. package/dist/logic/handlers/free-spins-bonus.handler.d.ts +11 -0
  65. package/dist/logic/handlers/steering-to-the-fortune-bonus.handler.d.ts +11 -0
  66. package/dist/logic/handlers/treasure-hunt-bonus.handler.d.ts +15 -0
  67. package/dist/rng/DummyRngClient.d.ts +18 -0
  68. package/dist/rng/DummyRngClient.js +1 -8
  69. package/dist/rng/DummyRngClient.js.map +1 -1
  70. package/dist/rng/rng-client.factory.d.ts +7 -0
  71. package/dist/rng/rng-client.factory.js.map +1 -1
  72. package/dist/rng/rng-client.interface.d.ts +16 -0
  73. package/dist/rng/rng-service.d.ts +26 -0
  74. package/dist/validation/abstract-game-logic-config.validator.d.ts +4 -0
  75. package/dist/validation/bonnys-fortune/bonnys-fortune-config.dto.d.ts +131 -0
  76. package/dist/validation/bonnys-fortune/bonnys-fortune-config.dto.js +9 -0
  77. package/dist/validation/bonnys-fortune/bonnys-fortune-config.dto.js.map +1 -1
  78. package/dist/validation/bonnys-fortune/bonnys-fortune-config.validator.d.ts +5 -0
  79. package/dist/validation/custom-decorators/IsNestedIntArray.d.ts +2 -0
  80. package/dist/validation/game-logic-config-validation.service.d.ts +8 -0
  81. package/dist/validation/reel-strips-config-validation.service.d.ts +5 -0
  82. package/package.json +4 -3
  83. package/src/__tests__/bonnys-fortune-v1.game-engine.test.ts +80 -0
  84. package/src/bonnys-fortune-v1.game-engine.ts +314 -0
  85. package/src/config/game-logic-config/file-system.game-logic-config-loader.ts +27 -0
  86. package/src/config/game-logic-config/game-logic-config-loader.ts +3 -0
  87. package/src/config/game-logic-config/game-logic-config.ts +382 -0
  88. package/src/config/reel-strips-config/file-system.reel-strips-config-loader.ts +43 -0
  89. package/src/config/reel-strips-config/reel-strip-option.dto.ts +13 -0
  90. package/src/config/reel-strips-config/reel-strips-config-loader.ts +9 -0
  91. package/src/config/reel-strips-config/reel-strips-config.dto.ts +16 -0
  92. package/src/config/reel-strips-config/reel.dto.ts +16 -0
  93. package/src/config/reel-strips-config/reels-BASE.csv +52 -0
  94. package/src/config/reel-strips-config/reels-BONUS.csv +52 -0
  95. package/src/domain/game-round.types.ts +10 -0
  96. package/src/domain/mappers/reel-strips-config.mapper.ts +16 -0
  97. package/src/domain/reel-strip-option.ts +15 -0
  98. package/src/domain/reel-strips-config.ts +21 -0
  99. package/src/domain/reel.ts +17 -0
  100. package/src/domain/types/cheat-trigger-bonus-command.ts +5 -0
  101. package/src/domain/types/cheat-trigger-bonus-request.dto.ts +5 -0
  102. package/src/domain/types/cheat-update-bonus-meter-progress-command.ts +6 -0
  103. package/src/domain/types/cheat-update-bonus-meter-progress-request.dto.ts +5 -0
  104. package/src/domain/types/game-spin-command.ts +8 -0
  105. package/src/domain/types/game-spin-input.dto.ts +8 -0
  106. package/src/domain/types/game-spin-output.dto.ts +142 -0
  107. package/src/domain/types/game-symbols.response.dto.ts +11 -0
  108. package/src/domain/types/reel-strip-option.dto.ts +13 -0
  109. package/src/domain/types/reel-strips-config.dto.ts +15 -0
  110. package/src/domain/types/reel.dto.ts +15 -0
  111. package/src/domain/types/start-bonus-round-command.ts +8 -0
  112. package/src/domain/types/start-bonus-round-input.dto.ts +10 -0
  113. package/src/game-engine.interface.ts +59 -0
  114. package/src/helpers/generate-hash.ts +5 -0
  115. package/src/helpers/number-helper.ts +41 -0
  116. package/src/helpers/optional-boolean-mapper.ts +5 -0
  117. package/src/helpers/uuid-helper.ts +7 -0
  118. package/src/helpers/validation-helper.ts +27 -0
  119. package/src/index.ts +3 -0
  120. package/src/logger/logger.ts +178 -0
  121. package/src/logic/bonnys-fortune.game-logic.ts +490 -0
  122. package/src/logic/bonnys-fortune.spin-generator.ts +277 -0
  123. package/src/logic/bonnys-fortune.types.ts +223 -0
  124. package/src/logic/bonnys-fortune.win-calculator.ts +210 -0
  125. package/src/logic/game-logic-config.interface.ts +176 -0
  126. package/src/logic/handlers/base-game.handler.ts +221 -0
  127. package/src/logic/handlers/collect-feature-bonus.handler.ts +301 -0
  128. package/src/logic/handlers/free-spins-bonus.handler.ts +119 -0
  129. package/src/logic/handlers/steering-to-the-fortune-bonus.handler.ts +118 -0
  130. package/src/logic/handlers/treasure-hunt-bonus.handler.ts +232 -0
  131. package/src/rng/DummyRngClient.ts +108 -0
  132. package/src/rng/rng-client.factory.ts +27 -0
  133. package/src/rng/rng-client.interface.ts +38 -0
  134. package/src/rng/rng-service.ts +130 -0
  135. package/src/validation/abstract-game-logic-config.validator.ts +20 -0
  136. package/src/validation/bonnys-fortune/bonnys-fortune-config.dto.ts +379 -0
  137. package/src/validation/bonnys-fortune/bonnys-fortune-config.validator.ts +8 -0
  138. package/src/validation/custom-decorators/IsNestedIntArray.ts +29 -0
  139. package/src/validation/game-logic-config-validation.service.ts +28 -0
  140. package/src/validation/reel-strips-config-validation.service.ts +29 -0
  141. package/dist/__tests__/comprehensive.test.js +0 -741
  142. package/dist/__tests__/comprehensive.test.js.map +0 -1
  143. package/dist/domain/types/debug-trigger-bonus-command.js.map +0 -1
  144. package/dist/domain/types/debug-trigger-bonus-request.dto.js.map +0 -1
  145. package/dist/domain/types/debug-update-bonus-meter-progress-command.js.map +0 -1
  146. package/dist/domain/types/debug-update-bonus-meter-progress-request.dto.js.map +0 -1
@@ -0,0 +1,382 @@
1
+ import { BonnysFortuneGameLogicConfigInterface } from '../../logic/game-logic-config.interface';
2
+
3
+ export const gameLogicConfig: BonnysFortuneGameLogicConfigInterface = {
4
+ baseGame: {
5
+ symbolMultipliers: [
6
+ {
7
+ symbolId: 0,
8
+ name: 'H1',
9
+ isWild: false,
10
+ isScatter: false,
11
+ multipliers: {
12
+ x3: 50,
13
+ x4: 150,
14
+ x5: 500,
15
+ },
16
+ },
17
+ {
18
+ symbolId: 1,
19
+ name: 'H2',
20
+ isWild: false,
21
+ isScatter: false,
22
+ multipliers: {
23
+ x3: 30,
24
+ x4: 100,
25
+ x5: 300,
26
+ },
27
+ },
28
+ {
29
+ symbolId: 2,
30
+ name: 'H3',
31
+ isWild: false,
32
+ isScatter: false,
33
+ multipliers: {
34
+ x3: 20,
35
+ x4: 50,
36
+ x5: 150,
37
+ },
38
+ },
39
+ {
40
+ symbolId: 3,
41
+ name: 'M1',
42
+ isWild: false,
43
+ isScatter: false,
44
+ multipliers: {
45
+ x3: 10,
46
+ x4: 25,
47
+ x5: 75,
48
+ },
49
+ },
50
+ {
51
+ symbolId: 4,
52
+ name: 'M2',
53
+ isWild: false,
54
+ isScatter: false,
55
+ multipliers: {
56
+ x3: 7,
57
+ x4: 15,
58
+ x5: 50,
59
+ },
60
+ },
61
+ {
62
+ symbolId: 5,
63
+ name: 'M3',
64
+ isWild: false,
65
+ isScatter: false,
66
+ multipliers: {
67
+ x3: 5,
68
+ x4: 10,
69
+ x5: 25,
70
+ },
71
+ },
72
+ {
73
+ symbolId: 6,
74
+ name: 'L1',
75
+ isWild: false,
76
+ isScatter: false,
77
+ multipliers: {
78
+ x3: 3,
79
+ x4: 6,
80
+ x5: 15,
81
+ },
82
+ },
83
+ {
84
+ symbolId: 7,
85
+ name: 'L2',
86
+ isWild: false,
87
+ isScatter: false,
88
+ multipliers: {
89
+ x3: 3,
90
+ x4: 6,
91
+ x5: 15,
92
+ },
93
+ },
94
+ {
95
+ symbolId: 8,
96
+ name: 'L3',
97
+ isWild: false,
98
+ isScatter: false,
99
+ multipliers: {
100
+ x3: 2,
101
+ x4: 4,
102
+ x5: 10,
103
+ },
104
+ },
105
+ {
106
+ symbolId: 9,
107
+ name: 'L4',
108
+ isWild: false,
109
+ isScatter: false,
110
+ multipliers: {
111
+ x3: 2,
112
+ x4: 4,
113
+ x5: 10,
114
+ },
115
+ },
116
+ {
117
+ symbolId: 10,
118
+ name: 'WILD',
119
+ isWild: true,
120
+ isScatter: false,
121
+ multipliers: {
122
+ x3: 1,
123
+ x4: 1,
124
+ x5: 1,
125
+ },
126
+ },
127
+ {
128
+ symbolId: 11,
129
+ name: 'SCATTER',
130
+ isWild: false,
131
+ isScatter: true,
132
+ multipliers: {
133
+ x3: 1,
134
+ x4: 1,
135
+ x5: 1,
136
+ },
137
+ },
138
+ ],
139
+ symbolDefinitions: {
140
+ baseSymbols: {
141
+ minIndex: 0,
142
+ maxIndex: 9,
143
+ },
144
+ specialSymbols: {
145
+ WILD: 10,
146
+ SCATTER: 11,
147
+ },
148
+ collectFeatureSymbols: {
149
+ multipliers: {
150
+ CM1: 12,
151
+ CM2: 13,
152
+ CM3: 14,
153
+ },
154
+ values: {
155
+ CV1: 15,
156
+ CV2: 16,
157
+ CV3: 17,
158
+ },
159
+ },
160
+ },
161
+ baseGameConfig: {
162
+ layout: {
163
+ rows: 3,
164
+ reels: 5,
165
+ },
166
+ winConfig: {
167
+ minLength: 3,
168
+ maxLength: 5,
169
+ },
170
+ baseBet: 10,
171
+ reelsOptions: {
172
+ numberOfOptions: 4,
173
+ optionWeights: [4, 4, 5, 5],
174
+ },
175
+ },
176
+ paidHSymbolWeights: {
177
+ None: 298,
178
+ H1: 22,
179
+ H2: 12,
180
+ H3: 50,
181
+ },
182
+ paidHSymbolReelWeights: {
183
+ H1: [5, 15],
184
+ H2: [5, 15],
185
+ H3: [5, 15],
186
+ },
187
+ paidScatterReelWeights: {
188
+ reel1: [3, 15],
189
+ reel2: [0, 5],
190
+ reel3: [3, 15],
191
+ reel4: [0, 5],
192
+ reel5: [3, 15],
193
+ },
194
+ bonusGameMeters: {
195
+ bonusGame1: {
196
+ symbol: 'H1',
197
+ min: 25,
198
+ max: 100,
199
+ percentageLevels: {
200
+ level1: { min: 0, max: 0.25, value: 1 },
201
+ level2: { min: 0.25, max: 0.65, value: 2 },
202
+ level3: { min: 0.65, max: 0.8, value: 3 },
203
+ level4: { min: 0.8, max: 1.0, value: 4 },
204
+ level5: { min: 1.0, max: 1.0, value: 5 },
205
+ },
206
+ },
207
+ bonusGame2: {
208
+ symbol: 'H2',
209
+ min: 25,
210
+ max: 70,
211
+ percentageLevels: {
212
+ level1: { min: 0, max: 0.25, value: 1 },
213
+ level2: { min: 0.25, max: 0.65, value: 2 },
214
+ level3: { min: 0.65, max: 0.8, value: 3 },
215
+ level4: { min: 0.8, max: 1.0, value: 4 },
216
+ level5: { min: 1.0, max: 1.0, value: 5 },
217
+ },
218
+ },
219
+ bonusGame3: {
220
+ symbol: 'H3',
221
+ min: 25,
222
+ max: 80,
223
+ percentageLevels: {
224
+ level1: { min: 0, max: 0.25, value: 1 },
225
+ level2: { min: 0.25, max: 0.65, value: 2 },
226
+ level3: { min: 0.65, max: 0.8, value: 3 },
227
+ level4: { min: 0.8, max: 1.0, value: 4 },
228
+ level5: { min: 1.0, max: 1.0, value: 5 },
229
+ },
230
+ },
231
+ },
232
+ },
233
+ bonusGames: {
234
+ bonusGame1: {
235
+ type: 'treasure_hunt',
236
+ potMeter: 'bonusGame1',
237
+ config: {
238
+ symbolsCount: 25,
239
+ stepsCount: 6,
240
+ jackpotMultipliers: {
241
+ mini: 20,
242
+ minor: 50,
243
+ major: 200,
244
+ grand: 2000,
245
+ },
246
+ jackpotStartCounts: {
247
+ mini: 0,
248
+ minor: 0,
249
+ major: 0,
250
+ grand: 0,
251
+ },
252
+ jackpotScreenCounts: {
253
+ mini: 10,
254
+ minor: 7,
255
+ major: 5,
256
+ grand: 3,
257
+ },
258
+ winningWeights: {
259
+ none: 30,
260
+ mini: 90,
261
+ minor: 25,
262
+ major: 5,
263
+ grand: 1,
264
+ },
265
+ },
266
+ },
267
+ bonusGame2: {
268
+ type: 'free_spins',
269
+ potMeter: 'bonusGame2',
270
+ config: {
271
+ spinTypes: [
272
+ {
273
+ layout: { reels: 5, rows: 3 },
274
+ spins: 8,
275
+ multiplier: 10,
276
+ weight: 5,
277
+ reelsOptionsWeights: [1, 1, 4, 4],
278
+ },
279
+ {
280
+ layout: { reels: 5, rows: 3 },
281
+ spins: 4,
282
+ multiplier: 20,
283
+ weight: 5,
284
+ reelsOptionsWeights: [1, 1, 4, 4],
285
+ },
286
+ {
287
+ layout: { reels: 5, rows: 4 },
288
+ spins: 8,
289
+ multiplier: 3,
290
+ weight: 5,
291
+ reelsOptionsWeights: [1, 1, 4, 4],
292
+ },
293
+ {
294
+ layout: { reels: 5, rows: 4 },
295
+ spins: 4,
296
+ multiplier: 6,
297
+ weight: 5,
298
+ reelsOptionsWeights: [1, 1, 4, 4],
299
+ },
300
+ {
301
+ layout: { reels: 5, rows: 5 },
302
+ spins: 8,
303
+ multiplier: 1,
304
+ weight: 5,
305
+ reelsOptionsWeights: [1, 1, 4, 4],
306
+ },
307
+ {
308
+ layout: { reels: 5, rows: 5 },
309
+ spins: 4,
310
+ multiplier: 2,
311
+ weight: 5,
312
+ reelsOptionsWeights: [1, 1, 4, 4],
313
+ },
314
+ ],
315
+ },
316
+ },
317
+ bonusGame3: {
318
+ type: 'steering_to_the_fortune',
319
+ potMeter: 'bonusGame3',
320
+ config: {
321
+ wheelResults: [
322
+ { type: 'MULTIPLIER', value: 5, weight: 2 },
323
+ { type: 'MULTIPLIER', value: 8, weight: 3 },
324
+ { type: 'MULTIPLIER', value: 10, weight: 5 },
325
+ { type: 'MULTIPLIER', value: 15, weight: 5 },
326
+ { type: 'MULTIPLIER', value: 25, weight: 5 },
327
+ { type: 'MULTIPLIER', value: 40, weight: 3 },
328
+ { type: 'MULTIPLIER', value: 80, weight: 2 },
329
+ { type: 'BONUS', bonusType: 'collectFeature', weight: 2 },
330
+ { type: 'BONUS', bonusType: 'bonusGame1', weight: 2 },
331
+ { type: 'BONUS', bonusType: 'bonusGame2', weight: 2 },
332
+ ],
333
+ },
334
+ },
335
+ },
336
+ defaultBetAmountThresholds: [0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100],
337
+ defaultBetAmount: 1,
338
+ scatterGame: {
339
+ config: {
340
+ scatterMinNumber: 3,
341
+ scatterSpins: 6,
342
+ scatterCheckpoints: [
343
+ { spin: 3, multiMinValue: 0, valueMinValue: 1 },
344
+ { spin: 2, multiMinValue: 1, valueMinValue: 2 },
345
+ ],
346
+ scatterSymbols: [
347
+ {
348
+ symbolId: 'CM1',
349
+ value: 1,
350
+ weight: 20,
351
+ },
352
+ {
353
+ symbolId: 'CM2',
354
+ value: 2,
355
+ weight: 10,
356
+ },
357
+ {
358
+ symbolId: 'CM3',
359
+ value: 3,
360
+ weight: 2,
361
+ },
362
+ {
363
+ symbolId: 'CV1',
364
+ value: 1,
365
+ weight: 50,
366
+ },
367
+ {
368
+ symbolId: 'CV2',
369
+ value: 2,
370
+ weight: 15,
371
+ },
372
+ {
373
+ symbolId: 'CV3',
374
+ value: 5,
375
+ weight: 5,
376
+ },
377
+ ],
378
+ scatterSymbolSpins: [{ weight: 10 }, { weight: 4 }, { weight: 2 }],
379
+ scatterSymbolSlash: [{ weight: 10 }, { weight: 6 }, { weight: 0 }],
380
+ },
381
+ },
382
+ };
@@ -0,0 +1,43 @@
1
+ import { ReelStripsConfigLoader } from './reel-strips-config-loader';
2
+ import path from 'path';
3
+ import { readFileSync } from 'fs';
4
+
5
+ export class FileSystemReelStripsConfigLoader
6
+ implements ReelStripsConfigLoader
7
+ {
8
+ public async loadConfig(
9
+ gameId: string,
10
+ variantId: string,
11
+ reelSetName: string,
12
+ reelsCount: number,
13
+ optionsCount: number,
14
+ ): Promise<number[][][]> {
15
+ const filePath = path.resolve(__dirname, `./reels-${reelSetName}.csv`);
16
+
17
+ const content = readFileSync(filePath, 'utf-8');
18
+ const lines = content
19
+ .split('\n')
20
+ .map((line) => line.trim())
21
+ .filter((line) => line.length > 0)
22
+ .slice(2); // skip headers
23
+
24
+ const result: number[][][] = Array.from({ length: reelsCount }, () =>
25
+ Array.from({ length: optionsCount }, () => []),
26
+ );
27
+
28
+ for (const line of lines) {
29
+ const values = line.split(';').map((v) => v.trim());
30
+
31
+ for (let reel = 0; reel < reelsCount; reel++) {
32
+ for (let opt = 0; opt < optionsCount; opt++) {
33
+ const val = values[reel * optionsCount + opt];
34
+ if (val !== '') {
35
+ result[reel][opt].push(Number(val));
36
+ }
37
+ }
38
+ }
39
+ }
40
+
41
+ return result;
42
+ }
43
+ }
@@ -0,0 +1,13 @@
1
+ import { ArrayNotEmpty, IsArray, IsInt, Min } from 'class-validator';
2
+
3
+ export class ReelStripOptionDto {
4
+ @IsArray()
5
+ @ArrayNotEmpty()
6
+ @IsInt({ each: true })
7
+ @Min(0, { each: true })
8
+ public symbols: number[];
9
+
10
+ constructor(symbols: number[]) {
11
+ this.symbols = symbols;
12
+ }
13
+ }
@@ -0,0 +1,9 @@
1
+ export interface ReelStripsConfigLoader {
2
+ loadConfig(
3
+ gameId: string,
4
+ variantId: string,
5
+ reelSetName: string,
6
+ reelsCount: number,
7
+ optionsCount: number,
8
+ ): Promise<number[][][]>;
9
+ }
@@ -0,0 +1,16 @@
1
+ import { ArrayNotEmpty, IsArray, ValidateNested } from 'class-validator';
2
+
3
+ import { ReelDto } from './reel.dto';
4
+ import { Type } from 'class-transformer';
5
+
6
+ export class ReelStripsConfigDto {
7
+ @IsArray()
8
+ @ArrayNotEmpty()
9
+ @ValidateNested({ each: true })
10
+ @Type(() => ReelDto)
11
+ public reels: ReelDto[];
12
+
13
+ constructor(reels: ReelDto[]) {
14
+ this.reels = reels;
15
+ }
16
+ }
@@ -0,0 +1,16 @@
1
+ import { ArrayNotEmpty, IsArray, ValidateNested } from 'class-validator';
2
+
3
+ import { ReelStripOptionDto } from './reel-strip-option.dto';
4
+ import { Type } from 'class-transformer';
5
+
6
+ export class ReelDto {
7
+ @IsArray()
8
+ @ArrayNotEmpty()
9
+ @ValidateNested({ each: true })
10
+ @Type(() => ReelStripOptionDto)
11
+ public options: ReelStripOptionDto[];
12
+
13
+ constructor(options: ReelStripOptionDto[]) {
14
+ this.options = options;
15
+ }
16
+ }
@@ -0,0 +1,52 @@
1
+ Reel 1;;;;Reel 2;;;;Reel 3;;;;Reel 4;;;;Reel 5;;;
2
+ option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3
3
+ 9;8;9;8;8;9;8;9;9;8;9;9;9;9;9;9;9;9;9;8
4
+ 9;8;9;8;8;9;8;9;9;8;9;9;9;9;9;9;9;9;9;8
5
+ 9;8;9;9;8;9;9;10;10;8;10;8;9;8;8;10;8;9;9;9
6
+ 7;6;7;6;6;7;6;7;7;6;7;6;6;7;6;7;7;6;7;6
7
+ 7;6;7;7;6;7;10;7;7;6;7;10;10;7;10;7;7;6;7;7
8
+ 7;4;6;4;4;7;4;6;7;4;6;4;4;7;4;6;7;4;6;4
9
+ 9;8;8;8;8;9;8;8;9;8;8;8;5;8;8;8;8;5;8;8
10
+ 5;8;5;3;8;5;3;5;5;10;5;3;8;10;3;3;5;8;5;3
11
+ 5;4;5;5;4;5;5;5;5;4;5;5;4;4;5;3;4;4;5;5
12
+ 7;6;7;6;6;7;6;7;7;6;7;7;6;6;7;7;6;6;7;6
13
+ 9;8;9;9;8;9;9;9;9;8;9;8;8;9;7;9;9;8;9;9
14
+ 3;8;3;9;8;3;9;3;3;8;3;9;3;10;9;5;3;3;3;9
15
+ 3;6;3;3;6;3;3;3;3;6;3;3;10;4;3;5;4;7;3;3
16
+ 5;6;5;7;6;5;7;5;5;6;5;6;6;5;6;5;5;6;5;7
17
+ 9;6;8;7;6;9;7;8;9;6;8;7;6;9;8;8;9;6;8;7
18
+ 9;8;8;8;8;9;8;8;9;8;8;9;8;9;9;8;9;8;8;8
19
+ 7;4;6;4;4;7;4;6;10;4;6;4;5;7;4;6;7;5;6;4
20
+ 7;4;6;4;4;7;4;6;7;4;6;4;5;7;4;6;7;5;6;4
21
+ 5;8;4;8;8;5;8;4;5;8;4;8;8;5;7;4;5;8;4;8
22
+ 5;8;4;8;8;5;8;4;5;10;4;8;8;5;7;4;5;8;4;8
23
+ 9;8;9;8;8;9;8;9;9;8;9;8;8;8;8;7;8;8;9;8
24
+ 9;4;9;5;4;9;5;9;9;4;9;5;4;8;5;7;8;4;9;5
25
+ 9;4;9;5;4;9;5;9;9;4;9;5;4;8;6;7;8;4;9;5
26
+ 7;6;7;6;6;7;6;7;7;6;7;7;7;7;7;7;7;7;7;6
27
+ 3;8;3;8;8;3;8;3;3;8;3;8;8;10;8;5;3;8;3;8
28
+ 3;8;3;8;8;3;10;3;3;8;3;10;8;3;10;5;3;8;3;8
29
+ 9;4;9;3;4;9;3;9;10;4;9;3;10;9;3;9;9;4;9;3
30
+ 7;6;7;7;6;7;7;7;7;10;7;7;3;6;7;9;6;3;7;7
31
+ 7;6;7;7;6;7;7;7;7;6;7;7;3;6;7;9;6;3;7;7
32
+ 7;8;7;8;8;7;8;7;7;8;7;8;9;6;8;9;6;9;7;8
33
+ 9;4;9;4;4;9;4;9;9;4;9;4;4;9;4;9;9;4;9;4
34
+ 5;4;5;4;4;5;4;10;5;4;10;4;4;4;4;10;4;4;5;4
35
+ 5;8;5;8;8;5;8;5;5;8;5;8;8;4;8;3;4;8;5;8
36
+ 7;8;6;8;8;7;8;6;7;8;6;8;8;7;8;6;7;8;6;8
37
+ 9;6;8;6;6;9;6;8;9;10;8;7;6;9;8;8;9;6;8;6
38
+ 9;6;8;6;6;9;6;8;9;6;8;6;6;9;6;8;9;6;8;6
39
+ 5;6;5;3;6;5;3;5;10;6;5;3;6;10;3;3;5;6;5;3
40
+ 5;8;5;9;8;5;10;5;5;8;5;10;10;5;10;5;5;8;5;9
41
+ 7;8;7;9;8;7;9;7;7;8;7;9;8;6;9;9;6;8;7;9
42
+ 7;8;7;8;8;7;8;7;7;8;7;9;8;7;9;9;7;8;7;8
43
+ 9;6;9;6;6;9;6;9;9;6;9;6;6;9;5;7;9;6;9;6
44
+ 9;6;9;6;6;9;6;9;9;6;9;6;6;9;5;7;9;6;9;6
45
+ 9;6;9;6;6;9;6;10;10;6;10;6;6;9;5;10;9;6;9;6
46
+ 5;8;4;8;8;5;8;4;5;8;4;8;9;4;8;4;4;9;4;8
47
+ 3;4;4;5;4;3;5;4;3;4;4;5;4;4;6;4;4;4;4;5
48
+ 3;4;8;5;4;3;5;8;3;4;8;5;4;10;6;8;4;4;8;5
49
+ 9;4;9;4;4;9;4;9;9;10;9;4;10;9;4;9;9;5;9;4
50
+ 5;6;5;7;6;5;7;5;5;6;5;6;7;5;6;5;5;7;5;7
51
+ 7;6;6;7;6;7;7;6;7;6;6;6;7;7;6;6;7;7;6;7
52
+ 7;6;6;7;6;7;7;6;7;6;6;7;7;7;8;6;7;7;6;7
@@ -0,0 +1,52 @@
1
+ Reel 1;;;;Reel 2;;;;Reel 3;;;;Reel 4;;;;Reel 5;;;
2
+ option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3;option 0;option 1;option 2;option 3
3
+ 9;8;9;8;8;9;8;9;5;8;9;8;6;9;8;9;9;8;9;8
4
+ 9;8;9;8;8;9;10;10;5;8;10;10;6;9;10;10;9;8;9;8
5
+ 9;8;8;9;8;9;0;8;10;10;8;9;10;10;9;8;9;8;8;9
6
+ 7;6;6;6;6;7;4;5;7;6;6;4;8;7;4;6;7;6;6;6
7
+ 7;6;6;6;6;7;4;5;7;6;6;4;8;7;4;6;7;6;6;6
8
+ 5;4;4;5;4;5;5;3;9;4;4;5;4;5;5;4;5;4;4;5
9
+ 5;4;4;4;4;5;6;3;9;4;4;6;4;5;6;4;5;4;4;4
10
+ 9;8;9;8;8;9;7;8;9;8;8;7;6;9;8;9;9;8;9;8
11
+ 1;0;1;1;0;1;8;4;7;0;3;1;2;1;1;1;1;0;1;1
12
+ 1;0;0;0;0;1;9;0;7;0;0;0;2;1;0;0;1;0;0;0
13
+ 7;6;7;6;6;7;6;7;7;6;7;6;8;7;6;7;7;6;7;6
14
+ 3;2;2;3;2;3;3;2;3;2;2;3;2;3;3;2;3;2;2;3
15
+ 9;8;8;9;8;9;0;9;5;8;9;9;6;9;9;8;9;8;8;9
16
+ 9;8;8;9;8;9;10;8;5;8;8;10;6;9;10;8;9;8;8;9
17
+ 3;2;3;2;2;3;2;1;3;2;1;2;0;3;2;3;3;2;3;2
18
+ 3;2;3;2;2;3;2;4;3;2;3;2;0;3;2;3;3;2;3;2
19
+ 7;6;7;7;6;7;7;7;10;10;7;7;10;10;7;7;7;6;7;7
20
+ 7;6;7;7;6;7;1;7;7;6;7;8;6;7;7;7;7;6;7;7
21
+ 9;8;9;8;8;9;8;9;9;8;9;8;8;9;8;9;9;8;9;8
22
+ 5;4;4;4;4;5;6;4;9;4;4;6;4;5;6;4;5;4;4;4
23
+ 5;4;5;4;4;5;4;5;9;4;5;4;4;5;4;5;5;4;5;4
24
+ 5;4;5;4;4;5;4;5;5;4;5;4;4;5;4;5;5;4;5;4
25
+ 3;2;3;3;2;3;3;1;3;2;1;3;2;3;3;3;3;2;3;3
26
+ 9;8;9;8;8;9;8;9;9;8;9;8;8;9;8;9;9;8;9;8
27
+ 9;8;9;8;8;9;8;9;9;8;9;8;8;9;8;9;9;8;9;8
28
+ 9;8;9;9;8;9;2;9;9;8;9;7;8;9;9;9;9;8;9;9
29
+ 5;4;5;5;4;5;5;6;10;10;5;5;10;10;5;5;5;4;5;5
30
+ 7;6;6;6;6;7;5;6;7;6;6;5;6;7;6;6;7;6;6;6
31
+ 7;6;7;6;6;7;5;10;7;6;10;5;6;7;6;10;7;6;7;6
32
+ 7;6;7;6;6;7;10;7;7;6;7;10;6;7;10;7;7;6;7;6
33
+ 3;2;2;2;2;3;6;2;5;2;2;6;0;3;5;2;3;2;2;2
34
+ 3;2;2;2;2;3;6;2;5;2;2;6;0;3;5;2;3;2;2;2
35
+ 9;8;9;8;8;9;8;9;9;8;9;8;8;9;8;9;9;8;9;8
36
+ 1;0;0;1;0;1;8;0;10;10;0;1;10;10;1;0;1;0;0;1
37
+ 5;4;5;4;4;5;4;6;5;4;5;4;4;5;4;5;5;4;5;4
38
+ 7;6;7;7;6;7;2;7;7;6;7;7;6;7;7;7;7;6;7;7
39
+ 9;8;9;9;8;9;9;8;9;8;8;9;8;9;9;9;9;8;9;9
40
+ 9;8;9;8;8;9;7;8;9;8;8;7;8;9;8;9;9;8;9;8
41
+ 5;4;5;5;4;5;7;10;3;4;10;2;4;5;2;10;5;4;5;5
42
+ 5;4;4;5;4;5;2;4;3;4;4;2;4;5;2;4;5;4;4;5
43
+ 1;0;1;0;0;1;9;1;1;0;1;0;2;1;0;1;1;0;1;0
44
+ 1;0;1;0;0;1;0;3;1;0;3;0;2;1;0;1;1;0;1;0
45
+ 7;6;6;6;6;7;6;6;7;6;6;6;6;7;6;6;7;6;6;6
46
+ 7;6;6;7;6;7;9;6;7;6;6;9;6;7;7;6;7;6;6;7
47
+ 9;8;8;8;8;9;8;9;9;8;9;8;8;9;8;8;9;8;8;8
48
+ 9;8;8;8;8;9;8;9;9;8;9;8;8;9;8;8;9;8;8;8
49
+ 3;2;3;3;2;3;3;3;10;10;3;3;10;10;3;3;3;2;3;3
50
+ 5;4;4;4;4;5;4;4;5;4;4;4;4;5;4;4;5;4;4;4
51
+ 7;6;7;6;6;7;6;7;1;6;7;6;8;7;6;7;7;6;7;6
52
+ 7;6;7;7;6;7;1;7;1;6;7;8;8;7;7;7;7;6;7;7
@@ -0,0 +1,10 @@
1
+ export enum GameRoundType {
2
+ BASE = 'BASE',
3
+ BONUS = 'BONUS',
4
+ }
5
+
6
+ export type BonusProgress = {
7
+ completed: number;
8
+ remaining: number;
9
+ total: number;
10
+ };
@@ -0,0 +1,16 @@
1
+ import { Reel } from '../reel';
2
+ import { ReelStripOption } from '../reel-strip-option';
3
+ import { ReelStripsConfig } from '../reel-strips-config';
4
+
5
+ export class ReelStripsConfigMapper {
6
+ public mapRawToDomain(rawReels: number[][][]): ReelStripsConfig {
7
+ const reels: Reel[] = rawReels.map((reelOptions) => {
8
+ const options: ReelStripOption[] = reelOptions.map(
9
+ (symbols) => new ReelStripOption(symbols),
10
+ );
11
+ return new Reel(options);
12
+ });
13
+
14
+ return new ReelStripsConfig(reels);
15
+ }
16
+ }
@@ -0,0 +1,15 @@
1
+ export class ReelStripOption {
2
+ constructor(public readonly symbols: number[]) {}
3
+
4
+ public getSymbols(): number[] {
5
+ return this.symbols;
6
+ }
7
+
8
+ public get length(): number {
9
+ return this.symbols.length;
10
+ }
11
+
12
+ public getSymbolAt(position: number): number {
13
+ return this.symbols[position % this.length];
14
+ }
15
+ }
@@ -0,0 +1,21 @@
1
+ import { Reel } from './reel';
2
+
3
+ export class ReelStripsConfig {
4
+ constructor(public readonly reels: Reel[]) {}
5
+
6
+ public getReels(): Reel[] {
7
+ return this.reels;
8
+ }
9
+
10
+ public getReel(index: number): Reel {
11
+ return this.reels[index];
12
+ }
13
+
14
+ public get reelsCount(): number {
15
+ return this.reels.length;
16
+ }
17
+
18
+ public get optionsCount(): number {
19
+ return this.reels[0]?.numberOfOptions ?? 0;
20
+ }
21
+ }
@@ -0,0 +1,17 @@
1
+ import { ReelStripOption } from './reel-strip-option';
2
+
3
+ export class Reel {
4
+ constructor(public readonly options: ReelStripOption[]) {}
5
+
6
+ public getOptions(): ReelStripOption[] {
7
+ return this.options;
8
+ }
9
+
10
+ public getOption(index: number): ReelStripOption {
11
+ return this.options[index];
12
+ }
13
+
14
+ public get numberOfOptions(): number {
15
+ return this.options.length;
16
+ }
17
+ }
@@ -0,0 +1,5 @@
1
+ export type CheatTriggerBonusCommand = {
2
+ sessionId: string;
3
+ bonusType: string;
4
+ betAmount: number;
5
+ };
@@ -0,0 +1,5 @@
1
+ export interface CheatTriggerBonusRequestDto {
2
+ sessionId: string;
3
+ bonusType: string;
4
+ betAmount: number;
5
+ }
@@ -0,0 +1,6 @@
1
+
2
+ export type CheatUpdateBonusMeterProgressCommand = {
3
+ sessionId: string;
4
+ bonusType: string;
5
+ progress: number;
6
+ };
@@ -0,0 +1,5 @@
1
+ export interface CheatUpdateBonusMeterProgressRequestDto {
2
+ sessionId: string;
3
+ bonusType: string;
4
+ progress: number;
5
+ }