code-battles 1.6.4 → 1.7.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 +2234 -2004
- package/dist/cjs/styles.css +2 -1
- package/dist/cjs/types/components/DataTable.d.ts +21 -0
- package/dist/cjs/types/components/ResultStaticsTable.d.ts +3 -0
- package/dist/cjs/types/configuration.d.ts +2 -2
- package/dist/cjs/types/utilities.d.ts +2 -2
- package/dist/code_battles/__init__.py +1 -1
- package/dist/code_battles/battles.py +69 -28
- package/dist/code_battles/utilities.py +12 -3
- package/dist/esm/index.js +2235 -2005
- package/dist/esm/styles.css +2 -1
- package/dist/esm/types/components/DataTable.d.ts +21 -0
- package/dist/esm/types/components/ResultStaticsTable.d.ts +3 -0
- package/dist/esm/types/configuration.d.ts +2 -2
- package/dist/esm/types/utilities.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/pyscript/codemirror-eKulCBrd.js +2 -0
- package/dist/pyscript/codemirror-eKulCBrd.js.map +1 -0
- package/dist/pyscript/codemirror_commands-BVu_0Pnj.js +2 -0
- package/dist/pyscript/codemirror_commands-BVu_0Pnj.js.map +1 -0
- package/dist/pyscript/codemirror_lang-python-a2LxSo5G.js +2 -0
- package/dist/pyscript/codemirror_lang-python-a2LxSo5G.js.map +1 -0
- package/dist/pyscript/codemirror_language-_2pXlKJ9.js +2 -0
- package/dist/pyscript/codemirror_language-_2pXlKJ9.js.map +1 -0
- package/dist/pyscript/codemirror_view-DMW9kQlJ.js +2 -0
- package/dist/pyscript/codemirror_view-DMW9kQlJ.js.map +1 -0
- package/dist/pyscript/core-DezwbZpG.js +4 -0
- package/dist/pyscript/core-DezwbZpG.js.map +1 -0
- package/dist/pyscript/core.js +1 -1
- package/dist/pyscript/deprecations-manager-B1bDno27.js +2 -0
- package/dist/pyscript/deprecations-manager-B1bDno27.js.map +1 -0
- package/dist/pyscript/donkey-DNl0ASkM.js +2 -0
- package/dist/pyscript/donkey-DNl0ASkM.js.map +1 -0
- package/dist/pyscript/error-DmRE4Y-7.js +2 -0
- package/dist/pyscript/error-DmRE4Y-7.js.map +1 -0
- package/dist/pyscript/index-DkgvWIf-.js +2 -0
- package/dist/pyscript/index-DkgvWIf-.js.map +1 -0
- package/dist/pyscript/mpy-BoY0tVRD.js +2 -0
- package/dist/pyscript/mpy-BoY0tVRD.js.map +1 -0
- package/dist/pyscript/py-DsQqgZuM.js +2 -0
- package/dist/pyscript/py-DsQqgZuM.js.map +1 -0
- package/dist/pyscript/py-editor-DZkG_or6.js +2 -0
- package/dist/pyscript/py-editor-DZkG_or6.js.map +1 -0
- package/dist/pyscript/py-game-D0Z4YnzZ.js +2 -0
- package/dist/pyscript/py-game-D0Z4YnzZ.js.map +1 -0
- package/dist/pyscript/py-terminal-DYHK7LJ0.js +2 -0
- package/dist/pyscript/py-terminal-DYHK7LJ0.js.map +1 -0
- package/dist/pyscript/service-worker.js +1 -0
- package/dist/pyscript/storage.js +1 -1
- package/dist/pyscript/storage.js.map +1 -1
- package/dist/pyscript/xterm-CVv2fC4I.js +2 -0
- package/dist/pyscript/xterm-CVv2fC4I.js.map +1 -0
- package/dist/pyscript/zip-D13-hp9W.js +2 -0
- package/dist/pyscript/zip-D13-hp9W.js.map +1 -0
- package/package.json +14 -14
package/dist/cjs/styles.css
CHANGED
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
pre[class*="language-"].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber;}pre[class*="language-"].line-numbers>code{position:relative;white-space:inherit;}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.line-numbers-rows>span{display:block;counter-increment:linenumber;}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:0.8em;text-align:right;}
|
|
3
3
|
code[class*="language-"],pre[class*="language-"]{color:black;background:none;text-shadow:0 1px white;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}pre[class*="language-"]::-moz-selection,pre[class*="language-"] ::-moz-selection,code[class*="language-"]::-moz-selection,code[class*="language-"] ::-moz-selection{text-shadow:none;background:#b3d4fc;}pre[class*="language-"]::selection,pre[class*="language-"] ::selection,code[class*="language-"]::selection,code[class*="language-"] ::selection{text-shadow:none;background:#b3d4fc;}@media print{code[class*="language-"],pre[class*="language-"]{text-shadow:none;}}pre[class*="language-"]{padding:1em;margin:.5em 0;overflow:auto;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#f5f2f0;}:not(pre)>code[class*="language-"]{padding:.1em;border-radius:.3em;white-space:normal;}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:slategray;}.token.punctuation{color:#999;}.token.namespace{opacity:.7;}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#905;}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#690;}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#9a6e3a;background:hsla(0,0%,100%,.5);}.token.atrule,.token.attr-value,.token.keyword{color:#07a;}.token.function,.token.class-name{color:#DD4A68;}.token.regex,.token.important,.token.variable{color:#e90;}.token.important,.token.bold{font-weight:bold;}.token.italic{font-style:italic;}.token.entity{cursor:help;}
|
|
4
4
|
py-config,py-script,py-splashscreen,.py-error{display:none;}h1,h2,h3,h4,h5,h6,p{margin:0;}
|
|
5
|
-
.token.operator{background:inherit !important;}pre[class*="language-"],code[class*="language-"]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,"Andale Mono","Ubuntu Mono","Courier New",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}pre[class*="language-"]::selection,code[class*="language-"]::selection,pre[class*="language-"] *::selection,code[class*="language-"] *::selection{text-shadow:none;background:#264f78;}@media print{pre[class*="language-"],code[class*="language-"]{text-shadow:none;}}pre[class*="language-"]{padding:1em;margin:0.5em 0;overflow:auto;background:#1e1e1e;}:not(pre)>code[class*="language-"]{padding:0.1em 0.3em;border-radius:0.3em;color:#db4c69;background:#1e1e1e;}.namespace{opacity:0.7;}.token.doctype .token.doctype-tag{color:#569cd6;}.token.doctype .token.name{color:#9cdcfe;}.token.comment,.token.prolog{color:#6a9955;}.token.punctuation,.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation{color:#d4d4d4;}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.inserted,.token.unit{color:#b5cea8;}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.deleted{color:#ce9178;}.language-css .token.string.url{text-decoration:underline;}.token.operator,.token.entity{color:#d4d4d4;}.token.operator.arrow{color:#569cd6;}.token.atrule{color:#ce9178;}.token.atrule .token.rule{color:#c586c0;}.token.atrule .token.url{color:#9cdcfe;}.token.atrule .token.url .token.function{color:#dcdcaa;}.token.atrule .token.url .token.punctuation{color:#d4d4d4;}.token.keyword{color:#569cd6;}.token.keyword.module,.token.keyword.control-flow{color:#c586c0;}.token.function,.token.function .token.maybe-class-name{color:#dcdcaa;}.token.regex{color:#d16969;}.token.important{color:#569cd6;}.token.italic{font-style:italic;}.token.constant{color:#9cdcfe;}.token.class-name,.token.maybe-class-name{color:#4ec9b0;}.token.console{color:#9cdcfe;}.token.parameter{color:#9cdcfe;}.token.interpolation{color:#9cdcfe;}.token.punctuation.interpolation-punctuation{color:#569cd6;}.token.boolean{color:#569cd6;}.token.property,.token.variable,.token.imports .token.maybe-class-name,.token.exports .token.maybe-class-name{color:#9cdcfe;}.token.selector{color:#d7ba7d;}.token.escape{color:#d7ba7d;}.token.tag{color:#569cd6;}.token.tag .token.punctuation{color:#808080;}.token.cdata{color:#808080;}.token.attr-name{color:#9cdcfe;}.token.attr-value,.token.attr-value .token.punctuation{color:#ce9178;}.token.attr-value .token.punctuation.attr-equals{color:#d4d4d4;}.token.entity{color:#569cd6;}.token.namespace{color:#4ec9b0;}pre[class*="language-javascript"],code[class*="language-javascript"],pre[class*="language-jsx"],code[class*="language-jsx"],pre[class*="language-typescript"],code[class*="language-typescript"],pre[class*="language-tsx"],code[class*="language-tsx"]{color:#9cdcfe;}pre[class*="language-css"],code[class*="language-css"]{color:#ce9178;}pre[class*="language-html"],code[class*="language-html"]{color:#d4d4d4;}.language-regex .token.anchor{color:#dcdcaa;}.language-html .token.punctuation{color:#808080;}pre[class*="language-"]>code[class*="language-"]{position:relative;z-index:1;}.line-highlight.line-highlight{background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0;}
|
|
5
|
+
.token.operator{background:inherit !important;}pre[class*="language-"],code[class*="language-"]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,"Andale Mono","Ubuntu Mono","Courier New",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}pre[class*="language-"]::selection,code[class*="language-"]::selection,pre[class*="language-"] *::selection,code[class*="language-"] *::selection{text-shadow:none;background:#264f78;}@media print{pre[class*="language-"],code[class*="language-"]{text-shadow:none;}}pre[class*="language-"]{padding:1em;margin:0.5em 0;overflow:auto;background:#1e1e1e;}:not(pre)>code[class*="language-"]{padding:0.1em 0.3em;border-radius:0.3em;color:#db4c69;background:#1e1e1e;}.namespace{opacity:0.7;}.token.doctype .token.doctype-tag{color:#569cd6;}.token.doctype .token.name{color:#9cdcfe;}.token.comment,.token.prolog{color:#6a9955;}.token.punctuation,.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation{color:#d4d4d4;}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.inserted,.token.unit{color:#b5cea8;}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.deleted{color:#ce9178;}.language-css .token.string.url{text-decoration:underline;}.token.operator,.token.entity{color:#d4d4d4;}.token.operator.arrow{color:#569cd6;}.token.atrule{color:#ce9178;}.token.atrule .token.rule{color:#c586c0;}.token.atrule .token.url{color:#9cdcfe;}.token.atrule .token.url .token.function{color:#dcdcaa;}.token.atrule .token.url .token.punctuation{color:#d4d4d4;}.token.keyword{color:#569cd6;}.token.keyword.module,.token.keyword.control-flow{color:#c586c0;}.token.function,.token.function .token.maybe-class-name{color:#dcdcaa;}.token.regex{color:#d16969;}.token.important{color:#569cd6;}.token.italic{font-style:italic;}.token.constant{color:#9cdcfe;}.token.class-name,.token.maybe-class-name{color:#4ec9b0;}.token.console{color:#9cdcfe;}.token.parameter{color:#9cdcfe;}.token.interpolation{color:#9cdcfe;}.token.punctuation.interpolation-punctuation{color:#569cd6;}.token.boolean{color:#569cd6;}.token.property,.token.variable,.token.imports .token.maybe-class-name,.token.exports .token.maybe-class-name{color:#9cdcfe;}.token.selector{color:#d7ba7d;}.token.escape{color:#d7ba7d;}.token.tag{color:#569cd6;}.token.tag .token.punctuation{color:#808080;}.token.cdata{color:#808080;}.token.attr-name{color:#9cdcfe;}.token.attr-value,.token.attr-value .token.punctuation{color:#ce9178;}.token.attr-value .token.punctuation.attr-equals{color:#d4d4d4;}.token.entity{color:#569cd6;}.token.namespace{color:#4ec9b0;}pre[class*="language-javascript"],code[class*="language-javascript"],pre[class*="language-jsx"],code[class*="language-jsx"],pre[class*="language-typescript"],code[class*="language-typescript"],pre[class*="language-tsx"],code[class*="language-tsx"]{color:#9cdcfe;}pre[class*="language-css"],code[class*="language-css"]{color:#ce9178;}pre[class*="language-html"],code[class*="language-html"]{color:#d4d4d4;}.language-regex .token.anchor{color:#dcdcaa;}.language-html .token.punctuation{color:#808080;}pre[class*="language-"]>code[class*="language-"]{position:relative;z-index:1;}.line-highlight.line-highlight{background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0;}
|
|
6
|
+
.control{width:100%;padding:10px;cursor:pointer;}.control:hover{background-color:light-dark(var(--mantine-color-gray-0),var(--mantine-color-dark-6));}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import "./DataTable.css";
|
|
3
|
+
export interface DataTableData {
|
|
4
|
+
head: string[];
|
|
5
|
+
body: string[][];
|
|
6
|
+
}
|
|
7
|
+
declare const DataTable: ({ tableName, data, renderValue, renderHead, disableSort, hideIfEmpty, selectable, selectedRows, setSelectedRows, defaultSort, defaultReversed, stickyFirstColumn, }: {
|
|
8
|
+
tableName: string;
|
|
9
|
+
data: DataTableData;
|
|
10
|
+
renderValue?: (rowIndex: number, columnName: string, value: string) => React.ReactNode;
|
|
11
|
+
renderHead?: (columnName: string, columnIndex: number) => React.ReactNode;
|
|
12
|
+
disableSort?: boolean;
|
|
13
|
+
hideIfEmpty?: boolean;
|
|
14
|
+
selectable?: boolean;
|
|
15
|
+
selectedRows?: number[];
|
|
16
|
+
setSelectedRows?: React.Dispatch<React.SetStateAction<number[]>>;
|
|
17
|
+
defaultSort?: number;
|
|
18
|
+
defaultReversed?: boolean;
|
|
19
|
+
stickyFirstColumn?: boolean;
|
|
20
|
+
}) => React.JSX.Element;
|
|
21
|
+
export default DataTable;
|
|
@@ -3,13 +3,12 @@ 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;
|
|
10
10
|
firstDayOfWeek?: DayOfWeek;
|
|
11
11
|
weekendDays?: DayOfWeek[];
|
|
12
|
-
timezone?: string;
|
|
13
12
|
}
|
|
14
13
|
interface CodeBattlesOptionalConfiguration {
|
|
15
14
|
primaryColor: string;
|
|
@@ -19,6 +18,7 @@ interface CodeBattlesOptionalConfiguration {
|
|
|
19
18
|
authentication: Auth;
|
|
20
19
|
runningCountOptions?: number[];
|
|
21
20
|
dates?: CodeBattlesDatesConfiguration;
|
|
21
|
+
parameterIcons?: Record<string, string>;
|
|
22
22
|
}
|
|
23
23
|
export interface CodeBattlesConfiguration extends CodeBattlesRequiredConfiguration, Partial<CodeBattlesOptionalConfiguration> {
|
|
24
24
|
}
|
|
@@ -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, Union
|
|
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"
|
|
@@ -231,6 +235,15 @@ class CodeBattles(
|
|
|
231
235
|
|
|
232
236
|
pass
|
|
233
237
|
|
|
238
|
+
def get_statistics(self) -> Dict[str, Union[int, float]]:
|
|
239
|
+
"""
|
|
240
|
+
Optional method to return statistics, called after the game ends.
|
|
241
|
+
|
|
242
|
+
When running multiple no UI simulations, you can use this to view the simulations in a table.
|
|
243
|
+
"""
|
|
244
|
+
|
|
245
|
+
return {}
|
|
246
|
+
|
|
234
247
|
def configure_extra_width(self) -> int:
|
|
235
248
|
"""Optionally add extra height to the right of the boards. 0 by default."""
|
|
236
249
|
|
|
@@ -358,12 +371,13 @@ class CodeBattles(
|
|
|
358
371
|
await ff.load()
|
|
359
372
|
document.fonts.add(ff)
|
|
360
373
|
|
|
361
|
-
def run_bot_method(self, player_index: int, method_name: str):
|
|
374
|
+
def run_bot_method(self, player_index: int, method_name: str) -> float:
|
|
362
375
|
"""
|
|
363
|
-
Runs the
|
|
376
|
+
Runs the specified method of the given player and returns the time it took (in seconds).
|
|
364
377
|
|
|
365
378
|
Upon exception, shows an alert (does not terminate the bot).
|
|
366
379
|
"""
|
|
380
|
+
start = time.time()
|
|
367
381
|
|
|
368
382
|
assert player_index in self.active_players
|
|
369
383
|
|
|
@@ -392,6 +406,9 @@ class CodeBattles(
|
|
|
392
406
|
"fa-solid fa-exclamation",
|
|
393
407
|
)
|
|
394
408
|
|
|
409
|
+
end = time.time()
|
|
410
|
+
return end - start
|
|
411
|
+
|
|
395
412
|
def eliminate_player(self, player_index: int, reason=""):
|
|
396
413
|
"""Eliminate the specified player for the specified reason from the simulation."""
|
|
397
414
|
|
|
@@ -468,7 +485,7 @@ class CodeBattles(
|
|
|
468
485
|
|
|
469
486
|
If ``force`` is set, will play the sound even if the simulation is not :attr:`verbose`.
|
|
470
487
|
"""
|
|
471
|
-
from js import
|
|
488
|
+
from js import Audio, window
|
|
472
489
|
|
|
473
490
|
if not force and not self.verbose:
|
|
474
491
|
return
|
|
@@ -521,7 +538,7 @@ class CodeBattles(
|
|
|
521
538
|
|
|
522
539
|
@web_only
|
|
523
540
|
def _initialize(self):
|
|
524
|
-
from js import
|
|
541
|
+
from js import document, window
|
|
525
542
|
from pyscript.ffi import create_proxy
|
|
526
543
|
|
|
527
544
|
window.addEventListener("resize", create_proxy(lambda _: self._resize_canvas()))
|
|
@@ -565,7 +582,7 @@ class CodeBattles(
|
|
|
565
582
|
|
|
566
583
|
def _run_webworker_simulation(
|
|
567
584
|
self,
|
|
568
|
-
|
|
585
|
+
parameters: Dict[str, str],
|
|
569
586
|
player_names_str: str,
|
|
570
587
|
player_codes_str: str,
|
|
571
588
|
seed: Optional[int] = None,
|
|
@@ -573,10 +590,12 @@ class CodeBattles(
|
|
|
573
590
|
from pyscript import sync
|
|
574
591
|
|
|
575
592
|
# JS to Python
|
|
593
|
+
parameters = json.loads(parameters)
|
|
576
594
|
player_names = json.loads(player_names_str)
|
|
577
595
|
player_codes = json.loads(player_codes_str)
|
|
578
596
|
|
|
579
|
-
self.
|
|
597
|
+
self.parameters = parameters
|
|
598
|
+
self.map = parameters.get("map")
|
|
580
599
|
self.player_names = player_names
|
|
581
600
|
self.background = True
|
|
582
601
|
self.console_visible = False
|
|
@@ -589,7 +608,10 @@ class CodeBattles(
|
|
|
589
608
|
decisions = self._make_decisions()
|
|
590
609
|
logs = self._logs
|
|
591
610
|
alerts = self._alerts
|
|
611
|
+
log = self.log
|
|
612
|
+
self.log = lambda *args, **kwargs: None
|
|
592
613
|
self.apply_decisions(decisions)
|
|
614
|
+
self.log = log
|
|
593
615
|
|
|
594
616
|
sync.update_step(
|
|
595
617
|
base64.b64encode(decisions).decode(),
|
|
@@ -620,7 +642,8 @@ class CodeBattles(
|
|
|
620
642
|
contents = f.read()
|
|
621
643
|
simulation = Simulation.load(contents)
|
|
622
644
|
seed = simulation.seed
|
|
623
|
-
self.
|
|
645
|
+
self.parameters = simulation.parameters
|
|
646
|
+
self.map = simulation.parameters.get("map")
|
|
624
647
|
self.player_names = simulation.player_names
|
|
625
648
|
decisions = simulation.decisions
|
|
626
649
|
player_codes = ["" for _ in simulation.player_names]
|
|
@@ -684,12 +707,15 @@ class CodeBattles(
|
|
|
684
707
|
|
|
685
708
|
try:
|
|
686
709
|
simulation = Simulation.load(str(contents))
|
|
710
|
+
parameters = "&".join(
|
|
711
|
+
[f"{p}={quote(v)}" for p, v in simulation.parameters.items()]
|
|
712
|
+
)
|
|
687
713
|
navigate(
|
|
688
|
-
f"/simulation/{
|
|
714
|
+
f"/simulation/{','.join([quote(player_name) for player_name in simulation.player_names])}?seed={simulation.seed}&{parameters}"
|
|
689
715
|
)
|
|
690
716
|
self.alert(
|
|
691
717
|
"Loaded simulation file!",
|
|
692
|
-
f"{', '.join(simulation.player_names)} competed
|
|
718
|
+
f"{', '.join(simulation.player_names)} competed with {simulation.parameters} at {simulation.timestamp}",
|
|
693
719
|
"blue",
|
|
694
720
|
"fa-solid fa-file-code",
|
|
695
721
|
0,
|
|
@@ -713,9 +739,10 @@ class CodeBattles(
|
|
|
713
739
|
while document.getElementById("loader") is None:
|
|
714
740
|
await asyncio.sleep(0.01)
|
|
715
741
|
self._initialize()
|
|
716
|
-
self.
|
|
742
|
+
self.parameters = simulation.parameters
|
|
743
|
+
self.map = self.parameters.get("map")
|
|
717
744
|
self.map_image = await download_image(
|
|
718
|
-
self.configure_map_image_url(
|
|
745
|
+
self.configure_map_image_url(self.map)
|
|
719
746
|
)
|
|
720
747
|
self.player_names = simulation.player_names
|
|
721
748
|
self.background = False
|
|
@@ -744,7 +771,7 @@ class CodeBattles(
|
|
|
744
771
|
@web_only
|
|
745
772
|
async def _start_simulation_async(
|
|
746
773
|
self,
|
|
747
|
-
|
|
774
|
+
parameters: Dict[str, str],
|
|
748
775
|
player_codes: List[str],
|
|
749
776
|
player_names: List[str],
|
|
750
777
|
background: bool,
|
|
@@ -758,15 +785,19 @@ class CodeBattles(
|
|
|
758
785
|
# JS to Python
|
|
759
786
|
player_names = [str(x) for x in player_names]
|
|
760
787
|
player_codes = [str(x) for x in player_codes]
|
|
788
|
+
parameters = parameters.to_py()
|
|
761
789
|
|
|
762
790
|
try:
|
|
763
791
|
render_status = document.getElementById("render-status")
|
|
764
792
|
if render_status is not None:
|
|
765
793
|
render_status.textContent = "Rendering: Initializing..."
|
|
766
794
|
|
|
767
|
-
self.
|
|
795
|
+
self.parameters = parameters
|
|
796
|
+
self.map = parameters.get("map")
|
|
768
797
|
self.player_names = player_names
|
|
769
|
-
self.map_image = await download_image(
|
|
798
|
+
self.map_image = await download_image(
|
|
799
|
+
self.configure_map_image_url(self.map)
|
|
800
|
+
)
|
|
770
801
|
self.background = background
|
|
771
802
|
self.console_visible = console_visible
|
|
772
803
|
self.verbose = verbose
|
|
@@ -794,7 +825,10 @@ class CodeBattles(
|
|
|
794
825
|
self._worker = await workers["worker"]
|
|
795
826
|
self._worker.update_step = self._update_step
|
|
796
827
|
self._worker._run_webworker_simulation(
|
|
797
|
-
|
|
828
|
+
json.dumps(parameters),
|
|
829
|
+
json.dumps(player_names),
|
|
830
|
+
json.dumps(player_codes),
|
|
831
|
+
self._seed,
|
|
798
832
|
)
|
|
799
833
|
|
|
800
834
|
if self.background:
|
|
@@ -824,7 +858,7 @@ class CodeBattles(
|
|
|
824
858
|
|
|
825
859
|
def _get_simulation(self):
|
|
826
860
|
return Simulation(
|
|
827
|
-
self.
|
|
861
|
+
self.parameters,
|
|
828
862
|
self.player_names,
|
|
829
863
|
self.__class__.__name__,
|
|
830
864
|
self.configure_version(),
|
|
@@ -842,7 +876,7 @@ class CodeBattles(
|
|
|
842
876
|
is_over_str: str,
|
|
843
877
|
should_pause_str: str,
|
|
844
878
|
):
|
|
845
|
-
from js import
|
|
879
|
+
from js import document, window
|
|
846
880
|
|
|
847
881
|
now = time.time()
|
|
848
882
|
decisions = base64.b64decode(str(decisions_str))
|
|
@@ -1020,7 +1054,12 @@ class CodeBattles(
|
|
|
1020
1054
|
if len(self.active_players) == 1:
|
|
1021
1055
|
self._eliminated.append(self.active_players[0])
|
|
1022
1056
|
set_results(
|
|
1023
|
-
self.player_names,
|
|
1057
|
+
self.player_names,
|
|
1058
|
+
self._seed,
|
|
1059
|
+
self._eliminated[::-1],
|
|
1060
|
+
self.get_statistics(),
|
|
1061
|
+
self.parameters,
|
|
1062
|
+
self.verbose,
|
|
1024
1063
|
)
|
|
1025
1064
|
if not self.background:
|
|
1026
1065
|
self.render()
|
|
@@ -1111,3 +1150,5 @@ class CodeBattles(
|
|
|
1111
1150
|
0,
|
|
1112
1151
|
)
|
|
1113
1152
|
)
|
|
1153
|
+
else:
|
|
1154
|
+
await asyncio.sleep(0.0005)
|
|
@@ -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,21 @@ 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
|
+
seed: int,
|
|
79
|
+
places: List[int],
|
|
80
|
+
statistics: Dict[str, Union[float, int]],
|
|
81
|
+
parameters: Dict[str, str],
|
|
82
|
+
verbose: bool,
|
|
83
|
+
):
|
|
77
84
|
from js import window
|
|
78
85
|
|
|
79
86
|
if hasattr(window, "setResults"):
|
|
80
87
|
try:
|
|
81
|
-
window.setResults(
|
|
88
|
+
window.setResults(
|
|
89
|
+
player_names, str(seed), places, statistics, parameters, verbose
|
|
90
|
+
)
|
|
82
91
|
except Exception as e:
|
|
83
92
|
print(e)
|
|
84
93
|
|