@slot-engine/core 0.2.0 → 0.2.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.
- package/dist/index.d.mts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +109 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +109 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -50,6 +50,7 @@ type PermanentFilePaths = {
|
|
|
50
50
|
booksIndexMeta: (mode: string) => string;
|
|
51
51
|
booksChunk: (mode: string, worker: number, chunk: number) => string;
|
|
52
52
|
booksCompressed: (mode: string) => string;
|
|
53
|
+
booksUncompressed: (mode: string) => string;
|
|
53
54
|
lookupTable: (mode: string) => string;
|
|
54
55
|
lookupTableIndex: (mode: string) => string;
|
|
55
56
|
lookupTableSegmented: (mode: string) => string;
|
|
@@ -175,6 +176,7 @@ declare class Simulation {
|
|
|
175
176
|
readonly gameConfig: GameConfig & GameMetadata;
|
|
176
177
|
readonly simRunsAmount: Partial<Record<string, number>>;
|
|
177
178
|
readonly concurrency: number;
|
|
179
|
+
readonly makeUncompressedBooks: boolean;
|
|
178
180
|
private debug;
|
|
179
181
|
private actualSims;
|
|
180
182
|
private wallet;
|
|
@@ -265,6 +267,7 @@ declare class Simulation {
|
|
|
265
267
|
*/
|
|
266
268
|
confirmRecords(ctx: GameContext): void;
|
|
267
269
|
printSimulationSummary(): Promise<void>;
|
|
270
|
+
private sendSimulationStatus;
|
|
268
271
|
}
|
|
269
272
|
type SimulationOptions = {
|
|
270
273
|
/**
|
|
@@ -293,6 +296,10 @@ type SimulationOptions = {
|
|
|
293
296
|
* Default: 50
|
|
294
297
|
*/
|
|
295
298
|
maxDiskBuffer?: number;
|
|
299
|
+
/**
|
|
300
|
+
* Whether to generate uncompressed book files alongside compressed ones.
|
|
301
|
+
*/
|
|
302
|
+
makeUncompressedBooks?: boolean;
|
|
296
303
|
};
|
|
297
304
|
type SimulationConfigOptions = {
|
|
298
305
|
debug?: boolean;
|
|
@@ -538,6 +545,7 @@ declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymb
|
|
|
538
545
|
getPaddingTop(): Reels;
|
|
539
546
|
getPaddingBottom(): Reels;
|
|
540
547
|
getAnticipation(): boolean[];
|
|
548
|
+
getLockedReels(): boolean[];
|
|
541
549
|
/**
|
|
542
550
|
* Gets the symbol at the specified reel and row index.
|
|
543
551
|
*/
|
|
@@ -555,6 +563,10 @@ declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymb
|
|
|
555
563
|
* Sets the anticipation value for a specific reel.
|
|
556
564
|
*/
|
|
557
565
|
setAnticipationForReel(reelIndex: number, value: boolean): void;
|
|
566
|
+
/**
|
|
567
|
+
* Sets the locked state for a specific reel.
|
|
568
|
+
*/
|
|
569
|
+
setReelLocked(reelIndex: number, value: boolean): void;
|
|
558
570
|
/**
|
|
559
571
|
* Counts how many symbols matching the criteria are on a specific reel.
|
|
560
572
|
*/
|
|
@@ -1722,6 +1734,8 @@ declare class StandaloneBoard {
|
|
|
1722
1734
|
getBoardReels(): Reels;
|
|
1723
1735
|
getPaddingTop(): Reels;
|
|
1724
1736
|
getPaddingBottom(): Reels;
|
|
1737
|
+
getAnticipation(): boolean[];
|
|
1738
|
+
getLockedReels(): boolean[];
|
|
1725
1739
|
/**
|
|
1726
1740
|
* Gets the symbol at the specified reel and row index.
|
|
1727
1741
|
*/
|
|
@@ -1739,6 +1753,10 @@ declare class StandaloneBoard {
|
|
|
1739
1753
|
* Sets the anticipation value for a specific reel.
|
|
1740
1754
|
*/
|
|
1741
1755
|
setAnticipationForReel(reelIndex: number, value: boolean): void;
|
|
1756
|
+
/**
|
|
1757
|
+
* Sets the locked state for a specific reel.
|
|
1758
|
+
*/
|
|
1759
|
+
setReelLocked(reelIndex: number, value: boolean): void;
|
|
1742
1760
|
/**
|
|
1743
1761
|
* Counts how many symbols matching the criteria are on a specific reel.
|
|
1744
1762
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ type PermanentFilePaths = {
|
|
|
50
50
|
booksIndexMeta: (mode: string) => string;
|
|
51
51
|
booksChunk: (mode: string, worker: number, chunk: number) => string;
|
|
52
52
|
booksCompressed: (mode: string) => string;
|
|
53
|
+
booksUncompressed: (mode: string) => string;
|
|
53
54
|
lookupTable: (mode: string) => string;
|
|
54
55
|
lookupTableIndex: (mode: string) => string;
|
|
55
56
|
lookupTableSegmented: (mode: string) => string;
|
|
@@ -175,6 +176,7 @@ declare class Simulation {
|
|
|
175
176
|
readonly gameConfig: GameConfig & GameMetadata;
|
|
176
177
|
readonly simRunsAmount: Partial<Record<string, number>>;
|
|
177
178
|
readonly concurrency: number;
|
|
179
|
+
readonly makeUncompressedBooks: boolean;
|
|
178
180
|
private debug;
|
|
179
181
|
private actualSims;
|
|
180
182
|
private wallet;
|
|
@@ -265,6 +267,7 @@ declare class Simulation {
|
|
|
265
267
|
*/
|
|
266
268
|
confirmRecords(ctx: GameContext): void;
|
|
267
269
|
printSimulationSummary(): Promise<void>;
|
|
270
|
+
private sendSimulationStatus;
|
|
268
271
|
}
|
|
269
272
|
type SimulationOptions = {
|
|
270
273
|
/**
|
|
@@ -293,6 +296,10 @@ type SimulationOptions = {
|
|
|
293
296
|
* Default: 50
|
|
294
297
|
*/
|
|
295
298
|
maxDiskBuffer?: number;
|
|
299
|
+
/**
|
|
300
|
+
* Whether to generate uncompressed book files alongside compressed ones.
|
|
301
|
+
*/
|
|
302
|
+
makeUncompressedBooks?: boolean;
|
|
296
303
|
};
|
|
297
304
|
type SimulationConfigOptions = {
|
|
298
305
|
debug?: boolean;
|
|
@@ -538,6 +545,7 @@ declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymb
|
|
|
538
545
|
getPaddingTop(): Reels;
|
|
539
546
|
getPaddingBottom(): Reels;
|
|
540
547
|
getAnticipation(): boolean[];
|
|
548
|
+
getLockedReels(): boolean[];
|
|
541
549
|
/**
|
|
542
550
|
* Gets the symbol at the specified reel and row index.
|
|
543
551
|
*/
|
|
@@ -555,6 +563,10 @@ declare class BoardService<TGameModes extends AnyGameModes = AnyGameModes, TSymb
|
|
|
555
563
|
* Sets the anticipation value for a specific reel.
|
|
556
564
|
*/
|
|
557
565
|
setAnticipationForReel(reelIndex: number, value: boolean): void;
|
|
566
|
+
/**
|
|
567
|
+
* Sets the locked state for a specific reel.
|
|
568
|
+
*/
|
|
569
|
+
setReelLocked(reelIndex: number, value: boolean): void;
|
|
558
570
|
/**
|
|
559
571
|
* Counts how many symbols matching the criteria are on a specific reel.
|
|
560
572
|
*/
|
|
@@ -1722,6 +1734,8 @@ declare class StandaloneBoard {
|
|
|
1722
1734
|
getBoardReels(): Reels;
|
|
1723
1735
|
getPaddingTop(): Reels;
|
|
1724
1736
|
getPaddingBottom(): Reels;
|
|
1737
|
+
getAnticipation(): boolean[];
|
|
1738
|
+
getLockedReels(): boolean[];
|
|
1725
1739
|
/**
|
|
1726
1740
|
* Gets the symbol at the specified reel and row index.
|
|
1727
1741
|
*/
|
|
@@ -1739,6 +1753,10 @@ declare class StandaloneBoard {
|
|
|
1739
1753
|
* Sets the anticipation value for a specific reel.
|
|
1740
1754
|
*/
|
|
1741
1755
|
setAnticipationForReel(reelIndex: number, value: boolean): void;
|
|
1756
|
+
/**
|
|
1757
|
+
* Sets the locked state for a specific reel.
|
|
1758
|
+
*/
|
|
1759
|
+
setReelLocked(reelIndex: number, value: boolean): void;
|
|
1742
1760
|
/**
|
|
1743
1761
|
* Counts how many symbols matching the criteria are on a specific reel.
|
|
1744
1762
|
*/
|
package/dist/index.js
CHANGED
|
@@ -79,6 +79,7 @@ function createPermanentFilePaths(basePath) {
|
|
|
79
79
|
`books_${mode}_chunk_${worker}-${chunk}.jsonl.zst`
|
|
80
80
|
),
|
|
81
81
|
booksCompressed: (mode) => import_path.default.join(basePath, "publish_files", `books_${mode}.jsonl.zst`),
|
|
82
|
+
booksUncompressed: (mode) => import_path.default.join(basePath, `books_${mode}.jsonl`),
|
|
82
83
|
lookupTable: (mode) => import_path.default.join(basePath, `lookUpTable_${mode}.csv`),
|
|
83
84
|
lookupTableIndex: (mode) => import_path.default.join(basePath, `lookUpTable_${mode}.index`),
|
|
84
85
|
lookupTableSegmented: (mode) => import_path.default.join(basePath, `lookUpTableSegmented_${mode}.csv`),
|
|
@@ -476,8 +477,18 @@ var Board = class {
|
|
|
476
477
|
* Used for triggering anticipation effects.
|
|
477
478
|
*/
|
|
478
479
|
anticipation;
|
|
480
|
+
/**
|
|
481
|
+
* The most recent stop positions for the reels.
|
|
482
|
+
*/
|
|
479
483
|
lastDrawnReelStops;
|
|
484
|
+
/**
|
|
485
|
+
* The reel set used in the most recent draw.
|
|
486
|
+
*/
|
|
480
487
|
lastUsedReels;
|
|
488
|
+
/**
|
|
489
|
+
* Indicates whether each reel is locked or not.
|
|
490
|
+
*/
|
|
491
|
+
reelsLocked;
|
|
481
492
|
constructor() {
|
|
482
493
|
this.reels = [];
|
|
483
494
|
this.paddingTop = [];
|
|
@@ -485,6 +496,7 @@ var Board = class {
|
|
|
485
496
|
this.anticipation = [];
|
|
486
497
|
this.lastDrawnReelStops = [];
|
|
487
498
|
this.lastUsedReels = [];
|
|
499
|
+
this.reelsLocked = [];
|
|
488
500
|
}
|
|
489
501
|
getSymbol(reelIndex, rowIndex) {
|
|
490
502
|
return this.reels[reelIndex]?.[rowIndex];
|
|
@@ -632,14 +644,19 @@ var Board = class {
|
|
|
632
644
|
return reelSet;
|
|
633
645
|
}
|
|
634
646
|
resetReels(opts) {
|
|
635
|
-
const
|
|
647
|
+
const { ctx, reelsAmount, reelsLocked } = opts;
|
|
648
|
+
const length = reelsAmount ?? ctx.services.game.getCurrentGameMode().reelsAmount;
|
|
636
649
|
this.reels = this.makeEmptyReels(opts);
|
|
637
650
|
this.anticipation = Array.from({ length }, () => false);
|
|
651
|
+
this.reelsLocked = reelsLocked ?? Array.from({ length }, () => false);
|
|
638
652
|
this.paddingTop = this.makeEmptyReels(opts);
|
|
639
653
|
this.paddingBottom = this.makeEmptyReels(opts);
|
|
640
654
|
}
|
|
641
655
|
drawBoardMixed(opts) {
|
|
642
|
-
this.resetReels(
|
|
656
|
+
this.resetReels({
|
|
657
|
+
...opts,
|
|
658
|
+
...this.reelsLocked.length && { reelsLocked: this.reelsLocked }
|
|
659
|
+
});
|
|
643
660
|
const reelsAmount = opts.reelsAmount ?? opts.ctx.services.game.getCurrentGameMode().reelsAmount;
|
|
644
661
|
const symbolsPerReel = opts.symbolsPerReel ?? opts.ctx.services.game.getCurrentGameMode().symbolsPerReel;
|
|
645
662
|
const padSymbols = opts.padSymbols ?? opts.ctx.config.padSymbols;
|
|
@@ -668,6 +685,18 @@ var Board = class {
|
|
|
668
685
|
);
|
|
669
686
|
}
|
|
670
687
|
}
|
|
688
|
+
if (this.reelsLocked.some((locked) => locked) && this.lastDrawnReelStops.length == 0) {
|
|
689
|
+
throw new Error(
|
|
690
|
+
"Cannot draw board with locked reels before drawing it at least once."
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
if (this.reelsLocked.some((locked) => locked)) {
|
|
694
|
+
for (let ridx = 0; ridx < reelsAmount; ridx++) {
|
|
695
|
+
if (this.reelsLocked[ridx]) {
|
|
696
|
+
finalReelStops[ridx] = this.lastDrawnReelStops[ridx];
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
671
700
|
this.lastDrawnReelStops = finalReelStops.map((pos) => pos);
|
|
672
701
|
this.lastUsedReels = opts.reels;
|
|
673
702
|
for (let ridx = 0; ridx < reelsAmount; ridx++) {
|
|
@@ -829,6 +858,9 @@ var BoardService = class extends AbstractService {
|
|
|
829
858
|
getAnticipation() {
|
|
830
859
|
return this.board.anticipation;
|
|
831
860
|
}
|
|
861
|
+
getLockedReels() {
|
|
862
|
+
return this.board.reelsLocked;
|
|
863
|
+
}
|
|
832
864
|
/**
|
|
833
865
|
* Gets the symbol at the specified reel and row index.
|
|
834
866
|
*/
|
|
@@ -858,6 +890,12 @@ var BoardService = class extends AbstractService {
|
|
|
858
890
|
setAnticipationForReel(reelIndex, value) {
|
|
859
891
|
this.board.anticipation[reelIndex] = value;
|
|
860
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* Sets the locked state for a specific reel.
|
|
895
|
+
*/
|
|
896
|
+
setReelLocked(reelIndex, value) {
|
|
897
|
+
this.board.reelsLocked[reelIndex] = value;
|
|
898
|
+
}
|
|
861
899
|
/**
|
|
862
900
|
* Counts how many symbols matching the criteria are on a specific reel.
|
|
863
901
|
*/
|
|
@@ -1799,6 +1837,8 @@ var TerminalUi = class {
|
|
|
1799
1837
|
logs = [];
|
|
1800
1838
|
logScrollOffset = 0;
|
|
1801
1839
|
isScrolled = false;
|
|
1840
|
+
maxLogs = 500;
|
|
1841
|
+
totalLogs = 0;
|
|
1802
1842
|
minWidth = 50;
|
|
1803
1843
|
minHeight = 12;
|
|
1804
1844
|
isRendering = false;
|
|
@@ -1824,12 +1864,13 @@ var TerminalUi = class {
|
|
|
1824
1864
|
this.scrollDown();
|
|
1825
1865
|
} else if (key === "l") {
|
|
1826
1866
|
this.scrollToBottom();
|
|
1827
|
-
} else if (key === "") {
|
|
1867
|
+
} else if (key === "q" || key === "") {
|
|
1828
1868
|
this.stop();
|
|
1829
1869
|
process.exit(0);
|
|
1830
1870
|
}
|
|
1831
1871
|
};
|
|
1832
1872
|
process.stdout.on("resize", this.resizeHandler);
|
|
1873
|
+
process.on("SIGINT", this.sigintHandler);
|
|
1833
1874
|
}
|
|
1834
1875
|
get terminalWidth() {
|
|
1835
1876
|
return process.stdout.columns || 80;
|
|
@@ -1851,7 +1892,6 @@ var TerminalUi = class {
|
|
|
1851
1892
|
}
|
|
1852
1893
|
this.render();
|
|
1853
1894
|
this.renderInterval = setInterval(() => this.render(), 100);
|
|
1854
|
-
process.on("SIGINT", this.sigintHandler);
|
|
1855
1895
|
}
|
|
1856
1896
|
stop() {
|
|
1857
1897
|
if (this.renderInterval) {
|
|
@@ -1879,7 +1919,16 @@ var TerminalUi = class {
|
|
|
1879
1919
|
this.totalSims = opts.totalSims;
|
|
1880
1920
|
}
|
|
1881
1921
|
log(message) {
|
|
1882
|
-
this.logs.push({ i: this.
|
|
1922
|
+
this.logs.push({ i: this.totalLogs, m: message });
|
|
1923
|
+
this.totalLogs++;
|
|
1924
|
+
if (this.logs.length > this.maxLogs) {
|
|
1925
|
+
const excess = this.logs.length - this.maxLogs;
|
|
1926
|
+
this.logs.splice(0, excess);
|
|
1927
|
+
this.logScrollOffset = Math.min(
|
|
1928
|
+
this.logScrollOffset,
|
|
1929
|
+
Math.max(0, this.logs.length - this.getLogAreaHeight())
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1883
1932
|
if (!this.isScrolled) this.scrollToBottom();
|
|
1884
1933
|
}
|
|
1885
1934
|
scrollUp(lines = 1) {
|
|
@@ -2044,6 +2093,7 @@ var Simulation = class {
|
|
|
2044
2093
|
gameConfig;
|
|
2045
2094
|
simRunsAmount;
|
|
2046
2095
|
concurrency;
|
|
2096
|
+
makeUncompressedBooks;
|
|
2047
2097
|
debug = false;
|
|
2048
2098
|
actualSims = 0;
|
|
2049
2099
|
wallet = new Wallet();
|
|
@@ -2072,6 +2122,7 @@ var Simulation = class {
|
|
|
2072
2122
|
const { config, metadata } = createGameConfig(gameConfigOpts);
|
|
2073
2123
|
this.gameConfig = { ...config, ...metadata };
|
|
2074
2124
|
this.gameConfigOpts = gameConfigOpts;
|
|
2125
|
+
this.makeUncompressedBooks = opts.makeUncompressedBooks || false;
|
|
2075
2126
|
this.simRunsAmount = opts.simRunsAmount || {};
|
|
2076
2127
|
this.concurrency = (opts.concurrency || 6) >= 2 ? opts.concurrency || 6 : 2;
|
|
2077
2128
|
this.maxPendingSims = opts.maxPendingSims ?? 25;
|
|
@@ -2149,9 +2200,7 @@ var Simulation = class {
|
|
|
2149
2200
|
const startTime = Date.now();
|
|
2150
2201
|
statusMessage = `Simulating mode "${mode}" with ${this.simRunsAmount[mode]} runs.`;
|
|
2151
2202
|
this.tui?.log(statusMessage);
|
|
2152
|
-
|
|
2153
|
-
this.socket.emit("simulationStatus", statusMessage);
|
|
2154
|
-
}
|
|
2203
|
+
this.sendSimulationStatus(statusMessage);
|
|
2155
2204
|
const runs = this.simRunsAmount[mode] || 0;
|
|
2156
2205
|
if (runs <= 0) continue;
|
|
2157
2206
|
if (!configuredGameModes.includes(mode)) {
|
|
@@ -2188,9 +2237,7 @@ var Simulation = class {
|
|
|
2188
2237
|
createDirIfNotExists(this.PATHS.publishFiles);
|
|
2189
2238
|
statusMessage = `Writing final files for game mode "${mode}". This may take a while...`;
|
|
2190
2239
|
this.tui?.log(statusMessage);
|
|
2191
|
-
|
|
2192
|
-
this.socket.emit("simulationStatus", statusMessage);
|
|
2193
|
-
}
|
|
2240
|
+
this.sendSimulationStatus(statusMessage);
|
|
2194
2241
|
writeFile(
|
|
2195
2242
|
this.PATHS.booksIndexMeta(mode),
|
|
2196
2243
|
JSON.stringify(
|
|
@@ -2245,13 +2292,43 @@ var Simulation = class {
|
|
|
2245
2292
|
}
|
|
2246
2293
|
await this.writeRecords(mode);
|
|
2247
2294
|
this.writeIndexJson();
|
|
2295
|
+
if (this.makeUncompressedBooks) {
|
|
2296
|
+
statusMessage = `Creating decompressed book file for mode "${mode}". This may take a while...`;
|
|
2297
|
+
this.tui?.log(statusMessage);
|
|
2298
|
+
this.sendSimulationStatus(statusMessage);
|
|
2299
|
+
const uncompressedBooksPath = this.PATHS.booksUncompressed(mode);
|
|
2300
|
+
const outputStream = import_fs3.default.createWriteStream(uncompressedBooksPath, {
|
|
2301
|
+
highWaterMark: this.streamHighWaterMark
|
|
2302
|
+
});
|
|
2303
|
+
try {
|
|
2304
|
+
for (const { worker, chunks: chunks2 } of this.bookIndexMetas) {
|
|
2305
|
+
for (let chunk = 0; chunk < chunks2; chunk++) {
|
|
2306
|
+
const bookChunkPath = this.PATHS.booksChunk(mode, worker, chunk);
|
|
2307
|
+
if (!import_fs3.default.existsSync(bookChunkPath)) continue;
|
|
2308
|
+
const inputStream = import_fs3.default.createReadStream(bookChunkPath);
|
|
2309
|
+
const compress = import_zlib.default.createZstdDecompress();
|
|
2310
|
+
for await (const decompChunk of inputStream.pipe(compress)) {
|
|
2311
|
+
if (!outputStream.write(decompChunk)) {
|
|
2312
|
+
await new Promise((r) => outputStream.once("drain", () => r()));
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
outputStream.end();
|
|
2318
|
+
await new Promise((r) => outputStream.on("finish", () => r()));
|
|
2319
|
+
} catch (error) {
|
|
2320
|
+
statusMessage = import_chalk2.default.yellow(
|
|
2321
|
+
`Error creating uncompressed book file: ${error.message}`
|
|
2322
|
+
);
|
|
2323
|
+
this.tui?.log(statusMessage);
|
|
2324
|
+
this.sendSimulationStatus(statusMessage);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2248
2327
|
const endTime = Date.now();
|
|
2249
2328
|
const prettyTime = new Date(endTime - startTime).toISOString().slice(11, -1);
|
|
2250
2329
|
statusMessage = `Mode ${mode} done! Time taken: ${prettyTime}`;
|
|
2251
2330
|
this.tui?.log(statusMessage);
|
|
2252
|
-
|
|
2253
|
-
this.socket.emit("simulationStatus", statusMessage);
|
|
2254
|
-
}
|
|
2331
|
+
this.sendSimulationStatus(statusMessage);
|
|
2255
2332
|
}
|
|
2256
2333
|
this.tui?.stop();
|
|
2257
2334
|
await this.printSimulationSummary();
|
|
@@ -2453,7 +2530,7 @@ var Simulation = class {
|
|
|
2453
2530
|
`
|
|
2454
2531
|
)
|
|
2455
2532
|
]);
|
|
2456
|
-
if (this.bookBufferSizes.get(index) >=
|
|
2533
|
+
if (this.bookBufferSizes.get(index) >= 10 * 1024 * 1024) {
|
|
2457
2534
|
await flushBookChunk();
|
|
2458
2535
|
}
|
|
2459
2536
|
if (this.recordsWriteStream) {
|
|
@@ -2899,6 +2976,11 @@ var Simulation = class {
|
|
|
2899
2976
|
});
|
|
2900
2977
|
}
|
|
2901
2978
|
}
|
|
2979
|
+
sendSimulationStatus(message) {
|
|
2980
|
+
if (this.socket && this.panelActive) {
|
|
2981
|
+
this.socket.emit("simulationStatus", message);
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2902
2984
|
};
|
|
2903
2985
|
|
|
2904
2986
|
// src/analysis/index.ts
|
|
@@ -4546,6 +4628,12 @@ var StandaloneBoard = class {
|
|
|
4546
4628
|
getPaddingBottom() {
|
|
4547
4629
|
return this.board.paddingBottom;
|
|
4548
4630
|
}
|
|
4631
|
+
getAnticipation() {
|
|
4632
|
+
return this.board.anticipation;
|
|
4633
|
+
}
|
|
4634
|
+
getLockedReels() {
|
|
4635
|
+
return this.board.reelsLocked;
|
|
4636
|
+
}
|
|
4549
4637
|
/**
|
|
4550
4638
|
* Gets the symbol at the specified reel and row index.
|
|
4551
4639
|
*/
|
|
@@ -4575,6 +4663,12 @@ var StandaloneBoard = class {
|
|
|
4575
4663
|
setAnticipationForReel(reelIndex, value) {
|
|
4576
4664
|
this.board.anticipation[reelIndex] = value;
|
|
4577
4665
|
}
|
|
4666
|
+
/**
|
|
4667
|
+
* Sets the locked state for a specific reel.
|
|
4668
|
+
*/
|
|
4669
|
+
setReelLocked(reelIndex, value) {
|
|
4670
|
+
this.board.reelsLocked[reelIndex] = value;
|
|
4671
|
+
}
|
|
4578
4672
|
/**
|
|
4579
4673
|
* Counts how many symbols matching the criteria are on a specific reel.
|
|
4580
4674
|
*/
|