@slot-engine/core 0.1.4 → 0.1.6
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/dist/index.d.mts +98 -64
- package/dist/index.d.ts +98 -64
- package/dist/index.js +69 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -365,6 +365,70 @@ interface GameSymbolOpts {
|
|
|
365
365
|
properties?: Record<string, any>;
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
+
declare class WinType {
|
|
369
|
+
protected payout: number;
|
|
370
|
+
protected winCombinations: WinCombination[];
|
|
371
|
+
protected ctx: GameContext;
|
|
372
|
+
protected readonly wildSymbol?: WildSymbol;
|
|
373
|
+
constructor(opts: WinTypeOpts);
|
|
374
|
+
/**
|
|
375
|
+
* Implementation of win evaluation logic. Sets `this.payout` and `this.winCombinations`.
|
|
376
|
+
*/
|
|
377
|
+
evaluateWins(board: Reels): this;
|
|
378
|
+
/**
|
|
379
|
+
* Custom post-processing of wins, e.g. for handling multipliers.
|
|
380
|
+
*/
|
|
381
|
+
postProcess(func: PostProcessFn<typeof this.winCombinations>): this;
|
|
382
|
+
/**
|
|
383
|
+
* Returns the total payout and detailed win combinations.
|
|
384
|
+
*/
|
|
385
|
+
getWins(): {
|
|
386
|
+
payout: number;
|
|
387
|
+
winCombinations: WinCombination[];
|
|
388
|
+
};
|
|
389
|
+
protected isWild(symbol: GameSymbol): boolean;
|
|
390
|
+
protected getSymbolPayout(symbol: GameSymbol, count: number): number;
|
|
391
|
+
}
|
|
392
|
+
interface WinTypeOpts {
|
|
393
|
+
/**
|
|
394
|
+
* A reference to the game context.
|
|
395
|
+
*/
|
|
396
|
+
ctx: GameContext<any, any, any>;
|
|
397
|
+
/**
|
|
398
|
+
* Configuration used to identify wild symbols on the board.\
|
|
399
|
+
* You can either provide a specific `GameSymbol` instance or a set of properties to match against symbols on the board.
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* If you have different wild symbols, each with a property `isWild: true`, you can define:
|
|
403
|
+
* ```ts
|
|
404
|
+
* wildSymbol: { isWild: true }
|
|
405
|
+
* ```
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* If you have a single wild symbol instance, you can define:
|
|
409
|
+
* ```ts
|
|
410
|
+
* wildSymbol: myWildSymbol
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
wildSymbol?: WildSymbol;
|
|
414
|
+
}
|
|
415
|
+
type WinCombination = {
|
|
416
|
+
payout: number;
|
|
417
|
+
kind: number;
|
|
418
|
+
baseSymbol: GameSymbol;
|
|
419
|
+
symbols: Array<{
|
|
420
|
+
symbol: GameSymbol;
|
|
421
|
+
isWild: boolean;
|
|
422
|
+
substitutedFor?: GameSymbol;
|
|
423
|
+
reelIndex: number;
|
|
424
|
+
posIndex: number;
|
|
425
|
+
}>;
|
|
426
|
+
};
|
|
427
|
+
type PostProcessFn<TWinCombs extends WinCombination[]> = (wins: TWinCombs, ctx: GameContext) => {
|
|
428
|
+
winCombinations: TWinCombs;
|
|
429
|
+
};
|
|
430
|
+
type WildSymbol = GameSymbol | Record<string, any>;
|
|
431
|
+
|
|
368
432
|
declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymbols extends AnySymbols = AnySymbols, TUserState extends AnyUserData = AnyUserData> extends AbstractService {
|
|
369
433
|
private board;
|
|
370
434
|
constructor(ctx: () => GameContext<TGameModes, TSymbols, TUserState>);
|
|
@@ -454,6 +518,17 @@ declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymb
|
|
|
454
518
|
newBoardSymbols: Record<string, GameSymbol[]>;
|
|
455
519
|
newPaddingTopSymbols: Record<string, GameSymbol[]>;
|
|
456
520
|
};
|
|
521
|
+
/**
|
|
522
|
+
* Dedupes win symbols for tumble.\
|
|
523
|
+
* Returns a list of symbols to remove from the board based on the given win combinations.
|
|
524
|
+
*
|
|
525
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
526
|
+
* this method ensures that each symbol is only listed once for removal. Otherwise tumbling may break.
|
|
527
|
+
*/
|
|
528
|
+
dedupeWinSymbolsForTumble(winCombinations: WinCombination[]): {
|
|
529
|
+
reelIdx: number;
|
|
530
|
+
rowIdx: number;
|
|
531
|
+
}[];
|
|
457
532
|
}
|
|
458
533
|
|
|
459
534
|
declare class Recorder {
|
|
@@ -736,6 +811,18 @@ declare class GameService<TGameModes extends AnyGameModes = AnyGameModes, TSymbo
|
|
|
736
811
|
* Also sets `state.triggeredFreespins` to true.
|
|
737
812
|
*/
|
|
738
813
|
awardFreespins(amount: number): void;
|
|
814
|
+
/**
|
|
815
|
+
* Dedupes win symbols.
|
|
816
|
+
*
|
|
817
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
818
|
+
* this method ensures that each symbol is only listed once.
|
|
819
|
+
*
|
|
820
|
+
* If you want to tumble based on winning symbols, run them through this method first.
|
|
821
|
+
*/
|
|
822
|
+
dedupeWinSymbols(winCombinations: WinCombination[]): {
|
|
823
|
+
reelIdx: number;
|
|
824
|
+
rowIdx: number;
|
|
825
|
+
}[];
|
|
739
826
|
}
|
|
740
827
|
|
|
741
828
|
declare class Wallet {
|
|
@@ -1180,70 +1267,6 @@ declare const defineUserState: <TUserState extends AnyUserData>(data: TUserState
|
|
|
1180
1267
|
declare const defineSymbols: <TSymbols extends AnySymbols>(symbols: TSymbols) => TSymbols;
|
|
1181
1268
|
declare const defineGameModes: <TGameModes extends AnyGameModes>(gameModes: TGameModes) => TGameModes;
|
|
1182
1269
|
|
|
1183
|
-
declare class WinType {
|
|
1184
|
-
protected payout: number;
|
|
1185
|
-
protected winCombinations: WinCombination[];
|
|
1186
|
-
protected ctx: GameContext;
|
|
1187
|
-
protected readonly wildSymbol?: WildSymbol;
|
|
1188
|
-
constructor(opts: WinTypeOpts);
|
|
1189
|
-
/**
|
|
1190
|
-
* Implementation of win evaluation logic. Sets `this.payout` and `this.winCombinations`.
|
|
1191
|
-
*/
|
|
1192
|
-
evaluateWins(board: Reels): this;
|
|
1193
|
-
/**
|
|
1194
|
-
* Custom post-processing of wins, e.g. for handling multipliers.
|
|
1195
|
-
*/
|
|
1196
|
-
postProcess(func: PostProcessFn<typeof this.winCombinations>): this;
|
|
1197
|
-
/**
|
|
1198
|
-
* Returns the total payout and detailed win combinations.
|
|
1199
|
-
*/
|
|
1200
|
-
getWins(): {
|
|
1201
|
-
payout: number;
|
|
1202
|
-
winCombinations: WinCombination[];
|
|
1203
|
-
};
|
|
1204
|
-
protected isWild(symbol: GameSymbol): boolean;
|
|
1205
|
-
protected getSymbolPayout(symbol: GameSymbol, count: number): number;
|
|
1206
|
-
}
|
|
1207
|
-
interface WinTypeOpts {
|
|
1208
|
-
/**
|
|
1209
|
-
* A reference to the game context.
|
|
1210
|
-
*/
|
|
1211
|
-
ctx: GameContext<any, any, any>;
|
|
1212
|
-
/**
|
|
1213
|
-
* Configuration used to identify wild symbols on the board.\
|
|
1214
|
-
* You can either provide a specific `GameSymbol` instance or a set of properties to match against symbols on the board.
|
|
1215
|
-
*
|
|
1216
|
-
* @example
|
|
1217
|
-
* If you have different wild symbols, each with a property `isWild: true`, you can define:
|
|
1218
|
-
* ```ts
|
|
1219
|
-
* wildSymbol: { isWild: true }
|
|
1220
|
-
* ```
|
|
1221
|
-
*
|
|
1222
|
-
* @example
|
|
1223
|
-
* If you have a single wild symbol instance, you can define:
|
|
1224
|
-
* ```ts
|
|
1225
|
-
* wildSymbol: myWildSymbol
|
|
1226
|
-
* ```
|
|
1227
|
-
*/
|
|
1228
|
-
wildSymbol?: WildSymbol;
|
|
1229
|
-
}
|
|
1230
|
-
type WinCombination = {
|
|
1231
|
-
payout: number;
|
|
1232
|
-
kind: number;
|
|
1233
|
-
baseSymbol: GameSymbol;
|
|
1234
|
-
symbols: Array<{
|
|
1235
|
-
symbol: GameSymbol;
|
|
1236
|
-
isWild: boolean;
|
|
1237
|
-
substitutedFor?: GameSymbol;
|
|
1238
|
-
reelIndex: number;
|
|
1239
|
-
posIndex: number;
|
|
1240
|
-
}>;
|
|
1241
|
-
};
|
|
1242
|
-
type PostProcessFn<TWinCombs extends WinCombination[]> = (wins: TWinCombs, ctx: GameContext) => {
|
|
1243
|
-
winCombinations: TWinCombs;
|
|
1244
|
-
};
|
|
1245
|
-
type WildSymbol = GameSymbol | Record<string, any>;
|
|
1246
|
-
|
|
1247
1270
|
declare class LinesWinType extends WinType {
|
|
1248
1271
|
protected lines: Record<number, number[]>;
|
|
1249
1272
|
protected winCombinations: LineWinCombination[];
|
|
@@ -1571,6 +1594,17 @@ declare class StandaloneBoard {
|
|
|
1571
1594
|
newBoardSymbols: Record<string, GameSymbol[]>;
|
|
1572
1595
|
newPaddingTopSymbols: Record<string, GameSymbol[]>;
|
|
1573
1596
|
};
|
|
1597
|
+
/**
|
|
1598
|
+
* Dedupes win symbols for tumble.\
|
|
1599
|
+
* Returns a list of symbols to remove from the board based on the given win combinations.
|
|
1600
|
+
*
|
|
1601
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
1602
|
+
* this method ensures that each symbol is only listed once for removal. Otherwise tumbling may break.
|
|
1603
|
+
*/
|
|
1604
|
+
dedupeWinSymbolsForTumble(winCombinations: WinCombination[]): {
|
|
1605
|
+
reelIdx: number;
|
|
1606
|
+
rowIdx: number;
|
|
1607
|
+
}[];
|
|
1574
1608
|
}
|
|
1575
1609
|
interface StandaloneBoardOptions {
|
|
1576
1610
|
ctx: GameContext;
|
package/dist/index.d.ts
CHANGED
|
@@ -365,6 +365,70 @@ interface GameSymbolOpts {
|
|
|
365
365
|
properties?: Record<string, any>;
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
+
declare class WinType {
|
|
369
|
+
protected payout: number;
|
|
370
|
+
protected winCombinations: WinCombination[];
|
|
371
|
+
protected ctx: GameContext;
|
|
372
|
+
protected readonly wildSymbol?: WildSymbol;
|
|
373
|
+
constructor(opts: WinTypeOpts);
|
|
374
|
+
/**
|
|
375
|
+
* Implementation of win evaluation logic. Sets `this.payout` and `this.winCombinations`.
|
|
376
|
+
*/
|
|
377
|
+
evaluateWins(board: Reels): this;
|
|
378
|
+
/**
|
|
379
|
+
* Custom post-processing of wins, e.g. for handling multipliers.
|
|
380
|
+
*/
|
|
381
|
+
postProcess(func: PostProcessFn<typeof this.winCombinations>): this;
|
|
382
|
+
/**
|
|
383
|
+
* Returns the total payout and detailed win combinations.
|
|
384
|
+
*/
|
|
385
|
+
getWins(): {
|
|
386
|
+
payout: number;
|
|
387
|
+
winCombinations: WinCombination[];
|
|
388
|
+
};
|
|
389
|
+
protected isWild(symbol: GameSymbol): boolean;
|
|
390
|
+
protected getSymbolPayout(symbol: GameSymbol, count: number): number;
|
|
391
|
+
}
|
|
392
|
+
interface WinTypeOpts {
|
|
393
|
+
/**
|
|
394
|
+
* A reference to the game context.
|
|
395
|
+
*/
|
|
396
|
+
ctx: GameContext<any, any, any>;
|
|
397
|
+
/**
|
|
398
|
+
* Configuration used to identify wild symbols on the board.\
|
|
399
|
+
* You can either provide a specific `GameSymbol` instance or a set of properties to match against symbols on the board.
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* If you have different wild symbols, each with a property `isWild: true`, you can define:
|
|
403
|
+
* ```ts
|
|
404
|
+
* wildSymbol: { isWild: true }
|
|
405
|
+
* ```
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* If you have a single wild symbol instance, you can define:
|
|
409
|
+
* ```ts
|
|
410
|
+
* wildSymbol: myWildSymbol
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
wildSymbol?: WildSymbol;
|
|
414
|
+
}
|
|
415
|
+
type WinCombination = {
|
|
416
|
+
payout: number;
|
|
417
|
+
kind: number;
|
|
418
|
+
baseSymbol: GameSymbol;
|
|
419
|
+
symbols: Array<{
|
|
420
|
+
symbol: GameSymbol;
|
|
421
|
+
isWild: boolean;
|
|
422
|
+
substitutedFor?: GameSymbol;
|
|
423
|
+
reelIndex: number;
|
|
424
|
+
posIndex: number;
|
|
425
|
+
}>;
|
|
426
|
+
};
|
|
427
|
+
type PostProcessFn<TWinCombs extends WinCombination[]> = (wins: TWinCombs, ctx: GameContext) => {
|
|
428
|
+
winCombinations: TWinCombs;
|
|
429
|
+
};
|
|
430
|
+
type WildSymbol = GameSymbol | Record<string, any>;
|
|
431
|
+
|
|
368
432
|
declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymbols extends AnySymbols = AnySymbols, TUserState extends AnyUserData = AnyUserData> extends AbstractService {
|
|
369
433
|
private board;
|
|
370
434
|
constructor(ctx: () => GameContext<TGameModes, TSymbols, TUserState>);
|
|
@@ -454,6 +518,17 @@ declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymb
|
|
|
454
518
|
newBoardSymbols: Record<string, GameSymbol[]>;
|
|
455
519
|
newPaddingTopSymbols: Record<string, GameSymbol[]>;
|
|
456
520
|
};
|
|
521
|
+
/**
|
|
522
|
+
* Dedupes win symbols for tumble.\
|
|
523
|
+
* Returns a list of symbols to remove from the board based on the given win combinations.
|
|
524
|
+
*
|
|
525
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
526
|
+
* this method ensures that each symbol is only listed once for removal. Otherwise tumbling may break.
|
|
527
|
+
*/
|
|
528
|
+
dedupeWinSymbolsForTumble(winCombinations: WinCombination[]): {
|
|
529
|
+
reelIdx: number;
|
|
530
|
+
rowIdx: number;
|
|
531
|
+
}[];
|
|
457
532
|
}
|
|
458
533
|
|
|
459
534
|
declare class Recorder {
|
|
@@ -736,6 +811,18 @@ declare class GameService<TGameModes extends AnyGameModes = AnyGameModes, TSymbo
|
|
|
736
811
|
* Also sets `state.triggeredFreespins` to true.
|
|
737
812
|
*/
|
|
738
813
|
awardFreespins(amount: number): void;
|
|
814
|
+
/**
|
|
815
|
+
* Dedupes win symbols.
|
|
816
|
+
*
|
|
817
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
818
|
+
* this method ensures that each symbol is only listed once.
|
|
819
|
+
*
|
|
820
|
+
* If you want to tumble based on winning symbols, run them through this method first.
|
|
821
|
+
*/
|
|
822
|
+
dedupeWinSymbols(winCombinations: WinCombination[]): {
|
|
823
|
+
reelIdx: number;
|
|
824
|
+
rowIdx: number;
|
|
825
|
+
}[];
|
|
739
826
|
}
|
|
740
827
|
|
|
741
828
|
declare class Wallet {
|
|
@@ -1180,70 +1267,6 @@ declare const defineUserState: <TUserState extends AnyUserData>(data: TUserState
|
|
|
1180
1267
|
declare const defineSymbols: <TSymbols extends AnySymbols>(symbols: TSymbols) => TSymbols;
|
|
1181
1268
|
declare const defineGameModes: <TGameModes extends AnyGameModes>(gameModes: TGameModes) => TGameModes;
|
|
1182
1269
|
|
|
1183
|
-
declare class WinType {
|
|
1184
|
-
protected payout: number;
|
|
1185
|
-
protected winCombinations: WinCombination[];
|
|
1186
|
-
protected ctx: GameContext;
|
|
1187
|
-
protected readonly wildSymbol?: WildSymbol;
|
|
1188
|
-
constructor(opts: WinTypeOpts);
|
|
1189
|
-
/**
|
|
1190
|
-
* Implementation of win evaluation logic. Sets `this.payout` and `this.winCombinations`.
|
|
1191
|
-
*/
|
|
1192
|
-
evaluateWins(board: Reels): this;
|
|
1193
|
-
/**
|
|
1194
|
-
* Custom post-processing of wins, e.g. for handling multipliers.
|
|
1195
|
-
*/
|
|
1196
|
-
postProcess(func: PostProcessFn<typeof this.winCombinations>): this;
|
|
1197
|
-
/**
|
|
1198
|
-
* Returns the total payout and detailed win combinations.
|
|
1199
|
-
*/
|
|
1200
|
-
getWins(): {
|
|
1201
|
-
payout: number;
|
|
1202
|
-
winCombinations: WinCombination[];
|
|
1203
|
-
};
|
|
1204
|
-
protected isWild(symbol: GameSymbol): boolean;
|
|
1205
|
-
protected getSymbolPayout(symbol: GameSymbol, count: number): number;
|
|
1206
|
-
}
|
|
1207
|
-
interface WinTypeOpts {
|
|
1208
|
-
/**
|
|
1209
|
-
* A reference to the game context.
|
|
1210
|
-
*/
|
|
1211
|
-
ctx: GameContext<any, any, any>;
|
|
1212
|
-
/**
|
|
1213
|
-
* Configuration used to identify wild symbols on the board.\
|
|
1214
|
-
* You can either provide a specific `GameSymbol` instance or a set of properties to match against symbols on the board.
|
|
1215
|
-
*
|
|
1216
|
-
* @example
|
|
1217
|
-
* If you have different wild symbols, each with a property `isWild: true`, you can define:
|
|
1218
|
-
* ```ts
|
|
1219
|
-
* wildSymbol: { isWild: true }
|
|
1220
|
-
* ```
|
|
1221
|
-
*
|
|
1222
|
-
* @example
|
|
1223
|
-
* If you have a single wild symbol instance, you can define:
|
|
1224
|
-
* ```ts
|
|
1225
|
-
* wildSymbol: myWildSymbol
|
|
1226
|
-
* ```
|
|
1227
|
-
*/
|
|
1228
|
-
wildSymbol?: WildSymbol;
|
|
1229
|
-
}
|
|
1230
|
-
type WinCombination = {
|
|
1231
|
-
payout: number;
|
|
1232
|
-
kind: number;
|
|
1233
|
-
baseSymbol: GameSymbol;
|
|
1234
|
-
symbols: Array<{
|
|
1235
|
-
symbol: GameSymbol;
|
|
1236
|
-
isWild: boolean;
|
|
1237
|
-
substitutedFor?: GameSymbol;
|
|
1238
|
-
reelIndex: number;
|
|
1239
|
-
posIndex: number;
|
|
1240
|
-
}>;
|
|
1241
|
-
};
|
|
1242
|
-
type PostProcessFn<TWinCombs extends WinCombination[]> = (wins: TWinCombs, ctx: GameContext) => {
|
|
1243
|
-
winCombinations: TWinCombs;
|
|
1244
|
-
};
|
|
1245
|
-
type WildSymbol = GameSymbol | Record<string, any>;
|
|
1246
|
-
|
|
1247
1270
|
declare class LinesWinType extends WinType {
|
|
1248
1271
|
protected lines: Record<number, number[]>;
|
|
1249
1272
|
protected winCombinations: LineWinCombination[];
|
|
@@ -1571,6 +1594,17 @@ declare class StandaloneBoard {
|
|
|
1571
1594
|
newBoardSymbols: Record<string, GameSymbol[]>;
|
|
1572
1595
|
newPaddingTopSymbols: Record<string, GameSymbol[]>;
|
|
1573
1596
|
};
|
|
1597
|
+
/**
|
|
1598
|
+
* Dedupes win symbols for tumble.\
|
|
1599
|
+
* Returns a list of symbols to remove from the board based on the given win combinations.
|
|
1600
|
+
*
|
|
1601
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
1602
|
+
* this method ensures that each symbol is only listed once for removal. Otherwise tumbling may break.
|
|
1603
|
+
*/
|
|
1604
|
+
dedupeWinSymbolsForTumble(winCombinations: WinCombination[]): {
|
|
1605
|
+
reelIdx: number;
|
|
1606
|
+
rowIdx: number;
|
|
1607
|
+
}[];
|
|
1574
1608
|
}
|
|
1575
1609
|
interface StandaloneBoardOptions {
|
|
1576
1610
|
ctx: GameContext;
|
package/dist/index.js
CHANGED
|
@@ -697,14 +697,15 @@ var Board = class {
|
|
|
697
697
|
this.lastUsedReels = opts.reels;
|
|
698
698
|
for (let ridx = 0; ridx < reelsAmount; ridx++) {
|
|
699
699
|
const reelPos = finalReelStops[ridx];
|
|
700
|
+
const reelLength = opts.reels[ridx].length;
|
|
700
701
|
for (let p = padSymbols - 1; p >= 0; p--) {
|
|
701
|
-
const topPos = (reelPos - (p + 1)) %
|
|
702
|
+
const topPos = ((reelPos - (p + 1)) % reelLength + reelLength) % reelLength;
|
|
702
703
|
this.paddingTop[ridx].push(opts.reels[ridx][topPos]);
|
|
703
|
-
const bottomPos = (reelPos + symbolsPerReel[ridx] + p) %
|
|
704
|
+
const bottomPos = (reelPos + symbolsPerReel[ridx] + p) % reelLength;
|
|
704
705
|
this.paddingBottom[ridx].unshift(opts.reels[ridx][bottomPos]);
|
|
705
706
|
}
|
|
706
707
|
for (let row = 0; row < symbolsPerReel[ridx]; row++) {
|
|
707
|
-
const symbol = opts.reels[ridx][(reelPos + row) %
|
|
708
|
+
const symbol = opts.reels[ridx][(reelPos + row) % reelLength];
|
|
708
709
|
if (!symbol) {
|
|
709
710
|
throw new Error(`Failed to get symbol at pos ${reelPos + row} on reel ${ridx}`);
|
|
710
711
|
}
|
|
@@ -772,11 +773,27 @@ var Board = class {
|
|
|
772
773
|
newPaddingTopSymbols[ridx].unshift(padSymbol);
|
|
773
774
|
}
|
|
774
775
|
}
|
|
776
|
+
this.lastDrawnReelStops = this.lastDrawnReelStops.map((stop, ridx) => {
|
|
777
|
+
return newFirstSymbolPositions[ridx] ?? stop;
|
|
778
|
+
});
|
|
775
779
|
return {
|
|
776
780
|
newBoardSymbols,
|
|
777
781
|
newPaddingTopSymbols
|
|
778
782
|
};
|
|
779
783
|
}
|
|
784
|
+
dedupeWinSymbolsForTumble(winCombinations) {
|
|
785
|
+
const symbolsMap = /* @__PURE__ */ new Map();
|
|
786
|
+
winCombinations.forEach((wc) => {
|
|
787
|
+
wc.symbols.forEach((s) => {
|
|
788
|
+
symbolsMap.set(`${s.reelIndex},${s.posIndex}`, {
|
|
789
|
+
reelIdx: s.reelIndex,
|
|
790
|
+
rowIdx: s.posIndex
|
|
791
|
+
});
|
|
792
|
+
});
|
|
793
|
+
});
|
|
794
|
+
const symbolsToRemove = Array.from(symbolsMap.values());
|
|
795
|
+
return symbolsToRemove;
|
|
796
|
+
}
|
|
780
797
|
};
|
|
781
798
|
|
|
782
799
|
// src/service/board.ts
|
|
@@ -921,6 +938,16 @@ var BoardService = class extends AbstractService {
|
|
|
921
938
|
symbolsToDelete
|
|
922
939
|
});
|
|
923
940
|
}
|
|
941
|
+
/**
|
|
942
|
+
* Dedupes win symbols for tumble.\
|
|
943
|
+
* Returns a list of symbols to remove from the board based on the given win combinations.
|
|
944
|
+
*
|
|
945
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
946
|
+
* this method ensures that each symbol is only listed once for removal. Otherwise tumbling may break.
|
|
947
|
+
*/
|
|
948
|
+
dedupeWinSymbolsForTumble(winCombinations) {
|
|
949
|
+
return this.board.dedupeWinSymbolsForTumble(winCombinations);
|
|
950
|
+
}
|
|
924
951
|
};
|
|
925
952
|
|
|
926
953
|
// src/service/data.ts
|
|
@@ -1117,6 +1144,27 @@ var GameService = class extends AbstractService {
|
|
|
1117
1144
|
this.ctx().state.totalFreespinAmount += amount;
|
|
1118
1145
|
this.ctx().state.triggeredFreespins = true;
|
|
1119
1146
|
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Dedupes win symbols.
|
|
1149
|
+
*
|
|
1150
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
1151
|
+
* this method ensures that each symbol is only listed once.
|
|
1152
|
+
*
|
|
1153
|
+
* If you want to tumble based on winning symbols, run them through this method first.
|
|
1154
|
+
*/
|
|
1155
|
+
dedupeWinSymbols(winCombinations) {
|
|
1156
|
+
const symbolsMap = /* @__PURE__ */ new Map();
|
|
1157
|
+
winCombinations.forEach((wc) => {
|
|
1158
|
+
wc.symbols.forEach((s) => {
|
|
1159
|
+
symbolsMap.set(`${s.reelIndex},${s.posIndex}`, {
|
|
1160
|
+
reelIdx: s.reelIndex,
|
|
1161
|
+
rowIdx: s.posIndex
|
|
1162
|
+
});
|
|
1163
|
+
});
|
|
1164
|
+
});
|
|
1165
|
+
const symbolsToRemove = Array.from(symbolsMap.values());
|
|
1166
|
+
return symbolsToRemove;
|
|
1167
|
+
}
|
|
1120
1168
|
};
|
|
1121
1169
|
|
|
1122
1170
|
// src/service/wallet.ts
|
|
@@ -1731,7 +1779,12 @@ Simulating game mode: ${mode}`);
|
|
|
1731
1779
|
}
|
|
1732
1780
|
});
|
|
1733
1781
|
worker.on("error", (error) => {
|
|
1734
|
-
|
|
1782
|
+
process.stdout.write(`
|
|
1783
|
+
${error.message}
|
|
1784
|
+
`);
|
|
1785
|
+
process.stdout.write(`
|
|
1786
|
+
${error.stack}
|
|
1787
|
+
`);
|
|
1735
1788
|
reject(error);
|
|
1736
1789
|
});
|
|
1737
1790
|
worker.on("exit", (code) => {
|
|
@@ -2293,28 +2346,12 @@ var Analysis = class {
|
|
|
2293
2346
|
const payoutRanges = {};
|
|
2294
2347
|
for (const modeStr of gameModes) {
|
|
2295
2348
|
payoutRanges[modeStr] = { overall: {}, criteria: {} };
|
|
2296
|
-
const lutOptimized = parseLookupTable(
|
|
2297
|
-
import_fs3.default.readFileSync(this.filePaths[modeStr].lutOptimized, "utf-8")
|
|
2298
|
-
);
|
|
2299
2349
|
const lutSegmented = parseLookupTableSegmented(
|
|
2300
2350
|
import_fs3.default.readFileSync(this.filePaths[modeStr].lutSegmented, "utf-8")
|
|
2301
2351
|
);
|
|
2302
|
-
lutOptimized.forEach(([, , p]) => {
|
|
2303
|
-
const payout = p / 100;
|
|
2304
|
-
for (const [min, max] of winRanges) {
|
|
2305
|
-
if (payout >= min && payout <= max) {
|
|
2306
|
-
const rangeKey = `${min}-${max}`;
|
|
2307
|
-
if (!payoutRanges[modeStr].overall[rangeKey]) {
|
|
2308
|
-
payoutRanges[modeStr].overall[rangeKey] = 0;
|
|
2309
|
-
}
|
|
2310
|
-
payoutRanges[modeStr].overall[rangeKey] += 1;
|
|
2311
|
-
break;
|
|
2312
|
-
}
|
|
2313
|
-
}
|
|
2314
|
-
});
|
|
2315
2352
|
lutSegmented.forEach(([, criteria, bp, fsp]) => {
|
|
2316
|
-
const basePayout = bp
|
|
2317
|
-
const freeSpinPayout = fsp
|
|
2353
|
+
const basePayout = bp;
|
|
2354
|
+
const freeSpinPayout = fsp;
|
|
2318
2355
|
const payout = basePayout + freeSpinPayout;
|
|
2319
2356
|
for (const [min, max] of winRanges) {
|
|
2320
2357
|
if (payout >= min && payout <= max) {
|
|
@@ -3771,6 +3808,16 @@ var StandaloneBoard = class {
|
|
|
3771
3808
|
padSymbols: this.padSymbols
|
|
3772
3809
|
});
|
|
3773
3810
|
}
|
|
3811
|
+
/**
|
|
3812
|
+
* Dedupes win symbols for tumble.\
|
|
3813
|
+
* Returns a list of symbols to remove from the board based on the given win combinations.
|
|
3814
|
+
*
|
|
3815
|
+
* Since it may be possible that multiple win combinations include the same symbol (e.g. Wilds),\
|
|
3816
|
+
* this method ensures that each symbol is only listed once for removal. Otherwise tumbling may break.
|
|
3817
|
+
*/
|
|
3818
|
+
dedupeWinSymbolsForTumble(winCombinations) {
|
|
3819
|
+
return this.board.dedupeWinSymbolsForTumble(winCombinations);
|
|
3820
|
+
}
|
|
3774
3821
|
};
|
|
3775
3822
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3776
3823
|
0 && (module.exports = {
|