code-battles 1.4.0 → 1.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/dist/cjs/index.js +30 -12
- package/dist/cjs/types/utilities.d.ts +1 -1
- package/dist/code_battles/__pycache__/__init__.cpython-312.pyc +0 -0
- package/dist/code_battles/__pycache__/battles.cpython-312.pyc +0 -0
- package/dist/code_battles/__pycache__/utilities.cpython-312.pyc +0 -0
- package/dist/code_battles/battles.py +54 -26
- package/dist/esm/index.js +31 -13
- package/dist/esm/types/utilities.d.ts +1 -1
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -411,11 +411,11 @@ const toPlacing = (n) => {
|
|
|
411
411
|
}
|
|
412
412
|
return n.toString() + DIGITS[n % 10];
|
|
413
413
|
};
|
|
414
|
-
const runNoUI = (map, apis, playerBots, verbose) => {
|
|
414
|
+
const runNoUI = (map, apis, playerBots, seed, verbose) => {
|
|
415
415
|
const players = playerBots.map((api) => (api === "None" ? "" : apis[api]));
|
|
416
416
|
tryUntilSuccess(() =>
|
|
417
417
|
// @ts-ignore
|
|
418
|
-
window._startSimulation(map, players, playerBots, true, false, verbose));
|
|
418
|
+
window._startSimulation(map, players, playerBots, true, false, verbose, seed));
|
|
419
419
|
};
|
|
420
420
|
const tryUntilSuccess = (f, timeout = 500) => {
|
|
421
421
|
try {
|
|
@@ -2504,6 +2504,10 @@ const RunSimulationBlock = () => {
|
|
|
2504
2504
|
key: "Player Bots",
|
|
2505
2505
|
defaultValue: ["None", "None"],
|
|
2506
2506
|
});
|
|
2507
|
+
const [seed, setSeed] = useLocalStorage({
|
|
2508
|
+
key: "Seed",
|
|
2509
|
+
defaultValue: "",
|
|
2510
|
+
});
|
|
2507
2511
|
const [runningNoUI, setRunningNoUI] = React.useState(false);
|
|
2508
2512
|
const [runningNoUIN, setRunningNoUIN] = React.useState({});
|
|
2509
2513
|
const navigate = reactRouterDom.useNavigate();
|
|
@@ -2514,15 +2518,16 @@ const RunSimulationBlock = () => {
|
|
|
2514
2518
|
const run = () => {
|
|
2515
2519
|
// @ts-ignore
|
|
2516
2520
|
window._isSimulationFromFile = false;
|
|
2517
|
-
navigate(`/simulation/${map.replaceAll(" ", "-")}/${playerBots.join("-")}`);
|
|
2521
|
+
navigate(`/simulation/${map.replaceAll(" ", "-")}/${playerBots.join("-")}?seed=${seed}`);
|
|
2518
2522
|
};
|
|
2519
2523
|
const startRunNoUI = () => {
|
|
2520
2524
|
setRunningNoUI(true);
|
|
2521
|
-
runNoUI(map, apis, playerBots, true);
|
|
2525
|
+
runNoUI(map, apis, playerBots, seed.toString(), true);
|
|
2522
2526
|
};
|
|
2523
2527
|
const startRunNoUIN = (n) => {
|
|
2528
|
+
setLocalStorage("Results", {});
|
|
2524
2529
|
setRunningNoUIN({ [n.toString()]: n });
|
|
2525
|
-
runNoUI(map, apis, playerBots, false);
|
|
2530
|
+
runNoUI(map, apis, playerBots, seed.toString(), false);
|
|
2526
2531
|
};
|
|
2527
2532
|
React.useEffect(() => {
|
|
2528
2533
|
// @ts-ignore
|
|
@@ -2576,7 +2581,7 @@ const RunSimulationBlock = () => {
|
|
|
2576
2581
|
setLocalStorage("Results", {});
|
|
2577
2582
|
}
|
|
2578
2583
|
else {
|
|
2579
|
-
runNoUI(map, apis, playerBots, false);
|
|
2584
|
+
runNoUI(map, apis, playerBots, seed.toString(), false);
|
|
2580
2585
|
}
|
|
2581
2586
|
}
|
|
2582
2587
|
}, [runningNoUIN]);
|
|
@@ -2587,6 +2592,7 @@ const RunSimulationBlock = () => {
|
|
|
2587
2592
|
}
|
|
2588
2593
|
} }),
|
|
2589
2594
|
React.createElement(BotSelector, { playerCount: playerCount, setPlayerCount: setPlayerCount, playerBots: playerBots, setPlayerBots: setPlayerBots, apis: apis }),
|
|
2595
|
+
React.createElement(core.NumberInput, { leftSection: React.createElement("i", { className: "fa-solid fa-dice" }), label: "Randomness Seed", min: 0, value: seed, onChange: setSeed }),
|
|
2590
2596
|
React.createElement(core.Button.Group, { mt: "xs" },
|
|
2591
2597
|
React.createElement(core.Button, { variant: "default", w: "50%", leftSection: React.createElement("i", { className: "fa-solid fa-play" }), onClick: run }, "Run"),
|
|
2592
2598
|
React.createElement(core.Button, { variant: "default", w: "50%", leftSection: React.createElement("i", { className: "fa-solid fa-forward" }), onClick: startRunNoUI, loading: runningNoUI || loading }, "Run (No UI)")),
|
|
@@ -14512,7 +14518,7 @@ const Round = () => {
|
|
|
14512
14518
|
}
|
|
14513
14519
|
React.useEffect(() => {
|
|
14514
14520
|
if (remaining > 0) {
|
|
14515
|
-
runNoUI(currentMap, apis, currentPlayers, false);
|
|
14521
|
+
runNoUI(currentMap, apis, currentPlayers, "", false);
|
|
14516
14522
|
}
|
|
14517
14523
|
}, [remaining]);
|
|
14518
14524
|
React.useEffect(updatePointModifier, [results]);
|
|
@@ -14571,7 +14577,7 @@ const Round = () => {
|
|
|
14571
14577
|
React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.map.replaceAll(" ", "-")}/${round.players.join("-")}?showcase=true`) }, "Simulate"),
|
|
14572
14578
|
React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-forward" }), size: "xs", onClick: () => {
|
|
14573
14579
|
if (roundIterations === 1) {
|
|
14574
|
-
runNoUI(round.map, apis, round.players, true);
|
|
14580
|
+
runNoUI(round.map, apis, round.players, "", true);
|
|
14575
14581
|
}
|
|
14576
14582
|
else {
|
|
14577
14583
|
currentMap = round.map;
|
|
@@ -15844,7 +15850,10 @@ const confetti = {
|
|
|
15844
15850
|
};
|
|
15845
15851
|
|
|
15846
15852
|
const AutoScrollButton = () => {
|
|
15847
|
-
const [autoScroll, setAutoScroll] =
|
|
15853
|
+
const [autoScroll, setAutoScroll] = useLocalStorage({
|
|
15854
|
+
key: "Auto Scroll",
|
|
15855
|
+
defaultValue: true,
|
|
15856
|
+
});
|
|
15848
15857
|
React.useEffect(() => {
|
|
15849
15858
|
// @ts-ignore
|
|
15850
15859
|
window.autoScroll = autoScroll;
|
|
@@ -15862,8 +15871,14 @@ const ShowLogsButtons = ({ playerNames, showLogs, setShowLogs, }) => {
|
|
|
15862
15871
|
};
|
|
15863
15872
|
|
|
15864
15873
|
const LogViewer = ({ playerNames }) => {
|
|
15865
|
-
const [showLogs, setShowLogs] =
|
|
15866
|
-
|
|
15874
|
+
const [showLogs, setShowLogs] = useLocalStorage({
|
|
15875
|
+
key: "Show Logs",
|
|
15876
|
+
defaultValue: [],
|
|
15877
|
+
});
|
|
15878
|
+
const [logs, setLogs] = useLocalStorage({
|
|
15879
|
+
key: "Logs",
|
|
15880
|
+
defaultValue: [],
|
|
15881
|
+
});
|
|
15867
15882
|
React.useEffect(() => {
|
|
15868
15883
|
// @ts-ignore
|
|
15869
15884
|
setShowLogs(playerNames.map(() => true));
|
|
@@ -15938,6 +15953,7 @@ const Simulation = () => {
|
|
|
15938
15953
|
const [apis, loading] = useAPIs();
|
|
15939
15954
|
let { map, playerapis } = reactRouterDom.useParams();
|
|
15940
15955
|
const location = reactRouterDom.useLocation();
|
|
15956
|
+
const [searchParams] = reactRouterDom.useSearchParams();
|
|
15941
15957
|
const [winner, setWinner] = React.useState();
|
|
15942
15958
|
const [downloadBytes, setDownloadBytes] = React.useState(false);
|
|
15943
15959
|
const navigate = reactRouterDom.useNavigate();
|
|
@@ -15979,14 +15995,16 @@ const Simulation = () => {
|
|
|
15979
15995
|
const playerNames = (_a = playerapis === null || playerapis === void 0 ? void 0 : playerapis.split("-")) !== null && _a !== void 0 ? _a : [];
|
|
15980
15996
|
const players = playerNames.map((api) => (api === "None" ? "" : apis[api]));
|
|
15981
15997
|
React.useEffect(() => {
|
|
15998
|
+
var _a;
|
|
15982
15999
|
if (!loading &&
|
|
15983
16000
|
players &&
|
|
15984
16001
|
playerapis &&
|
|
15985
16002
|
// @ts-ignore
|
|
15986
16003
|
window._isSimulationFromFile !== true) {
|
|
16004
|
+
const seed = (_a = searchParams.get("seed")) !== null && _a !== void 0 ? _a : "";
|
|
15987
16005
|
tryUntilSuccess(() =>
|
|
15988
16006
|
// @ts-ignore
|
|
15989
|
-
window._startSimulation(map, players, playerNames, false, !showcaseMode, true));
|
|
16007
|
+
window._startSimulation(map, players, playerNames, false, !showcaseMode, true, seed));
|
|
15990
16008
|
}
|
|
15991
16009
|
}, [loading]);
|
|
15992
16010
|
const newRank = getRank(getLocalStorage("Cached tournament/info"), winner, getLocalStorage("Point Modifier")) + 1;
|
|
@@ -10,6 +10,6 @@ export declare const getRank: (tournamentInfo: any, team: string, pointModifier:
|
|
|
10
10
|
export declare const updatePointModifier: () => void;
|
|
11
11
|
export declare const toPlacing: (n: number) => string;
|
|
12
12
|
export declare const zeroPad: (s: string, l: number) => string;
|
|
13
|
-
export declare const runNoUI: (map: string, apis: Record<string, any>, playerBots: string[], verbose: boolean) => void;
|
|
13
|
+
export declare const runNoUI: (map: string, apis: Record<string, any>, playerBots: string[], seed: string, verbose: boolean) => void;
|
|
14
14
|
export declare const tryUntilSuccess: (f: () => void, timeout?: number) => void;
|
|
15
15
|
export declare const downloadFile: (filename: string, mimeType: string, contents: string) => void;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -5,7 +5,7 @@ import datetime
|
|
|
5
5
|
import json
|
|
6
6
|
import math
|
|
7
7
|
import time
|
|
8
|
-
import
|
|
8
|
+
from random import Random
|
|
9
9
|
import sys
|
|
10
10
|
import traceback
|
|
11
11
|
import gzip
|
|
@@ -43,6 +43,7 @@ class Simulation:
|
|
|
43
43
|
timestamp: datetime.datetime
|
|
44
44
|
logs: list
|
|
45
45
|
decisions: List[bytes]
|
|
46
|
+
seed: int
|
|
46
47
|
|
|
47
48
|
def dump(self):
|
|
48
49
|
return base64.b64encode(
|
|
@@ -59,6 +60,7 @@ class Simulation:
|
|
|
59
60
|
base64.b64encode(decision).decode()
|
|
60
61
|
for decision in self.decisions
|
|
61
62
|
],
|
|
63
|
+
"seed": self.seed,
|
|
62
64
|
}
|
|
63
65
|
).encode()
|
|
64
66
|
)
|
|
@@ -66,7 +68,7 @@ class Simulation:
|
|
|
66
68
|
|
|
67
69
|
@staticmethod
|
|
68
70
|
def load(file: str):
|
|
69
|
-
contents = json.loads(gzip.decompress(base64.b64decode(file)))
|
|
71
|
+
contents: Dict[str, Any] = json.loads(gzip.decompress(base64.b64decode(file)))
|
|
70
72
|
return Simulation(
|
|
71
73
|
contents["map"],
|
|
72
74
|
contents["playerNames"],
|
|
@@ -75,6 +77,7 @@ class Simulation:
|
|
|
75
77
|
datetime.datetime.fromisoformat(contents["timestamp"]),
|
|
76
78
|
contents["logs"],
|
|
77
79
|
[base64.b64decode(decision) for decision in contents["decisions"]],
|
|
80
|
+
contents["seed"],
|
|
78
81
|
)
|
|
79
82
|
|
|
80
83
|
|
|
@@ -109,6 +112,12 @@ class CodeBattles(
|
|
|
109
112
|
"""The current state of the game. You should modify this in :func:`apply_decisions`."""
|
|
110
113
|
player_requests: List[PlayerRequestsType]
|
|
111
114
|
"""The current requests set by the players. Should be read in :func:`make_decisions` (and probably serialized), and set by the API implementation."""
|
|
115
|
+
random: Random
|
|
116
|
+
"""A pseudorandom generator that should be used for all randomness purposes (except :func:`make_decisions`)"""
|
|
117
|
+
player_randoms: List[Random]
|
|
118
|
+
"""A pseudorandom generator that should be used for all randomness purposes in a player's bot. Given to the bots as a global via :func:`configure_bot_globals`."""
|
|
119
|
+
make_decisions_random: Random
|
|
120
|
+
"""A pseudorandom generator that should be used for all randomness purposes in :func:`make_decisions`."""
|
|
112
121
|
|
|
113
122
|
background: bool
|
|
114
123
|
"""Whether the current simulation is occuring in the background (without UI)."""
|
|
@@ -144,12 +153,12 @@ class CodeBattles(
|
|
|
144
153
|
Use the current state and bots to make decisions in order to reach the next state.
|
|
145
154
|
You may use :func:`run_bot_method` to run a specific player's method (for instance, `run`).
|
|
146
155
|
|
|
156
|
+
If you need any randomness, use :attr:`make_decisions_random`.
|
|
157
|
+
|
|
147
158
|
This function may take a lot of time to execute.
|
|
148
159
|
|
|
149
160
|
.. warning::
|
|
150
161
|
Do not call any other method other than :func:`run_bot_method` in here. This method will run in a web worker.
|
|
151
|
-
|
|
152
|
-
Do NOT update :attr:`state` or :attr:`step`.
|
|
153
162
|
"""
|
|
154
163
|
|
|
155
164
|
raise NotImplementedError("make_decisions")
|
|
@@ -261,11 +270,11 @@ class CodeBattles(
|
|
|
261
270
|
"""
|
|
262
271
|
return 1
|
|
263
272
|
|
|
264
|
-
def configure_bot_globals(self) -> Dict[str, Any]:
|
|
273
|
+
def configure_bot_globals(self, player_index: int) -> Dict[str, Any]:
|
|
265
274
|
"""
|
|
266
275
|
Configure additional available global items, such as libraries from the Python standard library, bots can use.
|
|
267
276
|
|
|
268
|
-
By default, this is math, time and random
|
|
277
|
+
By default, this is math, time and random, where random is the corresponding :attr:`player_randoms`.
|
|
269
278
|
|
|
270
279
|
.. warning::
|
|
271
280
|
Bots will also have `api`, `context`, `player_api`, and the bot base class name (CodeBattlesBot by default) available as part of the globals, alongside everything in `api`.
|
|
@@ -276,7 +285,7 @@ class CodeBattles(
|
|
|
276
285
|
return {
|
|
277
286
|
"math": math,
|
|
278
287
|
"time": time,
|
|
279
|
-
"random":
|
|
288
|
+
"random": self.player_randoms[player_index],
|
|
280
289
|
}
|
|
281
290
|
|
|
282
291
|
def configure_version(self) -> str:
|
|
@@ -395,6 +404,9 @@ class CodeBattles(
|
|
|
395
404
|
|
|
396
405
|
For game-global log entries (not coming from a specific player), don't specify a ``player_index``.
|
|
397
406
|
"""
|
|
407
|
+
if not isinstance(text, str):
|
|
408
|
+
text = str(text)
|
|
409
|
+
|
|
398
410
|
if is_web():
|
|
399
411
|
console_log(-1 if player_index is None else player_index, text, color)
|
|
400
412
|
else:
|
|
@@ -456,13 +468,19 @@ class CodeBattles(
|
|
|
456
468
|
|
|
457
469
|
self._initialized = True
|
|
458
470
|
|
|
459
|
-
def _initialize_simulation(
|
|
460
|
-
self
|
|
471
|
+
def _initialize_simulation(
|
|
472
|
+
self, player_codes: List[str], seed: Optional[int] = None
|
|
473
|
+
):
|
|
474
|
+
if seed is None:
|
|
475
|
+
seed = Random().randint(0, 2**128)
|
|
461
476
|
self._logs = []
|
|
462
477
|
self._decisions = []
|
|
463
478
|
self._decision_index = 0
|
|
479
|
+
self._seed = seed
|
|
480
|
+
self.step = 0
|
|
464
481
|
self.active_players = list(range(len(self.player_names)))
|
|
465
|
-
self.
|
|
482
|
+
self.random = Random(seed)
|
|
483
|
+
self.player_randoms = [Random(self.random.random()) for _ in self.player_names]
|
|
466
484
|
self.state = self.create_initial_state()
|
|
467
485
|
self.player_requests = [
|
|
468
486
|
self.create_initial_player_requests(i)
|
|
@@ -474,7 +492,11 @@ class CodeBattles(
|
|
|
474
492
|
self._start_time = time.time()
|
|
475
493
|
|
|
476
494
|
def _run_webworker_simulation(
|
|
477
|
-
self,
|
|
495
|
+
self,
|
|
496
|
+
map: str,
|
|
497
|
+
player_names_str: str,
|
|
498
|
+
player_codes_str: str,
|
|
499
|
+
seed: Optional[int] = None,
|
|
478
500
|
):
|
|
479
501
|
from pyscript import sync
|
|
480
502
|
|
|
@@ -487,7 +509,7 @@ class CodeBattles(
|
|
|
487
509
|
self.background = True
|
|
488
510
|
self.console_visible = False
|
|
489
511
|
self.verbose = False
|
|
490
|
-
self._initialize_simulation(player_codes)
|
|
512
|
+
self._initialize_simulation(player_codes, seed)
|
|
491
513
|
while not self.over:
|
|
492
514
|
self._logs = []
|
|
493
515
|
decisions = self.make_decisions()
|
|
@@ -505,16 +527,17 @@ class CodeBattles(
|
|
|
505
527
|
self.step += 1
|
|
506
528
|
|
|
507
529
|
def _run_local_simulation(self):
|
|
508
|
-
|
|
509
|
-
self.
|
|
530
|
+
seed = None if sys.argv[1] == "None" else int(sys.argv[1])
|
|
531
|
+
self.map = sys.argv[2]
|
|
532
|
+
self.player_names = sys.argv[3].split("-")
|
|
510
533
|
self.background = True
|
|
511
534
|
self.console_visible = False
|
|
512
535
|
self.verbose = False
|
|
513
536
|
player_codes = []
|
|
514
|
-
for filename in sys.argv[
|
|
537
|
+
for filename in sys.argv[4:]:
|
|
515
538
|
with open(filename, "r") as f:
|
|
516
539
|
player_codes.append(f.read())
|
|
517
|
-
self._initialize_simulation(player_codes)
|
|
540
|
+
self._initialize_simulation(player_codes, seed)
|
|
518
541
|
|
|
519
542
|
while not self.over:
|
|
520
543
|
self.apply_decisions(self.make_decisions())
|
|
@@ -589,7 +612,9 @@ class CodeBattles(
|
|
|
589
612
|
self.background = False
|
|
590
613
|
self.console_visible = True
|
|
591
614
|
self.verbose = False
|
|
592
|
-
self._initialize_simulation(
|
|
615
|
+
self._initialize_simulation(
|
|
616
|
+
["" for _ in simulation.player_names], simulation.seed
|
|
617
|
+
)
|
|
593
618
|
self._decisions = simulation.decisions
|
|
594
619
|
self._logs = simulation.logs
|
|
595
620
|
self.canvas = GameCanvas(
|
|
@@ -616,6 +641,7 @@ class CodeBattles(
|
|
|
616
641
|
background: bool,
|
|
617
642
|
console_visible: bool,
|
|
618
643
|
verbose: bool,
|
|
644
|
+
seed="",
|
|
619
645
|
):
|
|
620
646
|
from js import document
|
|
621
647
|
from pyscript import workers
|
|
@@ -635,7 +661,7 @@ class CodeBattles(
|
|
|
635
661
|
self.background = background
|
|
636
662
|
self.console_visible = console_visible
|
|
637
663
|
self.verbose = verbose
|
|
638
|
-
self._initialize_simulation(player_codes)
|
|
664
|
+
self._initialize_simulation(player_codes, None if seed == "" else int(seed))
|
|
639
665
|
|
|
640
666
|
if not self.background:
|
|
641
667
|
self.canvas = GameCanvas(
|
|
@@ -661,11 +687,11 @@ class CodeBattles(
|
|
|
661
687
|
document.getElementById("loader").style.display = "none"
|
|
662
688
|
self.render()
|
|
663
689
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
690
|
+
self._worker = await workers["worker"]
|
|
691
|
+
self._worker.update_step = self._update_step
|
|
692
|
+
self._worker._run_webworker_simulation(
|
|
693
|
+
map, json.dumps(player_names), json.dumps(player_codes), self._seed
|
|
694
|
+
)
|
|
669
695
|
|
|
670
696
|
if self.background:
|
|
671
697
|
await self._play_pause()
|
|
@@ -693,6 +719,7 @@ class CodeBattles(
|
|
|
693
719
|
datetime.datetime.now(),
|
|
694
720
|
self._logs,
|
|
695
721
|
self._decisions,
|
|
722
|
+
self._seed,
|
|
696
723
|
)
|
|
697
724
|
window.simulationToDownload = simulation.dump()
|
|
698
725
|
show_download()
|
|
@@ -721,8 +748,8 @@ class CodeBattles(
|
|
|
721
748
|
"context": context,
|
|
722
749
|
**self.get_api().__dict__,
|
|
723
750
|
}
|
|
724
|
-
| self.configure_bot_globals()
|
|
725
|
-
for context in contexts
|
|
751
|
+
| self.configure_bot_globals(player_index)
|
|
752
|
+
for player_index, context in enumerate(contexts)
|
|
726
753
|
]
|
|
727
754
|
for index, api_code in enumerate(player_codes):
|
|
728
755
|
if api_code != "" and api_code is not None:
|
|
@@ -820,7 +847,8 @@ class CodeBattles(
|
|
|
820
847
|
set_results(
|
|
821
848
|
self.player_names, self._eliminated[::-1], self.map, self.verbose
|
|
822
849
|
)
|
|
823
|
-
self.
|
|
850
|
+
if not self.background:
|
|
851
|
+
self.render()
|
|
824
852
|
|
|
825
853
|
if not self.background:
|
|
826
854
|
if self._since_last_render >= self.configure_render_rate(
|
package/dist/esm/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { initializeApp } from 'firebase/app';
|
|
|
10
10
|
import { onAuthStateChanged, signInWithEmailAndPassword, signOut, getAuth } from 'firebase/auth';
|
|
11
11
|
import { onSnapshot, refEqual, doc, getDoc, setDoc, Timestamp, getFirestore } from 'firebase/firestore';
|
|
12
12
|
import React, { useEffect, useReducer, useCallback, useMemo, createContext, useContext, useState, useRef, cloneElement, Component, createElement } from 'react';
|
|
13
|
-
import { useNavigate, useLocation, useParams, Routes, Route, BrowserRouter } from 'react-router-dom';
|
|
13
|
+
import { useNavigate, useLocation, useParams, useSearchParams, Routes, Route, BrowserRouter } from 'react-router-dom';
|
|
14
14
|
import { Dropzone } from '@mantine/dropzone';
|
|
15
15
|
import { jsx } from 'react/jsx-runtime';
|
|
16
16
|
|
|
@@ -409,11 +409,11 @@ const toPlacing = (n) => {
|
|
|
409
409
|
}
|
|
410
410
|
return n.toString() + DIGITS[n % 10];
|
|
411
411
|
};
|
|
412
|
-
const runNoUI = (map, apis, playerBots, verbose) => {
|
|
412
|
+
const runNoUI = (map, apis, playerBots, seed, verbose) => {
|
|
413
413
|
const players = playerBots.map((api) => (api === "None" ? "" : apis[api]));
|
|
414
414
|
tryUntilSuccess(() =>
|
|
415
415
|
// @ts-ignore
|
|
416
|
-
window._startSimulation(map, players, playerBots, true, false, verbose));
|
|
416
|
+
window._startSimulation(map, players, playerBots, true, false, verbose, seed));
|
|
417
417
|
};
|
|
418
418
|
const tryUntilSuccess = (f, timeout = 500) => {
|
|
419
419
|
try {
|
|
@@ -2502,6 +2502,10 @@ const RunSimulationBlock = () => {
|
|
|
2502
2502
|
key: "Player Bots",
|
|
2503
2503
|
defaultValue: ["None", "None"],
|
|
2504
2504
|
});
|
|
2505
|
+
const [seed, setSeed] = useLocalStorage({
|
|
2506
|
+
key: "Seed",
|
|
2507
|
+
defaultValue: "",
|
|
2508
|
+
});
|
|
2505
2509
|
const [runningNoUI, setRunningNoUI] = useState(false);
|
|
2506
2510
|
const [runningNoUIN, setRunningNoUIN] = useState({});
|
|
2507
2511
|
const navigate = useNavigate();
|
|
@@ -2512,15 +2516,16 @@ const RunSimulationBlock = () => {
|
|
|
2512
2516
|
const run = () => {
|
|
2513
2517
|
// @ts-ignore
|
|
2514
2518
|
window._isSimulationFromFile = false;
|
|
2515
|
-
navigate(`/simulation/${map.replaceAll(" ", "-")}/${playerBots.join("-")}`);
|
|
2519
|
+
navigate(`/simulation/${map.replaceAll(" ", "-")}/${playerBots.join("-")}?seed=${seed}`);
|
|
2516
2520
|
};
|
|
2517
2521
|
const startRunNoUI = () => {
|
|
2518
2522
|
setRunningNoUI(true);
|
|
2519
|
-
runNoUI(map, apis, playerBots, true);
|
|
2523
|
+
runNoUI(map, apis, playerBots, seed.toString(), true);
|
|
2520
2524
|
};
|
|
2521
2525
|
const startRunNoUIN = (n) => {
|
|
2526
|
+
setLocalStorage("Results", {});
|
|
2522
2527
|
setRunningNoUIN({ [n.toString()]: n });
|
|
2523
|
-
runNoUI(map, apis, playerBots, false);
|
|
2528
|
+
runNoUI(map, apis, playerBots, seed.toString(), false);
|
|
2524
2529
|
};
|
|
2525
2530
|
useEffect(() => {
|
|
2526
2531
|
// @ts-ignore
|
|
@@ -2574,7 +2579,7 @@ const RunSimulationBlock = () => {
|
|
|
2574
2579
|
setLocalStorage("Results", {});
|
|
2575
2580
|
}
|
|
2576
2581
|
else {
|
|
2577
|
-
runNoUI(map, apis, playerBots, false);
|
|
2582
|
+
runNoUI(map, apis, playerBots, seed.toString(), false);
|
|
2578
2583
|
}
|
|
2579
2584
|
}
|
|
2580
2585
|
}, [runningNoUIN]);
|
|
@@ -2585,6 +2590,7 @@ const RunSimulationBlock = () => {
|
|
|
2585
2590
|
}
|
|
2586
2591
|
} }),
|
|
2587
2592
|
React.createElement(BotSelector, { playerCount: playerCount, setPlayerCount: setPlayerCount, playerBots: playerBots, setPlayerBots: setPlayerBots, apis: apis }),
|
|
2593
|
+
React.createElement(NumberInput, { leftSection: React.createElement("i", { className: "fa-solid fa-dice" }), label: "Randomness Seed", min: 0, value: seed, onChange: setSeed }),
|
|
2588
2594
|
React.createElement(Button.Group, { mt: "xs" },
|
|
2589
2595
|
React.createElement(Button, { variant: "default", w: "50%", leftSection: React.createElement("i", { className: "fa-solid fa-play" }), onClick: run }, "Run"),
|
|
2590
2596
|
React.createElement(Button, { variant: "default", w: "50%", leftSection: React.createElement("i", { className: "fa-solid fa-forward" }), onClick: startRunNoUI, loading: runningNoUI || loading }, "Run (No UI)")),
|
|
@@ -14510,7 +14516,7 @@ const Round = () => {
|
|
|
14510
14516
|
}
|
|
14511
14517
|
useEffect(() => {
|
|
14512
14518
|
if (remaining > 0) {
|
|
14513
|
-
runNoUI(currentMap, apis, currentPlayers, false);
|
|
14519
|
+
runNoUI(currentMap, apis, currentPlayers, "", false);
|
|
14514
14520
|
}
|
|
14515
14521
|
}, [remaining]);
|
|
14516
14522
|
useEffect(updatePointModifier, [results]);
|
|
@@ -14569,7 +14575,7 @@ const Round = () => {
|
|
|
14569
14575
|
React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.map.replaceAll(" ", "-")}/${round.players.join("-")}?showcase=true`) }, "Simulate"),
|
|
14570
14576
|
React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-forward" }), size: "xs", onClick: () => {
|
|
14571
14577
|
if (roundIterations === 1) {
|
|
14572
|
-
runNoUI(round.map, apis, round.players, true);
|
|
14578
|
+
runNoUI(round.map, apis, round.players, "", true);
|
|
14573
14579
|
}
|
|
14574
14580
|
else {
|
|
14575
14581
|
currentMap = round.map;
|
|
@@ -15842,7 +15848,10 @@ const confetti = {
|
|
|
15842
15848
|
};
|
|
15843
15849
|
|
|
15844
15850
|
const AutoScrollButton = () => {
|
|
15845
|
-
const [autoScroll, setAutoScroll] =
|
|
15851
|
+
const [autoScroll, setAutoScroll] = useLocalStorage({
|
|
15852
|
+
key: "Auto Scroll",
|
|
15853
|
+
defaultValue: true,
|
|
15854
|
+
});
|
|
15846
15855
|
useEffect(() => {
|
|
15847
15856
|
// @ts-ignore
|
|
15848
15857
|
window.autoScroll = autoScroll;
|
|
@@ -15860,8 +15869,14 @@ const ShowLogsButtons = ({ playerNames, showLogs, setShowLogs, }) => {
|
|
|
15860
15869
|
};
|
|
15861
15870
|
|
|
15862
15871
|
const LogViewer = ({ playerNames }) => {
|
|
15863
|
-
const [showLogs, setShowLogs] =
|
|
15864
|
-
|
|
15872
|
+
const [showLogs, setShowLogs] = useLocalStorage({
|
|
15873
|
+
key: "Show Logs",
|
|
15874
|
+
defaultValue: [],
|
|
15875
|
+
});
|
|
15876
|
+
const [logs, setLogs] = useLocalStorage({
|
|
15877
|
+
key: "Logs",
|
|
15878
|
+
defaultValue: [],
|
|
15879
|
+
});
|
|
15865
15880
|
useEffect(() => {
|
|
15866
15881
|
// @ts-ignore
|
|
15867
15882
|
setShowLogs(playerNames.map(() => true));
|
|
@@ -15936,6 +15951,7 @@ const Simulation = () => {
|
|
|
15936
15951
|
const [apis, loading] = useAPIs();
|
|
15937
15952
|
let { map, playerapis } = useParams();
|
|
15938
15953
|
const location = useLocation();
|
|
15954
|
+
const [searchParams] = useSearchParams();
|
|
15939
15955
|
const [winner, setWinner] = useState();
|
|
15940
15956
|
const [downloadBytes, setDownloadBytes] = useState(false);
|
|
15941
15957
|
const navigate = useNavigate();
|
|
@@ -15977,14 +15993,16 @@ const Simulation = () => {
|
|
|
15977
15993
|
const playerNames = (_a = playerapis === null || playerapis === void 0 ? void 0 : playerapis.split("-")) !== null && _a !== void 0 ? _a : [];
|
|
15978
15994
|
const players = playerNames.map((api) => (api === "None" ? "" : apis[api]));
|
|
15979
15995
|
useEffect(() => {
|
|
15996
|
+
var _a;
|
|
15980
15997
|
if (!loading &&
|
|
15981
15998
|
players &&
|
|
15982
15999
|
playerapis &&
|
|
15983
16000
|
// @ts-ignore
|
|
15984
16001
|
window._isSimulationFromFile !== true) {
|
|
16002
|
+
const seed = (_a = searchParams.get("seed")) !== null && _a !== void 0 ? _a : "";
|
|
15985
16003
|
tryUntilSuccess(() =>
|
|
15986
16004
|
// @ts-ignore
|
|
15987
|
-
window._startSimulation(map, players, playerNames, false, !showcaseMode, true));
|
|
16005
|
+
window._startSimulation(map, players, playerNames, false, !showcaseMode, true, seed));
|
|
15988
16006
|
}
|
|
15989
16007
|
}, [loading]);
|
|
15990
16008
|
const newRank = getRank(getLocalStorage("Cached tournament/info"), winner, getLocalStorage("Point Modifier")) + 1;
|
|
@@ -10,6 +10,6 @@ export declare const getRank: (tournamentInfo: any, team: string, pointModifier:
|
|
|
10
10
|
export declare const updatePointModifier: () => void;
|
|
11
11
|
export declare const toPlacing: (n: number) => string;
|
|
12
12
|
export declare const zeroPad: (s: string, l: number) => string;
|
|
13
|
-
export declare const runNoUI: (map: string, apis: Record<string, any>, playerBots: string[], verbose: boolean) => void;
|
|
13
|
+
export declare const runNoUI: (map: string, apis: Record<string, any>, playerBots: string[], seed: string, verbose: boolean) => void;
|
|
14
14
|
export declare const tryUntilSuccess: (f: () => void, timeout?: number) => void;
|
|
15
15
|
export declare const downloadFile: (filename: string, mimeType: string, contents: string) => void;
|
package/package.json
CHANGED