code-battles 1.6.4 → 1.7.0
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 +81 -49
- package/dist/cjs/types/configuration.d.ts +2 -1
- package/dist/cjs/types/utilities.d.ts +2 -2
- package/dist/code_battles/__init__.py +1 -1
- package/dist/code_battles/battles.py +53 -28
- package/dist/code_battles/utilities.py +8 -3
- package/dist/esm/index.js +81 -49
- package/dist/esm/types/configuration.d.ts +2 -1
- package/dist/esm/types/utilities.d.ts +2 -2
- package/dist/index.d.ts +2 -1
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -374,8 +374,8 @@ const updatePointModifier = () => {
|
|
|
374
374
|
const pointModifier = {};
|
|
375
375
|
for (const round of rounds) {
|
|
376
376
|
if (results[round.players.join(", ")] &&
|
|
377
|
-
results[round.players.join(", ")][round.
|
|
378
|
-
for (const result of results[round.players.join(", ")][round.
|
|
377
|
+
results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
|
|
378
|
+
for (const result of results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
|
|
379
379
|
const first = round.players[result[0]];
|
|
380
380
|
const second = round.players[result[1]];
|
|
381
381
|
if (!pointModifier[first]) {
|
|
@@ -403,11 +403,11 @@ const toPlacing = (n) => {
|
|
|
403
403
|
}
|
|
404
404
|
return n.toString() + DIGITS[n % 10];
|
|
405
405
|
};
|
|
406
|
-
const runNoUI = (
|
|
406
|
+
const runNoUI = (parameters, apis, playerBots, seed, verbose) => {
|
|
407
407
|
const players = playerBots.map((api) => (api === "None" ? "" : apis[api]));
|
|
408
408
|
tryUntilSuccess(() =>
|
|
409
409
|
// @ts-ignore
|
|
410
|
-
window._startSimulation(
|
|
410
|
+
window._startSimulation(parameters, players, playerBots, true, false, verbose, seed));
|
|
411
411
|
};
|
|
412
412
|
const tryUntilSuccess = (f, timeout = 500) => {
|
|
413
413
|
try {
|
|
@@ -2466,7 +2466,7 @@ const PickBotBlock = () => {
|
|
|
2466
2466
|
|
|
2467
2467
|
const BotSelector = ({ playerCount, setPlayerCount, playerBots, setPlayerBots, apis, }) => {
|
|
2468
2468
|
return (React.createElement(React.Fragment, null,
|
|
2469
|
-
React.createElement(core.NumberInput, {
|
|
2469
|
+
React.createElement(core.NumberInput, { label: "Player Count", value: playerCount, min: 1, onChange: (c) => {
|
|
2470
2470
|
if (typeof c === "number") {
|
|
2471
2471
|
setPlayerCount(c);
|
|
2472
2472
|
while (playerBots.length < c) {
|
|
@@ -2489,9 +2489,9 @@ const BotSelector = ({ playerCount, setPlayerCount, playerBots, setPlayerBots, a
|
|
|
2489
2489
|
const RunSimulationBlock = () => {
|
|
2490
2490
|
const [apis, loading] = useAPIs();
|
|
2491
2491
|
const configuration = useConfiguration();
|
|
2492
|
-
const [
|
|
2493
|
-
key: "
|
|
2494
|
-
defaultValue:
|
|
2492
|
+
const [parameters, setParameters] = useLocalStorage({
|
|
2493
|
+
key: "Parameters",
|
|
2494
|
+
defaultValue: {},
|
|
2495
2495
|
});
|
|
2496
2496
|
const [playerCount, setPlayerCount] = useLocalStorage({
|
|
2497
2497
|
key: "Player Count",
|
|
@@ -2512,19 +2512,30 @@ const RunSimulationBlock = () => {
|
|
|
2512
2512
|
if (Object.keys(runningNoUIN).length === 1) {
|
|
2513
2513
|
remaining = Math.max(...Object.values(runningNoUIN));
|
|
2514
2514
|
}
|
|
2515
|
+
const getFullParameters = () => {
|
|
2516
|
+
var _a;
|
|
2517
|
+
const result = {};
|
|
2518
|
+
for (const key in configuration.parameters) {
|
|
2519
|
+
result[key] = (_a = parameters[key]) !== null && _a !== void 0 ? _a : configuration.parameters[key][0];
|
|
2520
|
+
}
|
|
2521
|
+
return result;
|
|
2522
|
+
};
|
|
2515
2523
|
const run = () => {
|
|
2516
2524
|
// @ts-ignore
|
|
2517
2525
|
window._isSimulationFromFile = false;
|
|
2518
|
-
|
|
2526
|
+
const params = getFullParameters();
|
|
2527
|
+
navigate(`/simulation/${playerBots.map(encodeURIComponent).join(",")}?seed=${seed === "-" ? "" : seed}&${Object.keys(params)
|
|
2528
|
+
.map((p) => `${p}=${encodeURIComponent(params[p])}`)
|
|
2529
|
+
.join("&")}`);
|
|
2519
2530
|
};
|
|
2520
2531
|
const startRunNoUI = () => {
|
|
2521
2532
|
setRunningNoUI(true);
|
|
2522
|
-
runNoUI(
|
|
2533
|
+
runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
|
|
2523
2534
|
};
|
|
2524
2535
|
const startRunNoUIN = (n) => {
|
|
2525
2536
|
setLocalStorage("Results", {});
|
|
2526
2537
|
setRunningNoUIN({ [n.toString()]: n });
|
|
2527
|
-
runNoUI(
|
|
2538
|
+
runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
|
|
2528
2539
|
};
|
|
2529
2540
|
React.useEffect(() => {
|
|
2530
2541
|
// @ts-ignore
|
|
@@ -2553,7 +2564,7 @@ const RunSimulationBlock = () => {
|
|
|
2553
2564
|
for (const key in runningNoUIN) {
|
|
2554
2565
|
if (runningNoUIN[key] == 0) {
|
|
2555
2566
|
const results = getLocalStorage("Results");
|
|
2556
|
-
const currentResults = results[playerBots.join(", ")][
|
|
2567
|
+
const currentResults = results[playerBots.join(", ")][JSON.stringify(getFullParameters())];
|
|
2557
2568
|
const winCounts = {};
|
|
2558
2569
|
for (const result of currentResults) {
|
|
2559
2570
|
const winner = playerBots[result[0]];
|
|
@@ -2578,16 +2589,18 @@ const RunSimulationBlock = () => {
|
|
|
2578
2589
|
setLocalStorage("Results", {});
|
|
2579
2590
|
}
|
|
2580
2591
|
else {
|
|
2581
|
-
runNoUI(
|
|
2592
|
+
runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
|
|
2582
2593
|
}
|
|
2583
2594
|
}
|
|
2584
2595
|
}, [runningNoUIN]);
|
|
2585
2596
|
return (React.createElement(Block, { title: "Run Simulation", logo: "fa-solid fa-display" },
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2597
|
+
Object.keys(configuration.parameters)
|
|
2598
|
+
.sort()
|
|
2599
|
+
.map((parameter, parameterIndex) => {
|
|
2600
|
+
var _a, _b;
|
|
2601
|
+
const icon = ((_a = configuration.parameterIcons) !== null && _a !== void 0 ? _a : {})[parameter];
|
|
2602
|
+
return (React.createElement(core.Select, { mb: "xs", key: parameterIndex, leftSection: icon ? React.createElement("i", { className: icon }) : undefined, label: parameter[0].toUpperCase() + parameter.slice(1), data: configuration.parameters[parameter], value: (_b = parameters[parameter]) !== null && _b !== void 0 ? _b : configuration.parameters[parameter][0], onChange: (s) => setParameters(Object.assign(Object.assign({}, parameters), { [parameter]: s !== null && s !== void 0 ? s : configuration.parameters[parameter][0] })) }));
|
|
2603
|
+
}),
|
|
2591
2604
|
React.createElement(BotSelector, { playerCount: playerCount, setPlayerCount: setPlayerCount, playerBots: playerBots, setPlayerBots: setPlayerBots, apis: apis }),
|
|
2592
2605
|
React.createElement(core.NumberInput, { mt: "xs", leftSection: React.createElement("i", { className: "fa-solid fa-dice" }), label: "Randomness Seed", min: 0, value: seed, onChange: setSeed }),
|
|
2593
2606
|
React.createElement(core.Button.Group, { mt: "xs" },
|
|
@@ -2775,7 +2788,7 @@ const NotFoundPage = () => {
|
|
|
2775
2788
|
React.createElement("p", null, "Make sure the URL is correct.")));
|
|
2776
2789
|
};
|
|
2777
2790
|
|
|
2778
|
-
let
|
|
2791
|
+
let currentParameters;
|
|
2779
2792
|
let currentPlayers;
|
|
2780
2793
|
const Round = () => {
|
|
2781
2794
|
const firestore$1 = useFirestore();
|
|
@@ -2791,9 +2804,9 @@ const Round = () => {
|
|
|
2791
2804
|
key: "Player Bots",
|
|
2792
2805
|
defaultValue: ["None", "None"],
|
|
2793
2806
|
});
|
|
2794
|
-
const [
|
|
2795
|
-
key: "
|
|
2796
|
-
defaultValue:
|
|
2807
|
+
const [parameters, setParameters] = useLocalStorage({
|
|
2808
|
+
key: "Parameters",
|
|
2809
|
+
defaultValue: {},
|
|
2797
2810
|
});
|
|
2798
2811
|
const [rounds, setRounds] = useLocalStorage({
|
|
2799
2812
|
key: "Rounds",
|
|
@@ -2833,9 +2846,17 @@ const Round = () => {
|
|
|
2833
2846
|
}
|
|
2834
2847
|
React.useEffect(() => {
|
|
2835
2848
|
if (remaining > 0) {
|
|
2836
|
-
runNoUI(
|
|
2849
|
+
runNoUI(currentParameters, apis, currentPlayers, "", false);
|
|
2837
2850
|
}
|
|
2838
2851
|
}, [remaining]);
|
|
2852
|
+
const getFullParameters = () => {
|
|
2853
|
+
var _a;
|
|
2854
|
+
const result = {};
|
|
2855
|
+
for (const key in configuration.parameters) {
|
|
2856
|
+
result[key] = (_a = parameters[key]) !== null && _a !== void 0 ? _a : configuration.parameters[key][0];
|
|
2857
|
+
}
|
|
2858
|
+
return result;
|
|
2859
|
+
};
|
|
2839
2860
|
React.useEffect(updatePointModifier, [results]);
|
|
2840
2861
|
return (React.createElement(React.Fragment, null,
|
|
2841
2862
|
React.createElement("div", { style: {
|
|
@@ -2848,7 +2869,7 @@ const Round = () => {
|
|
|
2848
2869
|
React.createElement("table", { style: { textAlign: "center" } },
|
|
2849
2870
|
React.createElement("thead", null,
|
|
2850
2871
|
React.createElement("tr", null,
|
|
2851
|
-
React.createElement("th", { style: { width: "25%" } }, "
|
|
2872
|
+
React.createElement("th", { style: { width: "25%" } }, "Parameters"),
|
|
2852
2873
|
React.createElement("th", { style: { width: "35%" } }, "Players"),
|
|
2853
2874
|
roundIterations === 1 && (React.createElement(React.Fragment, null,
|
|
2854
2875
|
React.createElement("th", { style: { width: "17.5%" } }, "1st Place"),
|
|
@@ -2858,7 +2879,7 @@ const Round = () => {
|
|
|
2858
2879
|
React.createElement("tbody", null, rounds.map((round, index) => {
|
|
2859
2880
|
const winCounts = {};
|
|
2860
2881
|
if (results[round.players.join(", ")] !== undefined) {
|
|
2861
|
-
const currentResults = results[round.players.join(", ")][round.
|
|
2882
|
+
const currentResults = results[round.players.join(", ")][JSON.stringify(round.parameters)];
|
|
2862
2883
|
for (const result of currentResults) {
|
|
2863
2884
|
const winner = round.players[result[0]];
|
|
2864
2885
|
if (!winCounts[winner]) {
|
|
@@ -2871,28 +2892,31 @@ const Round = () => {
|
|
|
2871
2892
|
}
|
|
2872
2893
|
const winners = Object.keys(winCounts).sort((a, b) => winCounts[b] - winCounts[a]);
|
|
2873
2894
|
return (React.createElement("tr", { key: index },
|
|
2874
|
-
React.createElement("td",
|
|
2895
|
+
React.createElement("td", { style: { whiteSpace: "pre" } }, Object.keys(round.parameters)
|
|
2896
|
+
.sort()
|
|
2897
|
+
.map((p) => `${p[0].toUpperCase()}${p.slice(1)}: ${round.parameters[p]}`)
|
|
2898
|
+
.join("\n")),
|
|
2875
2899
|
React.createElement("td", null, round.players.map((player, index) => (React.createElement("img", { key: index, src: `/images/teams/${player.toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } })))),
|
|
2876
2900
|
roundIterations === 1 && (React.createElement(React.Fragment, null,
|
|
2877
2901
|
React.createElement("td", null, results[round.players.join(", ")] !== undefined &&
|
|
2878
|
-
results[round.players.join(", ")][round.
|
|
2879
|
-
undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][round.map][0][0]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))),
|
|
2902
|
+
results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][0]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))),
|
|
2880
2903
|
React.createElement("td", null, results[round.players.join(", ")] !== undefined &&
|
|
2881
|
-
results[round.players.join(", ")][round.
|
|
2882
|
-
undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][round.map][0][1]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))))),
|
|
2904
|
+
results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][1]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))))),
|
|
2883
2905
|
roundIterations !== 1 && (React.createElement("td", null, winners.map((winner, index) => (React.createElement("p", { key: index },
|
|
2884
2906
|
winner,
|
|
2885
2907
|
": ",
|
|
2886
2908
|
winCounts[winner]))))),
|
|
2887
2909
|
React.createElement("td", null,
|
|
2888
2910
|
React.createElement(core.Button.Group, { orientation: "vertical" },
|
|
2889
|
-
React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.
|
|
2911
|
+
React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.players.map(encodeURIComponent).join(",")}?showcase=true&${Object.keys(round.parameters)
|
|
2912
|
+
.map((p) => `${p}=${encodeURIComponent(round.parameters[p])}`)
|
|
2913
|
+
.join("&")}`) }, "Simulate"),
|
|
2890
2914
|
React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-forward" }), size: "xs", onClick: () => {
|
|
2891
2915
|
if (roundIterations === 1) {
|
|
2892
|
-
runNoUI(round.
|
|
2916
|
+
runNoUI(round.parameters, apis, round.players, "", false);
|
|
2893
2917
|
}
|
|
2894
2918
|
else {
|
|
2895
|
-
|
|
2919
|
+
currentParameters = round.parameters;
|
|
2896
2920
|
currentPlayers = round.players;
|
|
2897
2921
|
startRunNoUIN(roundIterations);
|
|
2898
2922
|
}
|
|
@@ -2903,12 +2927,14 @@ const Round = () => {
|
|
|
2903
2927
|
"Remaining Simulations: ",
|
|
2904
2928
|
remaining)),
|
|
2905
2929
|
location.search.includes("edit") && (React.createElement(React.Fragment, null,
|
|
2906
|
-
React.createElement(core.NumberInput, { value: roundIterations, onChange: (v) => { var _a; return setRoundIterations((_a = parseInt(v.toString(), 10)) !== null && _a !== void 0 ? _a : 1); }, label: "Round Iterations", leftSection: React.createElement("i", { className: "fa-solid fa-hashtag" }) }),
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2930
|
+
React.createElement(core.NumberInput, { mb: "xs", value: roundIterations, onChange: (v) => { var _a; return setRoundIterations((_a = parseInt(v.toString(), 10)) !== null && _a !== void 0 ? _a : 1); }, label: "Round Iterations", leftSection: React.createElement("i", { className: "fa-solid fa-hashtag" }) }),
|
|
2931
|
+
Object.keys(configuration.parameters)
|
|
2932
|
+
.sort()
|
|
2933
|
+
.map((parameter, parameterIndex) => {
|
|
2934
|
+
var _a, _b;
|
|
2935
|
+
const icon = ((_a = configuration.parameterIcons) !== null && _a !== void 0 ? _a : {})[parameter];
|
|
2936
|
+
return (React.createElement(core.Select, { key: parameterIndex, mb: "xs", leftSection: icon ? React.createElement("i", { className: icon }) : undefined, label: parameter[0].toUpperCase() + parameter.slice(1), data: configuration.parameters[parameter], value: (_b = parameters[parameter]) !== null && _b !== void 0 ? _b : configuration.parameters[parameter][0], onChange: (s) => setParameters(Object.assign(Object.assign({}, parameters), { [parameter]: s !== null && s !== void 0 ? s : configuration.parameters[parameter][0] })) }));
|
|
2937
|
+
}),
|
|
2912
2938
|
React.createElement(BotSelector, { playerCount: playerCount, setPlayerCount: setPlayerCount, playerBots: playerBots, setPlayerBots: setPlayerBots, apis: apis }),
|
|
2913
2939
|
React.createElement(core.Button, { color: "red", leftSection: React.createElement("i", { className: "fa-solid fa-trash" }), mt: "xs", onClick: () => {
|
|
2914
2940
|
setRounds([]);
|
|
@@ -2920,7 +2946,10 @@ const Round = () => {
|
|
|
2920
2946
|
React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-plus" }), mt: "xs", onClick: () => {
|
|
2921
2947
|
setRounds((rounds) => [
|
|
2922
2948
|
...rounds,
|
|
2923
|
-
{
|
|
2949
|
+
{
|
|
2950
|
+
players: playerBots,
|
|
2951
|
+
parameters: Object.assign({}, getFullParameters()),
|
|
2952
|
+
},
|
|
2924
2953
|
]);
|
|
2925
2954
|
}, style: { width: "30%" } }, "Add"),
|
|
2926
2955
|
React.createElement(core.Button, { leftSection: React.createElement("i", { className: "fa-solid fa-save" }), fullWidth: true, mt: "xs", onClick: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -2940,7 +2969,7 @@ const Round = () => {
|
|
|
2940
2969
|
80, 80, 80, 80,
|
|
2941
2970
|
]) {
|
|
2942
2971
|
setRounds((rounds) => rounds.map((round) => ({
|
|
2943
|
-
|
|
2972
|
+
parameters: round.parameters,
|
|
2944
2973
|
players: shuffle(round.players),
|
|
2945
2974
|
})));
|
|
2946
2975
|
yield new Promise((resolve) => setTimeout(resolve, timeout));
|
|
@@ -3108,7 +3137,7 @@ const Simulation = () => {
|
|
|
3108
3137
|
var _a, _b, _c, _d;
|
|
3109
3138
|
const admin = useAdmin();
|
|
3110
3139
|
const [apis, loading] = useAPIs();
|
|
3111
|
-
let {
|
|
3140
|
+
let { playerapis } = reactRouterDom.useParams();
|
|
3112
3141
|
const location = reactRouterDom.useLocation();
|
|
3113
3142
|
const [searchParams] = reactRouterDom.useSearchParams();
|
|
3114
3143
|
const [winner, setWinner] = React.useState();
|
|
@@ -3147,7 +3176,10 @@ const Simulation = () => {
|
|
|
3147
3176
|
}
|
|
3148
3177
|
};
|
|
3149
3178
|
}, []);
|
|
3150
|
-
|
|
3179
|
+
const parameters = Object.fromEntries(searchParams);
|
|
3180
|
+
if (parameters.seed) {
|
|
3181
|
+
delete parameters.seed;
|
|
3182
|
+
}
|
|
3151
3183
|
playerapis = playerapis === null || playerapis === void 0 ? void 0 : playerapis.split("&")[0];
|
|
3152
3184
|
const playerNames = (_a = playerapis === null || playerapis === void 0 ? void 0 : playerapis.split(",").map(decodeURIComponent)) !== null && _a !== void 0 ? _a : [];
|
|
3153
3185
|
const players = playerNames.map((api) => (api === "None" ? "" : apis[api]));
|
|
@@ -3161,7 +3193,7 @@ const Simulation = () => {
|
|
|
3161
3193
|
const seed = (_a = searchParams.get("seed")) !== null && _a !== void 0 ? _a : "";
|
|
3162
3194
|
tryUntilSuccess(() =>
|
|
3163
3195
|
// @ts-ignore
|
|
3164
|
-
window._startSimulation(
|
|
3196
|
+
window._startSimulation(parameters, players, playerNames, false, !showcaseMode, true, seed));
|
|
3165
3197
|
}
|
|
3166
3198
|
}, [loading]);
|
|
3167
3199
|
const newRank = getRank(getLocalStorage("Cached tournament/info"), winner, getLocalStorage("Point Modifier")) + 1;
|
|
@@ -3314,7 +3346,7 @@ const App = ({ routes, blocks }) => {
|
|
|
3314
3346
|
React.createElement(reactRouterDom.Routes, null,
|
|
3315
3347
|
React.createElement(reactRouterDom.Route, { path: "/", element: React.createElement(HomePage, { blocks: blocks }) }),
|
|
3316
3348
|
React.createElement(reactRouterDom.Route, { path: "/view/:apiname", element: React.createElement(ViewAPI, null) }),
|
|
3317
|
-
React.createElement(reactRouterDom.Route, { path: "/simulation/:
|
|
3349
|
+
React.createElement(reactRouterDom.Route, { path: "/simulation/:playerapis", element: React.createElement(Simulation, null) }),
|
|
3318
3350
|
React.createElement(reactRouterDom.Route, { path: "/round", element: React.createElement(Round, null) }),
|
|
3319
3351
|
React.createElement(reactRouterDom.Route, { path: "/settings", element: React.createElement(SettingsPage, null) }),
|
|
3320
3352
|
React.createElement(reactRouterDom.Route, { path: "*", element: React.createElement(NotFoundPage, null) }),
|
|
@@ -5718,15 +5750,15 @@ const initialize = () => {
|
|
|
5718
5750
|
}
|
|
5719
5751
|
};
|
|
5720
5752
|
// @ts-ignore
|
|
5721
|
-
window.setResults = (playerNames, places,
|
|
5753
|
+
window.setResults = (playerNames, places, parameters, verbose) => {
|
|
5722
5754
|
const results = getLocalStorage("Results");
|
|
5723
5755
|
if (!results[playerNames.join(", ")]) {
|
|
5724
5756
|
results[playerNames.join(", ")] = {};
|
|
5725
5757
|
}
|
|
5726
|
-
if (!results[playerNames.join(", ")][
|
|
5727
|
-
results[playerNames.join(", ")][
|
|
5758
|
+
if (!results[playerNames.join(", ")][JSON.stringify(parameters)]) {
|
|
5759
|
+
results[playerNames.join(", ")][JSON.stringify(parameters)] = [];
|
|
5728
5760
|
}
|
|
5729
|
-
results[playerNames.join(", ")][
|
|
5761
|
+
results[playerNames.join(", ")][JSON.stringify(parameters)].push(places);
|
|
5730
5762
|
setLocalStorage("Results", results);
|
|
5731
5763
|
updatePointModifier();
|
|
5732
5764
|
// @ts-ignore
|
|
@@ -3,7 +3,7 @@ import type { Auth } from "firebase/auth";
|
|
|
3
3
|
import type { Firestore } from "firebase/firestore";
|
|
4
4
|
interface CodeBattlesRequiredConfiguration {
|
|
5
5
|
firebase: any;
|
|
6
|
-
|
|
6
|
+
parameters: Record<string, string[]>;
|
|
7
7
|
}
|
|
8
8
|
interface CodeBattlesDatesConfiguration {
|
|
9
9
|
locale?: string;
|
|
@@ -19,6 +19,7 @@ interface CodeBattlesOptionalConfiguration {
|
|
|
19
19
|
authentication: Auth;
|
|
20
20
|
runningCountOptions?: number[];
|
|
21
21
|
dates?: CodeBattlesDatesConfiguration;
|
|
22
|
+
parameterIcons?: Record<string, string>;
|
|
22
23
|
}
|
|
23
24
|
export interface CodeBattlesConfiguration extends CodeBattlesRequiredConfiguration, Partial<CodeBattlesOptionalConfiguration> {
|
|
24
25
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface RoundInfo {
|
|
2
2
|
players: string[];
|
|
3
|
-
|
|
3
|
+
parameters: Record<string, string>;
|
|
4
4
|
}
|
|
5
5
|
export declare const getLocalStorage: (key: string, defaultValue?: {}) => any;
|
|
6
6
|
export declare const setLocalStorage: (key: string, value?: {}) => void;
|
|
@@ -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: (
|
|
13
|
+
export declare const runNoUI: (parameters: Record<string, 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;
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import base64
|
|
3
|
-
from dataclasses import dataclass
|
|
4
3
|
import datetime
|
|
4
|
+
import gzip
|
|
5
5
|
import json
|
|
6
6
|
import math
|
|
7
|
-
import time
|
|
8
|
-
from random import Random
|
|
9
7
|
import sys
|
|
8
|
+
import time
|
|
10
9
|
import traceback
|
|
11
|
-
import
|
|
10
|
+
import typing
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from random import Random
|
|
13
|
+
from typing import Any, Dict, Generic, List, Optional, Set, Tuple, TypeVar
|
|
12
14
|
from urllib.parse import quote
|
|
13
15
|
|
|
14
|
-
from typing import Any, Dict, Generic, List, Optional, Set, Tuple, TypeVar
|
|
15
|
-
import typing
|
|
16
16
|
from code_battles.utilities import (
|
|
17
17
|
GameCanvas,
|
|
18
18
|
console_log,
|
|
19
19
|
download_image,
|
|
20
|
+
is_web,
|
|
20
21
|
is_worker,
|
|
21
22
|
navigate,
|
|
22
23
|
set_results,
|
|
23
24
|
show_alert,
|
|
24
25
|
show_download,
|
|
25
26
|
web_only,
|
|
26
|
-
is_web,
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
try:
|
|
@@ -39,7 +39,7 @@ PlayerRequestsType = TypeVar("PlayerRequestsType")
|
|
|
39
39
|
|
|
40
40
|
@dataclass
|
|
41
41
|
class Simulation:
|
|
42
|
-
|
|
42
|
+
parameters: Dict[str, str]
|
|
43
43
|
player_names: str
|
|
44
44
|
game: str
|
|
45
45
|
version: str
|
|
@@ -53,7 +53,7 @@ class Simulation:
|
|
|
53
53
|
gzip.compress(
|
|
54
54
|
json.dumps(
|
|
55
55
|
{
|
|
56
|
-
"
|
|
56
|
+
"parameters": self.parameters,
|
|
57
57
|
"playerNames": self.player_names,
|
|
58
58
|
"game": self.game,
|
|
59
59
|
"version": self.version,
|
|
@@ -73,7 +73,9 @@ class Simulation:
|
|
|
73
73
|
def load(file: str):
|
|
74
74
|
contents: Dict[str, Any] = json.loads(gzip.decompress(base64.b64decode(file)))
|
|
75
75
|
return Simulation(
|
|
76
|
-
contents["
|
|
76
|
+
contents["parameters"]
|
|
77
|
+
if "parameters" in contents
|
|
78
|
+
else {"map": contents["map"]},
|
|
77
79
|
contents["playerNames"],
|
|
78
80
|
contents["game"],
|
|
79
81
|
contents["version"],
|
|
@@ -105,6 +107,8 @@ class CodeBattles(
|
|
|
105
107
|
|
|
106
108
|
player_names: List[str]
|
|
107
109
|
"""The name of the players. This is populated before any of the overridable methods run."""
|
|
110
|
+
parameters: Dict[str, str]
|
|
111
|
+
"""The parameters of the simulation. This is populated before any of the overridable methods run."""
|
|
108
112
|
map: str
|
|
109
113
|
"""The name of the map. This is populated before any of the overridable methods run."""
|
|
110
114
|
map_image: "js.Image"
|
|
@@ -358,12 +362,13 @@ class CodeBattles(
|
|
|
358
362
|
await ff.load()
|
|
359
363
|
document.fonts.add(ff)
|
|
360
364
|
|
|
361
|
-
def run_bot_method(self, player_index: int, method_name: str):
|
|
365
|
+
def run_bot_method(self, player_index: int, method_name: str) -> float:
|
|
362
366
|
"""
|
|
363
|
-
Runs the
|
|
367
|
+
Runs the specified method of the given player and returns the time it took (in seconds).
|
|
364
368
|
|
|
365
369
|
Upon exception, shows an alert (does not terminate the bot).
|
|
366
370
|
"""
|
|
371
|
+
start = time.time()
|
|
367
372
|
|
|
368
373
|
assert player_index in self.active_players
|
|
369
374
|
|
|
@@ -392,6 +397,9 @@ class CodeBattles(
|
|
|
392
397
|
"fa-solid fa-exclamation",
|
|
393
398
|
)
|
|
394
399
|
|
|
400
|
+
end = time.time()
|
|
401
|
+
return end - start
|
|
402
|
+
|
|
395
403
|
def eliminate_player(self, player_index: int, reason=""):
|
|
396
404
|
"""Eliminate the specified player for the specified reason from the simulation."""
|
|
397
405
|
|
|
@@ -468,7 +476,7 @@ class CodeBattles(
|
|
|
468
476
|
|
|
469
477
|
If ``force`` is set, will play the sound even if the simulation is not :attr:`verbose`.
|
|
470
478
|
"""
|
|
471
|
-
from js import
|
|
479
|
+
from js import Audio, window
|
|
472
480
|
|
|
473
481
|
if not force and not self.verbose:
|
|
474
482
|
return
|
|
@@ -521,7 +529,7 @@ class CodeBattles(
|
|
|
521
529
|
|
|
522
530
|
@web_only
|
|
523
531
|
def _initialize(self):
|
|
524
|
-
from js import
|
|
532
|
+
from js import document, window
|
|
525
533
|
from pyscript.ffi import create_proxy
|
|
526
534
|
|
|
527
535
|
window.addEventListener("resize", create_proxy(lambda _: self._resize_canvas()))
|
|
@@ -565,7 +573,7 @@ class CodeBattles(
|
|
|
565
573
|
|
|
566
574
|
def _run_webworker_simulation(
|
|
567
575
|
self,
|
|
568
|
-
|
|
576
|
+
parameters: Dict[str, str],
|
|
569
577
|
player_names_str: str,
|
|
570
578
|
player_codes_str: str,
|
|
571
579
|
seed: Optional[int] = None,
|
|
@@ -573,10 +581,12 @@ class CodeBattles(
|
|
|
573
581
|
from pyscript import sync
|
|
574
582
|
|
|
575
583
|
# JS to Python
|
|
584
|
+
parameters = json.loads(parameters)
|
|
576
585
|
player_names = json.loads(player_names_str)
|
|
577
586
|
player_codes = json.loads(player_codes_str)
|
|
578
587
|
|
|
579
|
-
self.
|
|
588
|
+
self.parameters = parameters
|
|
589
|
+
self.map = parameters.get("map")
|
|
580
590
|
self.player_names = player_names
|
|
581
591
|
self.background = True
|
|
582
592
|
self.console_visible = False
|
|
@@ -589,7 +599,10 @@ class CodeBattles(
|
|
|
589
599
|
decisions = self._make_decisions()
|
|
590
600
|
logs = self._logs
|
|
591
601
|
alerts = self._alerts
|
|
602
|
+
log = self.log
|
|
603
|
+
self.log = lambda *args, **kwargs: None
|
|
592
604
|
self.apply_decisions(decisions)
|
|
605
|
+
self.log = log
|
|
593
606
|
|
|
594
607
|
sync.update_step(
|
|
595
608
|
base64.b64encode(decisions).decode(),
|
|
@@ -620,7 +633,8 @@ class CodeBattles(
|
|
|
620
633
|
contents = f.read()
|
|
621
634
|
simulation = Simulation.load(contents)
|
|
622
635
|
seed = simulation.seed
|
|
623
|
-
self.
|
|
636
|
+
self.parameters = simulation.parameters
|
|
637
|
+
self.map = simulation.parameters.get("map")
|
|
624
638
|
self.player_names = simulation.player_names
|
|
625
639
|
decisions = simulation.decisions
|
|
626
640
|
player_codes = ["" for _ in simulation.player_names]
|
|
@@ -684,12 +698,15 @@ class CodeBattles(
|
|
|
684
698
|
|
|
685
699
|
try:
|
|
686
700
|
simulation = Simulation.load(str(contents))
|
|
701
|
+
parameters = "&".join(
|
|
702
|
+
[f"{p}={quote(v)}" for p, v in simulation.parameters.items()]
|
|
703
|
+
)
|
|
687
704
|
navigate(
|
|
688
|
-
f"/simulation/{
|
|
705
|
+
f"/simulation/{','.join([quote(player_name) for player_name in simulation.player_names])}?seed={simulation.seed}&{parameters}"
|
|
689
706
|
)
|
|
690
707
|
self.alert(
|
|
691
708
|
"Loaded simulation file!",
|
|
692
|
-
f"{', '.join(simulation.player_names)} competed
|
|
709
|
+
f"{', '.join(simulation.player_names)} competed with {simulation.parameters} at {simulation.timestamp}",
|
|
693
710
|
"blue",
|
|
694
711
|
"fa-solid fa-file-code",
|
|
695
712
|
0,
|
|
@@ -713,9 +730,10 @@ class CodeBattles(
|
|
|
713
730
|
while document.getElementById("loader") is None:
|
|
714
731
|
await asyncio.sleep(0.01)
|
|
715
732
|
self._initialize()
|
|
716
|
-
self.
|
|
733
|
+
self.parameters = simulation.parameters
|
|
734
|
+
self.map = self.parameters.get("map")
|
|
717
735
|
self.map_image = await download_image(
|
|
718
|
-
self.configure_map_image_url(
|
|
736
|
+
self.configure_map_image_url(self.map)
|
|
719
737
|
)
|
|
720
738
|
self.player_names = simulation.player_names
|
|
721
739
|
self.background = False
|
|
@@ -744,7 +762,7 @@ class CodeBattles(
|
|
|
744
762
|
@web_only
|
|
745
763
|
async def _start_simulation_async(
|
|
746
764
|
self,
|
|
747
|
-
|
|
765
|
+
parameters: Dict[str, str],
|
|
748
766
|
player_codes: List[str],
|
|
749
767
|
player_names: List[str],
|
|
750
768
|
background: bool,
|
|
@@ -758,15 +776,19 @@ class CodeBattles(
|
|
|
758
776
|
# JS to Python
|
|
759
777
|
player_names = [str(x) for x in player_names]
|
|
760
778
|
player_codes = [str(x) for x in player_codes]
|
|
779
|
+
parameters = parameters.to_py()
|
|
761
780
|
|
|
762
781
|
try:
|
|
763
782
|
render_status = document.getElementById("render-status")
|
|
764
783
|
if render_status is not None:
|
|
765
784
|
render_status.textContent = "Rendering: Initializing..."
|
|
766
785
|
|
|
767
|
-
self.
|
|
786
|
+
self.parameters = parameters
|
|
787
|
+
self.map = parameters.get("map")
|
|
768
788
|
self.player_names = player_names
|
|
769
|
-
self.map_image = await download_image(
|
|
789
|
+
self.map_image = await download_image(
|
|
790
|
+
self.configure_map_image_url(self.map)
|
|
791
|
+
)
|
|
770
792
|
self.background = background
|
|
771
793
|
self.console_visible = console_visible
|
|
772
794
|
self.verbose = verbose
|
|
@@ -794,7 +816,10 @@ class CodeBattles(
|
|
|
794
816
|
self._worker = await workers["worker"]
|
|
795
817
|
self._worker.update_step = self._update_step
|
|
796
818
|
self._worker._run_webworker_simulation(
|
|
797
|
-
|
|
819
|
+
json.dumps(parameters),
|
|
820
|
+
json.dumps(player_names),
|
|
821
|
+
json.dumps(player_codes),
|
|
822
|
+
self._seed,
|
|
798
823
|
)
|
|
799
824
|
|
|
800
825
|
if self.background:
|
|
@@ -824,7 +849,7 @@ class CodeBattles(
|
|
|
824
849
|
|
|
825
850
|
def _get_simulation(self):
|
|
826
851
|
return Simulation(
|
|
827
|
-
self.
|
|
852
|
+
self.parameters,
|
|
828
853
|
self.player_names,
|
|
829
854
|
self.__class__.__name__,
|
|
830
855
|
self.configure_version(),
|
|
@@ -842,7 +867,7 @@ class CodeBattles(
|
|
|
842
867
|
is_over_str: str,
|
|
843
868
|
should_pause_str: str,
|
|
844
869
|
):
|
|
845
|
-
from js import
|
|
870
|
+
from js import document, window
|
|
846
871
|
|
|
847
872
|
now = time.time()
|
|
848
873
|
decisions = base64.b64decode(str(decisions_str))
|
|
@@ -1020,7 +1045,7 @@ class CodeBattles(
|
|
|
1020
1045
|
if len(self.active_players) == 1:
|
|
1021
1046
|
self._eliminated.append(self.active_players[0])
|
|
1022
1047
|
set_results(
|
|
1023
|
-
self.player_names, self._eliminated[::-1], self.
|
|
1048
|
+
self.player_names, self._eliminated[::-1], self.parameters, self.verbose
|
|
1024
1049
|
)
|
|
1025
1050
|
if not self.background:
|
|
1026
1051
|
self.render()
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import math
|
|
5
5
|
import sys
|
|
6
|
-
from typing import Callable, List, Union
|
|
7
6
|
from enum import Enum
|
|
8
7
|
from functools import wraps
|
|
8
|
+
from typing import Callable, Dict, List, Union
|
|
9
9
|
|
|
10
10
|
try:
|
|
11
11
|
import js
|
|
@@ -73,12 +73,17 @@ def show_alert(
|
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
@web_only
|
|
76
|
-
def set_results(
|
|
76
|
+
def set_results(
|
|
77
|
+
player_names: List[str],
|
|
78
|
+
places: List[int],
|
|
79
|
+
parameters: Dict[str, str],
|
|
80
|
+
verbose: bool,
|
|
81
|
+
):
|
|
77
82
|
from js import window
|
|
78
83
|
|
|
79
84
|
if hasattr(window, "setResults"):
|
|
80
85
|
try:
|
|
81
|
-
window.setResults(player_names, places,
|
|
86
|
+
window.setResults(player_names, places, parameters, verbose)
|
|
82
87
|
except Exception as e:
|
|
83
88
|
print(e)
|
|
84
89
|
|
package/dist/esm/index.js
CHANGED
|
@@ -372,8 +372,8 @@ const updatePointModifier = () => {
|
|
|
372
372
|
const pointModifier = {};
|
|
373
373
|
for (const round of rounds) {
|
|
374
374
|
if (results[round.players.join(", ")] &&
|
|
375
|
-
results[round.players.join(", ")][round.
|
|
376
|
-
for (const result of results[round.players.join(", ")][round.
|
|
375
|
+
results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
|
|
376
|
+
for (const result of results[round.players.join(", ")][JSON.stringify(round.parameters)]) {
|
|
377
377
|
const first = round.players[result[0]];
|
|
378
378
|
const second = round.players[result[1]];
|
|
379
379
|
if (!pointModifier[first]) {
|
|
@@ -401,11 +401,11 @@ const toPlacing = (n) => {
|
|
|
401
401
|
}
|
|
402
402
|
return n.toString() + DIGITS[n % 10];
|
|
403
403
|
};
|
|
404
|
-
const runNoUI = (
|
|
404
|
+
const runNoUI = (parameters, apis, playerBots, seed, verbose) => {
|
|
405
405
|
const players = playerBots.map((api) => (api === "None" ? "" : apis[api]));
|
|
406
406
|
tryUntilSuccess(() =>
|
|
407
407
|
// @ts-ignore
|
|
408
|
-
window._startSimulation(
|
|
408
|
+
window._startSimulation(parameters, players, playerBots, true, false, verbose, seed));
|
|
409
409
|
};
|
|
410
410
|
const tryUntilSuccess = (f, timeout = 500) => {
|
|
411
411
|
try {
|
|
@@ -2464,7 +2464,7 @@ const PickBotBlock = () => {
|
|
|
2464
2464
|
|
|
2465
2465
|
const BotSelector = ({ playerCount, setPlayerCount, playerBots, setPlayerBots, apis, }) => {
|
|
2466
2466
|
return (React.createElement(React.Fragment, null,
|
|
2467
|
-
React.createElement(NumberInput, {
|
|
2467
|
+
React.createElement(NumberInput, { label: "Player Count", value: playerCount, min: 1, onChange: (c) => {
|
|
2468
2468
|
if (typeof c === "number") {
|
|
2469
2469
|
setPlayerCount(c);
|
|
2470
2470
|
while (playerBots.length < c) {
|
|
@@ -2487,9 +2487,9 @@ const BotSelector = ({ playerCount, setPlayerCount, playerBots, setPlayerBots, a
|
|
|
2487
2487
|
const RunSimulationBlock = () => {
|
|
2488
2488
|
const [apis, loading] = useAPIs();
|
|
2489
2489
|
const configuration = useConfiguration();
|
|
2490
|
-
const [
|
|
2491
|
-
key: "
|
|
2492
|
-
defaultValue:
|
|
2490
|
+
const [parameters, setParameters] = useLocalStorage({
|
|
2491
|
+
key: "Parameters",
|
|
2492
|
+
defaultValue: {},
|
|
2493
2493
|
});
|
|
2494
2494
|
const [playerCount, setPlayerCount] = useLocalStorage({
|
|
2495
2495
|
key: "Player Count",
|
|
@@ -2510,19 +2510,30 @@ const RunSimulationBlock = () => {
|
|
|
2510
2510
|
if (Object.keys(runningNoUIN).length === 1) {
|
|
2511
2511
|
remaining = Math.max(...Object.values(runningNoUIN));
|
|
2512
2512
|
}
|
|
2513
|
+
const getFullParameters = () => {
|
|
2514
|
+
var _a;
|
|
2515
|
+
const result = {};
|
|
2516
|
+
for (const key in configuration.parameters) {
|
|
2517
|
+
result[key] = (_a = parameters[key]) !== null && _a !== void 0 ? _a : configuration.parameters[key][0];
|
|
2518
|
+
}
|
|
2519
|
+
return result;
|
|
2520
|
+
};
|
|
2513
2521
|
const run = () => {
|
|
2514
2522
|
// @ts-ignore
|
|
2515
2523
|
window._isSimulationFromFile = false;
|
|
2516
|
-
|
|
2524
|
+
const params = getFullParameters();
|
|
2525
|
+
navigate(`/simulation/${playerBots.map(encodeURIComponent).join(",")}?seed=${seed === "-" ? "" : seed}&${Object.keys(params)
|
|
2526
|
+
.map((p) => `${p}=${encodeURIComponent(params[p])}`)
|
|
2527
|
+
.join("&")}`);
|
|
2517
2528
|
};
|
|
2518
2529
|
const startRunNoUI = () => {
|
|
2519
2530
|
setRunningNoUI(true);
|
|
2520
|
-
runNoUI(
|
|
2531
|
+
runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
|
|
2521
2532
|
};
|
|
2522
2533
|
const startRunNoUIN = (n) => {
|
|
2523
2534
|
setLocalStorage("Results", {});
|
|
2524
2535
|
setRunningNoUIN({ [n.toString()]: n });
|
|
2525
|
-
runNoUI(
|
|
2536
|
+
runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
|
|
2526
2537
|
};
|
|
2527
2538
|
useEffect(() => {
|
|
2528
2539
|
// @ts-ignore
|
|
@@ -2551,7 +2562,7 @@ const RunSimulationBlock = () => {
|
|
|
2551
2562
|
for (const key in runningNoUIN) {
|
|
2552
2563
|
if (runningNoUIN[key] == 0) {
|
|
2553
2564
|
const results = getLocalStorage("Results");
|
|
2554
|
-
const currentResults = results[playerBots.join(", ")][
|
|
2565
|
+
const currentResults = results[playerBots.join(", ")][JSON.stringify(getFullParameters())];
|
|
2555
2566
|
const winCounts = {};
|
|
2556
2567
|
for (const result of currentResults) {
|
|
2557
2568
|
const winner = playerBots[result[0]];
|
|
@@ -2576,16 +2587,18 @@ const RunSimulationBlock = () => {
|
|
|
2576
2587
|
setLocalStorage("Results", {});
|
|
2577
2588
|
}
|
|
2578
2589
|
else {
|
|
2579
|
-
runNoUI(
|
|
2590
|
+
runNoUI(getFullParameters(), apis, playerBots, seed.toString(), false);
|
|
2580
2591
|
}
|
|
2581
2592
|
}
|
|
2582
2593
|
}, [runningNoUIN]);
|
|
2583
2594
|
return (React.createElement(Block, { title: "Run Simulation", logo: "fa-solid fa-display" },
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2595
|
+
Object.keys(configuration.parameters)
|
|
2596
|
+
.sort()
|
|
2597
|
+
.map((parameter, parameterIndex) => {
|
|
2598
|
+
var _a, _b;
|
|
2599
|
+
const icon = ((_a = configuration.parameterIcons) !== null && _a !== void 0 ? _a : {})[parameter];
|
|
2600
|
+
return (React.createElement(Select, { mb: "xs", key: parameterIndex, leftSection: icon ? React.createElement("i", { className: icon }) : undefined, label: parameter[0].toUpperCase() + parameter.slice(1), data: configuration.parameters[parameter], value: (_b = parameters[parameter]) !== null && _b !== void 0 ? _b : configuration.parameters[parameter][0], onChange: (s) => setParameters(Object.assign(Object.assign({}, parameters), { [parameter]: s !== null && s !== void 0 ? s : configuration.parameters[parameter][0] })) }));
|
|
2601
|
+
}),
|
|
2589
2602
|
React.createElement(BotSelector, { playerCount: playerCount, setPlayerCount: setPlayerCount, playerBots: playerBots, setPlayerBots: setPlayerBots, apis: apis }),
|
|
2590
2603
|
React.createElement(NumberInput, { mt: "xs", leftSection: React.createElement("i", { className: "fa-solid fa-dice" }), label: "Randomness Seed", min: 0, value: seed, onChange: setSeed }),
|
|
2591
2604
|
React.createElement(Button.Group, { mt: "xs" },
|
|
@@ -2773,7 +2786,7 @@ const NotFoundPage = () => {
|
|
|
2773
2786
|
React.createElement("p", null, "Make sure the URL is correct.")));
|
|
2774
2787
|
};
|
|
2775
2788
|
|
|
2776
|
-
let
|
|
2789
|
+
let currentParameters;
|
|
2777
2790
|
let currentPlayers;
|
|
2778
2791
|
const Round = () => {
|
|
2779
2792
|
const firestore = useFirestore();
|
|
@@ -2789,9 +2802,9 @@ const Round = () => {
|
|
|
2789
2802
|
key: "Player Bots",
|
|
2790
2803
|
defaultValue: ["None", "None"],
|
|
2791
2804
|
});
|
|
2792
|
-
const [
|
|
2793
|
-
key: "
|
|
2794
|
-
defaultValue:
|
|
2805
|
+
const [parameters, setParameters] = useLocalStorage({
|
|
2806
|
+
key: "Parameters",
|
|
2807
|
+
defaultValue: {},
|
|
2795
2808
|
});
|
|
2796
2809
|
const [rounds, setRounds] = useLocalStorage({
|
|
2797
2810
|
key: "Rounds",
|
|
@@ -2831,9 +2844,17 @@ const Round = () => {
|
|
|
2831
2844
|
}
|
|
2832
2845
|
useEffect(() => {
|
|
2833
2846
|
if (remaining > 0) {
|
|
2834
|
-
runNoUI(
|
|
2847
|
+
runNoUI(currentParameters, apis, currentPlayers, "", false);
|
|
2835
2848
|
}
|
|
2836
2849
|
}, [remaining]);
|
|
2850
|
+
const getFullParameters = () => {
|
|
2851
|
+
var _a;
|
|
2852
|
+
const result = {};
|
|
2853
|
+
for (const key in configuration.parameters) {
|
|
2854
|
+
result[key] = (_a = parameters[key]) !== null && _a !== void 0 ? _a : configuration.parameters[key][0];
|
|
2855
|
+
}
|
|
2856
|
+
return result;
|
|
2857
|
+
};
|
|
2837
2858
|
useEffect(updatePointModifier, [results]);
|
|
2838
2859
|
return (React.createElement(React.Fragment, null,
|
|
2839
2860
|
React.createElement("div", { style: {
|
|
@@ -2846,7 +2867,7 @@ const Round = () => {
|
|
|
2846
2867
|
React.createElement("table", { style: { textAlign: "center" } },
|
|
2847
2868
|
React.createElement("thead", null,
|
|
2848
2869
|
React.createElement("tr", null,
|
|
2849
|
-
React.createElement("th", { style: { width: "25%" } }, "
|
|
2870
|
+
React.createElement("th", { style: { width: "25%" } }, "Parameters"),
|
|
2850
2871
|
React.createElement("th", { style: { width: "35%" } }, "Players"),
|
|
2851
2872
|
roundIterations === 1 && (React.createElement(React.Fragment, null,
|
|
2852
2873
|
React.createElement("th", { style: { width: "17.5%" } }, "1st Place"),
|
|
@@ -2856,7 +2877,7 @@ const Round = () => {
|
|
|
2856
2877
|
React.createElement("tbody", null, rounds.map((round, index) => {
|
|
2857
2878
|
const winCounts = {};
|
|
2858
2879
|
if (results[round.players.join(", ")] !== undefined) {
|
|
2859
|
-
const currentResults = results[round.players.join(", ")][round.
|
|
2880
|
+
const currentResults = results[round.players.join(", ")][JSON.stringify(round.parameters)];
|
|
2860
2881
|
for (const result of currentResults) {
|
|
2861
2882
|
const winner = round.players[result[0]];
|
|
2862
2883
|
if (!winCounts[winner]) {
|
|
@@ -2869,28 +2890,31 @@ const Round = () => {
|
|
|
2869
2890
|
}
|
|
2870
2891
|
const winners = Object.keys(winCounts).sort((a, b) => winCounts[b] - winCounts[a]);
|
|
2871
2892
|
return (React.createElement("tr", { key: index },
|
|
2872
|
-
React.createElement("td",
|
|
2893
|
+
React.createElement("td", { style: { whiteSpace: "pre" } }, Object.keys(round.parameters)
|
|
2894
|
+
.sort()
|
|
2895
|
+
.map((p) => `${p[0].toUpperCase()}${p.slice(1)}: ${round.parameters[p]}`)
|
|
2896
|
+
.join("\n")),
|
|
2873
2897
|
React.createElement("td", null, round.players.map((player, index) => (React.createElement("img", { key: index, src: `/images/teams/${player.toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } })))),
|
|
2874
2898
|
roundIterations === 1 && (React.createElement(React.Fragment, null,
|
|
2875
2899
|
React.createElement("td", null, results[round.players.join(", ")] !== undefined &&
|
|
2876
|
-
results[round.players.join(", ")][round.
|
|
2877
|
-
undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][round.map][0][0]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))),
|
|
2900
|
+
results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][0]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))),
|
|
2878
2901
|
React.createElement("td", null, results[round.players.join(", ")] !== undefined &&
|
|
2879
|
-
results[round.players.join(", ")][round.
|
|
2880
|
-
undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][round.map][0][1]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))))),
|
|
2902
|
+
results[round.players.join(", ")][JSON.stringify(round.parameters)] !== undefined && (React.createElement("img", { src: `/images/teams/${round.players[results[round.players.join(", ")][JSON.stringify(round.parameters)][0][1]].toLowerCase()}.png`, width: 30, style: { marginInlineEnd: 10 } }))))),
|
|
2881
2903
|
roundIterations !== 1 && (React.createElement("td", null, winners.map((winner, index) => (React.createElement("p", { key: index },
|
|
2882
2904
|
winner,
|
|
2883
2905
|
": ",
|
|
2884
2906
|
winCounts[winner]))))),
|
|
2885
2907
|
React.createElement("td", null,
|
|
2886
2908
|
React.createElement(Button.Group, { orientation: "vertical" },
|
|
2887
|
-
React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.
|
|
2909
|
+
React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-play" }), size: "xs", onClick: () => navigate(`/simulation/${round.players.map(encodeURIComponent).join(",")}?showcase=true&${Object.keys(round.parameters)
|
|
2910
|
+
.map((p) => `${p}=${encodeURIComponent(round.parameters[p])}`)
|
|
2911
|
+
.join("&")}`) }, "Simulate"),
|
|
2888
2912
|
React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-forward" }), size: "xs", onClick: () => {
|
|
2889
2913
|
if (roundIterations === 1) {
|
|
2890
|
-
runNoUI(round.
|
|
2914
|
+
runNoUI(round.parameters, apis, round.players, "", false);
|
|
2891
2915
|
}
|
|
2892
2916
|
else {
|
|
2893
|
-
|
|
2917
|
+
currentParameters = round.parameters;
|
|
2894
2918
|
currentPlayers = round.players;
|
|
2895
2919
|
startRunNoUIN(roundIterations);
|
|
2896
2920
|
}
|
|
@@ -2901,12 +2925,14 @@ const Round = () => {
|
|
|
2901
2925
|
"Remaining Simulations: ",
|
|
2902
2926
|
remaining)),
|
|
2903
2927
|
location.search.includes("edit") && (React.createElement(React.Fragment, null,
|
|
2904
|
-
React.createElement(NumberInput, { value: roundIterations, onChange: (v) => { var _a; return setRoundIterations((_a = parseInt(v.toString(), 10)) !== null && _a !== void 0 ? _a : 1); }, label: "Round Iterations", leftSection: React.createElement("i", { className: "fa-solid fa-hashtag" }) }),
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2928
|
+
React.createElement(NumberInput, { mb: "xs", value: roundIterations, onChange: (v) => { var _a; return setRoundIterations((_a = parseInt(v.toString(), 10)) !== null && _a !== void 0 ? _a : 1); }, label: "Round Iterations", leftSection: React.createElement("i", { className: "fa-solid fa-hashtag" }) }),
|
|
2929
|
+
Object.keys(configuration.parameters)
|
|
2930
|
+
.sort()
|
|
2931
|
+
.map((parameter, parameterIndex) => {
|
|
2932
|
+
var _a, _b;
|
|
2933
|
+
const icon = ((_a = configuration.parameterIcons) !== null && _a !== void 0 ? _a : {})[parameter];
|
|
2934
|
+
return (React.createElement(Select, { key: parameterIndex, mb: "xs", leftSection: icon ? React.createElement("i", { className: icon }) : undefined, label: parameter[0].toUpperCase() + parameter.slice(1), data: configuration.parameters[parameter], value: (_b = parameters[parameter]) !== null && _b !== void 0 ? _b : configuration.parameters[parameter][0], onChange: (s) => setParameters(Object.assign(Object.assign({}, parameters), { [parameter]: s !== null && s !== void 0 ? s : configuration.parameters[parameter][0] })) }));
|
|
2935
|
+
}),
|
|
2910
2936
|
React.createElement(BotSelector, { playerCount: playerCount, setPlayerCount: setPlayerCount, playerBots: playerBots, setPlayerBots: setPlayerBots, apis: apis }),
|
|
2911
2937
|
React.createElement(Button, { color: "red", leftSection: React.createElement("i", { className: "fa-solid fa-trash" }), mt: "xs", onClick: () => {
|
|
2912
2938
|
setRounds([]);
|
|
@@ -2918,7 +2944,10 @@ const Round = () => {
|
|
|
2918
2944
|
React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-plus" }), mt: "xs", onClick: () => {
|
|
2919
2945
|
setRounds((rounds) => [
|
|
2920
2946
|
...rounds,
|
|
2921
|
-
{
|
|
2947
|
+
{
|
|
2948
|
+
players: playerBots,
|
|
2949
|
+
parameters: Object.assign({}, getFullParameters()),
|
|
2950
|
+
},
|
|
2922
2951
|
]);
|
|
2923
2952
|
}, style: { width: "30%" } }, "Add"),
|
|
2924
2953
|
React.createElement(Button, { leftSection: React.createElement("i", { className: "fa-solid fa-save" }), fullWidth: true, mt: "xs", onClick: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -2938,7 +2967,7 @@ const Round = () => {
|
|
|
2938
2967
|
80, 80, 80, 80,
|
|
2939
2968
|
]) {
|
|
2940
2969
|
setRounds((rounds) => rounds.map((round) => ({
|
|
2941
|
-
|
|
2970
|
+
parameters: round.parameters,
|
|
2942
2971
|
players: shuffle(round.players),
|
|
2943
2972
|
})));
|
|
2944
2973
|
yield new Promise((resolve) => setTimeout(resolve, timeout));
|
|
@@ -3106,7 +3135,7 @@ const Simulation = () => {
|
|
|
3106
3135
|
var _a, _b, _c, _d;
|
|
3107
3136
|
const admin = useAdmin();
|
|
3108
3137
|
const [apis, loading] = useAPIs();
|
|
3109
|
-
let {
|
|
3138
|
+
let { playerapis } = useParams();
|
|
3110
3139
|
const location = useLocation();
|
|
3111
3140
|
const [searchParams] = useSearchParams();
|
|
3112
3141
|
const [winner, setWinner] = useState();
|
|
@@ -3145,7 +3174,10 @@ const Simulation = () => {
|
|
|
3145
3174
|
}
|
|
3146
3175
|
};
|
|
3147
3176
|
}, []);
|
|
3148
|
-
|
|
3177
|
+
const parameters = Object.fromEntries(searchParams);
|
|
3178
|
+
if (parameters.seed) {
|
|
3179
|
+
delete parameters.seed;
|
|
3180
|
+
}
|
|
3149
3181
|
playerapis = playerapis === null || playerapis === void 0 ? void 0 : playerapis.split("&")[0];
|
|
3150
3182
|
const playerNames = (_a = playerapis === null || playerapis === void 0 ? void 0 : playerapis.split(",").map(decodeURIComponent)) !== null && _a !== void 0 ? _a : [];
|
|
3151
3183
|
const players = playerNames.map((api) => (api === "None" ? "" : apis[api]));
|
|
@@ -3159,7 +3191,7 @@ const Simulation = () => {
|
|
|
3159
3191
|
const seed = (_a = searchParams.get("seed")) !== null && _a !== void 0 ? _a : "";
|
|
3160
3192
|
tryUntilSuccess(() =>
|
|
3161
3193
|
// @ts-ignore
|
|
3162
|
-
window._startSimulation(
|
|
3194
|
+
window._startSimulation(parameters, players, playerNames, false, !showcaseMode, true, seed));
|
|
3163
3195
|
}
|
|
3164
3196
|
}, [loading]);
|
|
3165
3197
|
const newRank = getRank(getLocalStorage("Cached tournament/info"), winner, getLocalStorage("Point Modifier")) + 1;
|
|
@@ -3312,7 +3344,7 @@ const App = ({ routes, blocks }) => {
|
|
|
3312
3344
|
React.createElement(Routes, null,
|
|
3313
3345
|
React.createElement(Route, { path: "/", element: React.createElement(HomePage, { blocks: blocks }) }),
|
|
3314
3346
|
React.createElement(Route, { path: "/view/:apiname", element: React.createElement(ViewAPI, null) }),
|
|
3315
|
-
React.createElement(Route, { path: "/simulation/:
|
|
3347
|
+
React.createElement(Route, { path: "/simulation/:playerapis", element: React.createElement(Simulation, null) }),
|
|
3316
3348
|
React.createElement(Route, { path: "/round", element: React.createElement(Round, null) }),
|
|
3317
3349
|
React.createElement(Route, { path: "/settings", element: React.createElement(SettingsPage, null) }),
|
|
3318
3350
|
React.createElement(Route, { path: "*", element: React.createElement(NotFoundPage, null) }),
|
|
@@ -5716,15 +5748,15 @@ const initialize = () => {
|
|
|
5716
5748
|
}
|
|
5717
5749
|
};
|
|
5718
5750
|
// @ts-ignore
|
|
5719
|
-
window.setResults = (playerNames, places,
|
|
5751
|
+
window.setResults = (playerNames, places, parameters, verbose) => {
|
|
5720
5752
|
const results = getLocalStorage("Results");
|
|
5721
5753
|
if (!results[playerNames.join(", ")]) {
|
|
5722
5754
|
results[playerNames.join(", ")] = {};
|
|
5723
5755
|
}
|
|
5724
|
-
if (!results[playerNames.join(", ")][
|
|
5725
|
-
results[playerNames.join(", ")][
|
|
5756
|
+
if (!results[playerNames.join(", ")][JSON.stringify(parameters)]) {
|
|
5757
|
+
results[playerNames.join(", ")][JSON.stringify(parameters)] = [];
|
|
5726
5758
|
}
|
|
5727
|
-
results[playerNames.join(", ")][
|
|
5759
|
+
results[playerNames.join(", ")][JSON.stringify(parameters)].push(places);
|
|
5728
5760
|
setLocalStorage("Results", results);
|
|
5729
5761
|
updatePointModifier();
|
|
5730
5762
|
// @ts-ignore
|
|
@@ -3,7 +3,7 @@ import type { Auth } from "firebase/auth";
|
|
|
3
3
|
import type { Firestore } from "firebase/firestore";
|
|
4
4
|
interface CodeBattlesRequiredConfiguration {
|
|
5
5
|
firebase: any;
|
|
6
|
-
|
|
6
|
+
parameters: Record<string, string[]>;
|
|
7
7
|
}
|
|
8
8
|
interface CodeBattlesDatesConfiguration {
|
|
9
9
|
locale?: string;
|
|
@@ -19,6 +19,7 @@ interface CodeBattlesOptionalConfiguration {
|
|
|
19
19
|
authentication: Auth;
|
|
20
20
|
runningCountOptions?: number[];
|
|
21
21
|
dates?: CodeBattlesDatesConfiguration;
|
|
22
|
+
parameterIcons?: Record<string, string>;
|
|
22
23
|
}
|
|
23
24
|
export interface CodeBattlesConfiguration extends CodeBattlesRequiredConfiguration, Partial<CodeBattlesOptionalConfiguration> {
|
|
24
25
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface RoundInfo {
|
|
2
2
|
players: string[];
|
|
3
|
-
|
|
3
|
+
parameters: Record<string, string>;
|
|
4
4
|
}
|
|
5
5
|
export declare const getLocalStorage: (key: string, defaultValue?: {}) => any;
|
|
6
6
|
export declare const setLocalStorage: (key: string, value?: {}) => void;
|
|
@@ -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: (
|
|
13
|
+
export declare const runNoUI: (parameters: Record<string, 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/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Firestore } from 'firebase/firestore';
|
|
|
5
5
|
|
|
6
6
|
interface CodeBattlesRequiredConfiguration {
|
|
7
7
|
firebase: any;
|
|
8
|
-
|
|
8
|
+
parameters: Record<string, string[]>;
|
|
9
9
|
}
|
|
10
10
|
interface CodeBattlesDatesConfiguration {
|
|
11
11
|
locale?: string;
|
|
@@ -21,6 +21,7 @@ interface CodeBattlesOptionalConfiguration {
|
|
|
21
21
|
authentication: Auth;
|
|
22
22
|
runningCountOptions?: number[];
|
|
23
23
|
dates?: CodeBattlesDatesConfiguration;
|
|
24
|
+
parameterIcons?: Record<string, string>;
|
|
24
25
|
}
|
|
25
26
|
interface CodeBattlesConfiguration extends CodeBattlesRequiredConfiguration, Partial<CodeBattlesOptionalConfiguration> {
|
|
26
27
|
}
|
package/package.json
CHANGED