kaggle-environments 0.2.1__py3-none-any.whl → 1.20.0__py3-none-any.whl
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.
Potentially problematic release.
This version of kaggle-environments might be problematic. Click here for more details.
- kaggle_environments/__init__.py +49 -13
- kaggle_environments/agent.py +177 -124
- kaggle_environments/api.py +31 -0
- kaggle_environments/core.py +295 -170
- kaggle_environments/envs/cabt/cabt.js +164 -0
- kaggle_environments/envs/cabt/cabt.json +28 -0
- kaggle_environments/envs/cabt/cabt.py +186 -0
- kaggle_environments/envs/cabt/cg/__init__.py +0 -0
- kaggle_environments/envs/cabt/cg/cg.dll +0 -0
- kaggle_environments/envs/cabt/cg/game.py +75 -0
- kaggle_environments/envs/cabt/cg/libcg.so +0 -0
- kaggle_environments/envs/cabt/cg/sim.py +48 -0
- kaggle_environments/envs/cabt/test_cabt.py +120 -0
- kaggle_environments/envs/chess/chess.js +4289 -0
- kaggle_environments/envs/chess/chess.json +60 -0
- kaggle_environments/envs/chess/chess.py +4241 -0
- kaggle_environments/envs/chess/test_chess.py +60 -0
- kaggle_environments/envs/connectx/connectx.ipynb +3186 -0
- kaggle_environments/envs/connectx/connectx.js +1 -1
- kaggle_environments/envs/connectx/connectx.json +15 -1
- kaggle_environments/envs/connectx/connectx.py +6 -23
- kaggle_environments/envs/connectx/test_connectx.py +70 -24
- kaggle_environments/envs/football/football.ipynb +75 -0
- kaggle_environments/envs/football/football.json +91 -0
- kaggle_environments/envs/football/football.py +277 -0
- kaggle_environments/envs/football/helpers.py +95 -0
- kaggle_environments/envs/football/test_football.py +360 -0
- kaggle_environments/envs/halite/__init__.py +0 -0
- kaggle_environments/envs/halite/halite.ipynb +44741 -0
- kaggle_environments/envs/halite/halite.js +199 -83
- kaggle_environments/envs/halite/halite.json +31 -18
- kaggle_environments/envs/halite/halite.py +164 -303
- kaggle_environments/envs/halite/helpers.py +720 -0
- kaggle_environments/envs/halite/test_halite.py +190 -0
- kaggle_environments/envs/hungry_geese/__init__.py +0 -0
- kaggle_environments/envs/{battlegeese/battlegeese.js → hungry_geese/hungry_geese.js} +38 -22
- kaggle_environments/envs/{battlegeese/battlegeese.json → hungry_geese/hungry_geese.json} +21 -14
- kaggle_environments/envs/hungry_geese/hungry_geese.py +316 -0
- kaggle_environments/envs/hungry_geese/test_hungry_geese.py +0 -0
- kaggle_environments/envs/identity/identity.json +6 -5
- kaggle_environments/envs/identity/identity.py +15 -2
- kaggle_environments/envs/kore_fleets/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/helpers.py +1005 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +114 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.js +658 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.json +164 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.py +555 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/Bot.java +54 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/README.md +26 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/hamcrest-core-1.3.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/junit-4.13.2.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Board.java +518 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Cell.java +61 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Configuration.java +24 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Direction.java +166 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Fleet.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/KoreJson.java +97 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Observation.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Pair.java +13 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Player.java +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Point.java +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Shipyard.java +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/ShipyardAction.java +59 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/BoardTest.java +567 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ConfigurationTest.java +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/KoreJsonTest.java +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ObservationTest.java +46 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/PointTest.java +21 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ShipyardTest.java +22 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/main.py +27 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/Bot.ts +34 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/DoNothingBot.ts +12 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/MinerBot.ts +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/README.md +55 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/interpreter.ts +402 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Board.ts +514 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Cell.ts +63 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Configuration.ts +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Direction.ts +169 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Fleet.ts +76 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/KoreIO.ts +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Observation.ts +45 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Pair.ts +11 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Player.ts +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Point.ts +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Shipyard.ts +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/ShipyardAction.ts +58 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/miner.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/package.json +23 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/BoardTest.ts +551 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ConfigurationTest.ts +16 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ObservationTest.ts +33 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/PointTest.ts +17 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ShipyardTest.ts +18 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/tsconfig.json +22 -0
- kaggle_environments/envs/kore_fleets/test_kore_fleets.py +331 -0
- kaggle_environments/envs/lux_ai_2021/README.md +3 -0
- kaggle_environments/envs/lux_ai_2021/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/agents.py +11 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js +2 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/main.js +1 -0
- kaggle_environments/envs/lux_ai_2021/index.html +43 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.json +100 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.py +231 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.js +6 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_objects.js +145 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/io.js +14 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/kit.js +209 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/map.js +107 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/parser.js +79 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.js +88 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.py +75 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/annotate.py +20 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/constants.py +25 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game.py +86 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.py +7 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_map.py +106 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_objects.py +154 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/random_agent.py +38 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/simple_agent.py +82 -0
- kaggle_environments/envs/lux_ai_2021/test_lux.py +19 -0
- kaggle_environments/envs/lux_ai_2021/testing.md +23 -0
- kaggle_environments/envs/lux_ai_2021/todo.md.og +18 -0
- kaggle_environments/envs/lux_ai_s3/README.md +21 -0
- kaggle_environments/envs/lux_ai_s3/agents.py +5 -0
- kaggle_environments/envs/lux_ai_s3/index.html +42 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.json +47 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.py +178 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +819 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +9 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +141 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +222 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +27 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +464 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +156 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +78 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/kit.py +31 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/utils.py +17 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/main.py +66 -0
- kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
- kaggle_environments/envs/mab/__init__.py +0 -0
- kaggle_environments/envs/mab/agents.py +12 -0
- kaggle_environments/envs/mab/mab.js +100 -0
- kaggle_environments/envs/mab/mab.json +74 -0
- kaggle_environments/envs/mab/mab.py +146 -0
- kaggle_environments/envs/open_spiel/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/chess/chess.js +441 -0
- kaggle_environments/envs/open_spiel/games/chess/image_config.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/chess/openings.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/connect_four/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js +284 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py +86 -0
- kaggle_environments/envs/open_spiel/games/go/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/go/go.js +481 -0
- kaggle_environments/envs/open_spiel/games/go/go_proxy.py +99 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe.js +345 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe_proxy.py +98 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker.js +431 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker_proxy.py +159 -0
- kaggle_environments/envs/open_spiel/html_playthrough_generator.py +31 -0
- kaggle_environments/envs/open_spiel/observation.py +128 -0
- kaggle_environments/envs/open_spiel/open_spiel.py +565 -0
- kaggle_environments/envs/open_spiel/proxy.py +138 -0
- kaggle_environments/envs/open_spiel/test_open_spiel.py +191 -0
- kaggle_environments/envs/rps/__init__.py +0 -0
- kaggle_environments/envs/rps/agents.py +84 -0
- kaggle_environments/envs/rps/helpers.py +25 -0
- kaggle_environments/envs/rps/rps.js +117 -0
- kaggle_environments/envs/rps/rps.json +63 -0
- kaggle_environments/envs/rps/rps.py +90 -0
- kaggle_environments/envs/rps/test_rps.py +110 -0
- kaggle_environments/envs/rps/utils.py +7 -0
- kaggle_environments/envs/tictactoe/test_tictactoe.py +43 -77
- kaggle_environments/envs/tictactoe/tictactoe.ipynb +1397 -0
- kaggle_environments/envs/tictactoe/tictactoe.json +10 -2
- kaggle_environments/envs/tictactoe/tictactoe.py +1 -1
- kaggle_environments/errors.py +2 -4
- kaggle_environments/helpers.py +377 -0
- kaggle_environments/main.py +340 -0
- kaggle_environments/schemas.json +23 -18
- kaggle_environments/static/player.html +206 -74
- kaggle_environments/utils.py +46 -73
- kaggle_environments-1.20.0.dist-info/METADATA +25 -0
- kaggle_environments-1.20.0.dist-info/RECORD +211 -0
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.0.dist-info}/WHEEL +1 -2
- kaggle_environments-1.20.0.dist-info/entry_points.txt +3 -0
- kaggle_environments/envs/battlegeese/battlegeese.py +0 -223
- kaggle_environments/temp.py +0 -14
- kaggle_environments-0.2.1.dist-info/METADATA +0 -393
- kaggle_environments-0.2.1.dist-info/RECORD +0 -32
- kaggle_environments-0.2.1.dist-info/entry_points.txt +0 -3
- kaggle_environments-0.2.1.dist-info/top_level.txt +0 -1
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -5,7 +5,14 @@
|
|
|
5
5
|
"version": "1.0.0",
|
|
6
6
|
"agents": [2],
|
|
7
7
|
"configuration": {
|
|
8
|
-
"episodeSteps": 10
|
|
8
|
+
"episodeSteps": 10,
|
|
9
|
+
"actTimeout": 1,
|
|
10
|
+
"agentTimeout": {
|
|
11
|
+
"description": "Obsolete field kept for backwards compatibility, please use observation.remainingOverageTime.",
|
|
12
|
+
"type": "number",
|
|
13
|
+
"minimum": 0,
|
|
14
|
+
"default": 2
|
|
15
|
+
}
|
|
9
16
|
},
|
|
10
17
|
"reward": {
|
|
11
18
|
"description": "-1 = Lost, 0 = Draw/Ongoing, 1 = Won",
|
|
@@ -25,7 +32,8 @@
|
|
|
25
32
|
"description": "Mark for the agent to use",
|
|
26
33
|
"defaults": [1, 2],
|
|
27
34
|
"enum": [1, 2]
|
|
28
|
-
}
|
|
35
|
+
},
|
|
36
|
+
"remainingOverageTime": 2
|
|
29
37
|
},
|
|
30
38
|
"action": {
|
|
31
39
|
"description": "Position to place a mark on the board.",
|
kaggle_environments/errors.py
CHANGED
|
@@ -21,15 +21,13 @@ with open(status_path) as json_file:
|
|
|
21
21
|
codes = json.load(json_file)
|
|
22
22
|
|
|
23
23
|
for status in codes:
|
|
24
|
-
codes[status]["name"] = "".join(
|
|
25
|
-
"".join([word[0].upper(), word[1:].lower()]) for word in status.split("_")
|
|
26
|
-
)
|
|
24
|
+
codes[status]["name"] = "".join("".join([word[0].upper(), word[1:].lower()]) for word in status.split("_"))
|
|
27
25
|
|
|
28
26
|
|
|
29
27
|
class CanonicalError(Exception):
|
|
30
28
|
def __init__(self, error="", status="UNKNOWN"):
|
|
31
29
|
super().__init__(error)
|
|
32
|
-
if not
|
|
30
|
+
if status not in codes:
|
|
33
31
|
status = "UNKNOWN"
|
|
34
32
|
self.status = status
|
|
35
33
|
self.message = error
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import operator
|
|
2
|
+
import random
|
|
3
|
+
from enum import Enum, auto
|
|
4
|
+
from typing import Any, Callable, Dict, Generic, Iterable, List, Tuple, Type, TypeVar, Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Point(tuple):
|
|
8
|
+
"""
|
|
9
|
+
This type wraps Tuple[int, int] to provide additional operators and convenience members.
|
|
10
|
+
Point are expressed in the form (x, y) where x is the board column and y is the row.
|
|
11
|
+
(0, 0) is the lower left corner of the board and (size - 1, size - 1) is the upper right corner of the board.
|
|
12
|
+
Note that this differs from arrays where the top left is (0, 0) and the bottom right is (size - 1, size - 1).
|
|
13
|
+
Note that operators in this class do not constrain points to the board.
|
|
14
|
+
You can generally constrain a point to the board by calling point % board.configuration.size.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __new__(cls: Type["Point"], x: int, y: int):
|
|
18
|
+
return super(Point, cls).__new__(cls, tuple((x, y)))
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def x(self):
|
|
22
|
+
return self[0]
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def y(self):
|
|
26
|
+
return self[1]
|
|
27
|
+
|
|
28
|
+
def map(self, f: Callable[[int], int]) -> "Point":
|
|
29
|
+
return Point(f(self[0]), f(self[1]))
|
|
30
|
+
|
|
31
|
+
def map2(self, other: Union[Tuple[int, int], "Point"], f: Callable[[int, int], int]) -> "Point":
|
|
32
|
+
return Point(f(self[0], other[0]), f(self[1], other[1]))
|
|
33
|
+
|
|
34
|
+
def translate(self, offset: "Point", size: int):
|
|
35
|
+
"""Translates the current point by offset and wraps it around a board of width and height size"""
|
|
36
|
+
return (self + offset) % size
|
|
37
|
+
|
|
38
|
+
def distance_to(self, other: "Point", size: int):
|
|
39
|
+
"""Computes total distance (manhattan) to travel to other Point"""
|
|
40
|
+
abs_x = abs(self.x - other.x)
|
|
41
|
+
dist_x = abs_x if abs_x < size / 2 else size - abs_x
|
|
42
|
+
abs_y = abs(self.y - other.y)
|
|
43
|
+
dist_y = abs_y if abs_y < size / 2 else size - abs_y
|
|
44
|
+
return dist_x + dist_y
|
|
45
|
+
|
|
46
|
+
def to_index(self, size: int):
|
|
47
|
+
"""
|
|
48
|
+
Converts a 2d position in the form (x, y) to an index in the observation.halite list.
|
|
49
|
+
See staticmethod from_index for the inverse.
|
|
50
|
+
"""
|
|
51
|
+
return (size - self.y - 1) * size + self.x
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def from_index(index: int, size: int) -> "Point":
|
|
55
|
+
"""
|
|
56
|
+
Converts an index in the observation.halite list to a 2d position in the form (x, y).
|
|
57
|
+
See Point method to_index for the inverse.
|
|
58
|
+
"""
|
|
59
|
+
y, x = divmod(index, size)
|
|
60
|
+
return Point(x, (size - y - 1))
|
|
61
|
+
|
|
62
|
+
def __abs__(self) -> "Point":
|
|
63
|
+
return self.map(operator.abs)
|
|
64
|
+
|
|
65
|
+
def __add__(self, other: Union[Tuple[int, int], "Point"]) -> "Point":
|
|
66
|
+
return self.map2(other, operator.add)
|
|
67
|
+
|
|
68
|
+
def __eq__(self, other: Union[Tuple[int, int], "Point"]) -> bool:
|
|
69
|
+
try:
|
|
70
|
+
return self[0] == other[0] and self[1] == other[1]
|
|
71
|
+
except (TypeError, IndexError):
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
def __floordiv__(self, denominator: int) -> "Point":
|
|
75
|
+
return self.map(lambda x: x // denominator)
|
|
76
|
+
|
|
77
|
+
def __hash__(self) -> int:
|
|
78
|
+
return hash((self.x, self.y))
|
|
79
|
+
|
|
80
|
+
def __mod__(self, mod: int) -> "Point":
|
|
81
|
+
return self.map(lambda x: x % mod)
|
|
82
|
+
|
|
83
|
+
def __mul__(self, factor: int) -> "Point":
|
|
84
|
+
return self.map(lambda x: x * factor)
|
|
85
|
+
|
|
86
|
+
def __neg__(self) -> "Point":
|
|
87
|
+
return self.map(operator.neg)
|
|
88
|
+
|
|
89
|
+
def __str__(self):
|
|
90
|
+
return f"({self.x}, {self.y})"
|
|
91
|
+
|
|
92
|
+
def __sub__(self, other: Union[Tuple[int, int], "Point"]) -> "Point":
|
|
93
|
+
return self.map2(other, operator.sub)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class Direction(Enum):
|
|
97
|
+
NORTH = auto()
|
|
98
|
+
EAST = auto()
|
|
99
|
+
SOUTH = auto()
|
|
100
|
+
WEST = auto()
|
|
101
|
+
|
|
102
|
+
def to_point(self) -> Point:
|
|
103
|
+
"""
|
|
104
|
+
This returns the position offset associated with a particular action
|
|
105
|
+
NORTH -> (0, 1)
|
|
106
|
+
EAST -> (1, 0)
|
|
107
|
+
SOUTH -> (0, -1)
|
|
108
|
+
WEST -> (-1, 0)
|
|
109
|
+
"""
|
|
110
|
+
return (
|
|
111
|
+
Point(0, 1)
|
|
112
|
+
if self == Direction.NORTH
|
|
113
|
+
else Point(1, 0)
|
|
114
|
+
if self == Direction.EAST
|
|
115
|
+
else Point(0, -1)
|
|
116
|
+
if self == Direction.SOUTH
|
|
117
|
+
else Point(-1, 0)
|
|
118
|
+
if self == Direction.WEST
|
|
119
|
+
else None
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def __str__(self) -> str:
|
|
123
|
+
return self.name
|
|
124
|
+
|
|
125
|
+
def to_index(self) -> int:
|
|
126
|
+
return (
|
|
127
|
+
0
|
|
128
|
+
if self == Direction.NORTH
|
|
129
|
+
else 1
|
|
130
|
+
if self == Direction.EAST
|
|
131
|
+
else 2
|
|
132
|
+
if self == Direction.SOUTH
|
|
133
|
+
else 3
|
|
134
|
+
if self == Direction.WEST
|
|
135
|
+
else None
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
def to_char(self) -> str:
|
|
139
|
+
return (
|
|
140
|
+
"N"
|
|
141
|
+
if self == Direction.NORTH
|
|
142
|
+
else "E"
|
|
143
|
+
if self == Direction.EAST
|
|
144
|
+
else "S"
|
|
145
|
+
if self == Direction.SOUTH
|
|
146
|
+
else "W"
|
|
147
|
+
if self == Direction.WEST
|
|
148
|
+
else None
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def opposite(self) -> "Direction":
|
|
152
|
+
return (
|
|
153
|
+
Direction.SOUTH
|
|
154
|
+
if self == Direction.NORTH
|
|
155
|
+
else Direction.WEST
|
|
156
|
+
if self == Direction.EAST
|
|
157
|
+
else Direction.NORTH
|
|
158
|
+
if self == Direction.SOUTH
|
|
159
|
+
else Direction.EAST
|
|
160
|
+
if self == Direction.WEST
|
|
161
|
+
else None
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def rotate_left(self) -> "Direction":
|
|
165
|
+
return (
|
|
166
|
+
Direction.WEST
|
|
167
|
+
if self == Direction.NORTH
|
|
168
|
+
else Direction.NORTH
|
|
169
|
+
if self == Direction.EAST
|
|
170
|
+
else Direction.EAST
|
|
171
|
+
if self == Direction.SOUTH
|
|
172
|
+
else Direction.SOUTH
|
|
173
|
+
if self == Direction.WEST
|
|
174
|
+
else None
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def rotate_right(self) -> "Direction":
|
|
178
|
+
return (
|
|
179
|
+
Direction.EAST
|
|
180
|
+
if self == Direction.NORTH
|
|
181
|
+
else Direction.SOUTH
|
|
182
|
+
if self == Direction.EAST
|
|
183
|
+
else Direction.WEST
|
|
184
|
+
if self == Direction.SOUTH
|
|
185
|
+
else Direction.NORTH
|
|
186
|
+
if self == Direction.WEST
|
|
187
|
+
else None
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
@staticmethod
|
|
191
|
+
def from_str(str_dir: str):
|
|
192
|
+
return (
|
|
193
|
+
Direction.NORTH
|
|
194
|
+
if str_dir == "NORTH"
|
|
195
|
+
else Direction.EAST
|
|
196
|
+
if str_dir == "EAST"
|
|
197
|
+
else Direction.SOUTH
|
|
198
|
+
if str_dir == "SOUTH"
|
|
199
|
+
else Direction.WEST
|
|
200
|
+
if str_dir == "WEST"
|
|
201
|
+
else None
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
@staticmethod
|
|
205
|
+
def from_char(str_char: str):
|
|
206
|
+
return (
|
|
207
|
+
Direction.NORTH
|
|
208
|
+
if str_char == "N"
|
|
209
|
+
else Direction.EAST
|
|
210
|
+
if str_char == "E"
|
|
211
|
+
else Direction.SOUTH
|
|
212
|
+
if str_char == "S"
|
|
213
|
+
else Direction.WEST
|
|
214
|
+
if str_char == "W"
|
|
215
|
+
else None
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
@staticmethod
|
|
219
|
+
def from_index(idx: int):
|
|
220
|
+
return (
|
|
221
|
+
Direction.NORTH
|
|
222
|
+
if idx == 0
|
|
223
|
+
else Direction.EAST
|
|
224
|
+
if idx == 1
|
|
225
|
+
else Direction.SOUTH
|
|
226
|
+
if idx == 2
|
|
227
|
+
else Direction.WEST
|
|
228
|
+
if idx == 3
|
|
229
|
+
else None
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
@staticmethod
|
|
233
|
+
def random_direction() -> "Direction":
|
|
234
|
+
rand = random.random()
|
|
235
|
+
if rand <= 0.25:
|
|
236
|
+
return Direction.NORTH
|
|
237
|
+
elif rand <= 0.5:
|
|
238
|
+
return Direction.EAST
|
|
239
|
+
elif rand <= 0.75:
|
|
240
|
+
return Direction.SOUTH
|
|
241
|
+
else:
|
|
242
|
+
return Direction.WEST
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
def list_directions() -> List["Direction"]:
|
|
246
|
+
return [
|
|
247
|
+
Direction.NORTH,
|
|
248
|
+
Direction.EAST,
|
|
249
|
+
Direction.SOUTH,
|
|
250
|
+
Direction.WEST,
|
|
251
|
+
]
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
TItem = TypeVar("TItem")
|
|
255
|
+
THash = TypeVar("THash")
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def group_by(items: Iterable[TItem], selector: Callable[[TItem], THash]) -> Dict[THash, List[TItem]]:
|
|
259
|
+
results = {}
|
|
260
|
+
for item in items:
|
|
261
|
+
key = selector(item)
|
|
262
|
+
if key not in results:
|
|
263
|
+
results[key] = []
|
|
264
|
+
results[key].append(item)
|
|
265
|
+
return results
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def histogram(items: Iterable[TItem]) -> Dict[TItem, int]:
|
|
269
|
+
"""Accepts a list of hashable items and returns a dictionary where the keys are items and the values are counts of each item in the list."""
|
|
270
|
+
results = {}
|
|
271
|
+
for item in items:
|
|
272
|
+
if item not in results:
|
|
273
|
+
results[item] = 1
|
|
274
|
+
else:
|
|
275
|
+
results[item] += 1
|
|
276
|
+
return results
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def with_print(item: TItem) -> TItem:
|
|
280
|
+
"""Prints an item and returns it -- useful for debug printing in lambdas and chained functions."""
|
|
281
|
+
print(item)
|
|
282
|
+
return item
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
class Observation(Dict[str, any]):
|
|
286
|
+
"""
|
|
287
|
+
Observation provides access to per-step parameters in the environment.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def step(self) -> int:
|
|
292
|
+
"""Current step within the episode."""
|
|
293
|
+
return self["step"]
|
|
294
|
+
|
|
295
|
+
@property
|
|
296
|
+
def remaining_overage_time(self) -> int:
|
|
297
|
+
"""Total remaining banked time (seconds) that can be used in excess of per-step actTimeouts -- agent is disqualified with TIMEOUT status when this drops below 0."""
|
|
298
|
+
return self["remainingOverageTime"]
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
class Configuration(Dict[str, any]):
|
|
302
|
+
"""
|
|
303
|
+
Configuration provides access to tunable parameters in the environment.
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
@property
|
|
307
|
+
def episode_steps(self) -> int:
|
|
308
|
+
"""Total number of steps/turns in the run."""
|
|
309
|
+
return self["episodeSteps"]
|
|
310
|
+
|
|
311
|
+
@property
|
|
312
|
+
def act_timeout(self) -> float:
|
|
313
|
+
"""Maximum runtime (seconds) to obtain an action from an agent."""
|
|
314
|
+
return self["actTimeout"]
|
|
315
|
+
|
|
316
|
+
@property
|
|
317
|
+
def run_timeout(self) -> float:
|
|
318
|
+
"""Maximum runtime (seconds) of an episode (not necessarily DONE)."""
|
|
319
|
+
return self["runTimeout"]
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
TConfiguration = TypeVar("TConfiguration", bound=Configuration)
|
|
323
|
+
TObservation = TypeVar("TObservation", bound=Observation)
|
|
324
|
+
TAction = TypeVar("TAction")
|
|
325
|
+
Agent = Callable[[TObservation, TConfiguration], TAction]
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
class AgentStatus(Enum):
|
|
329
|
+
UNKNOWN = 0
|
|
330
|
+
ACTIVE = 1
|
|
331
|
+
INACTIVE = 2
|
|
332
|
+
DONE = 3
|
|
333
|
+
INVALID = 4
|
|
334
|
+
ERROR = 5
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class AgentState(Generic[TObservation, TAction], Dict[str, any]):
|
|
338
|
+
@property
|
|
339
|
+
def observation(self) -> TObservation:
|
|
340
|
+
return self["observation"]
|
|
341
|
+
|
|
342
|
+
@property
|
|
343
|
+
def action(self) -> TAction:
|
|
344
|
+
return self["action"]
|
|
345
|
+
|
|
346
|
+
@property
|
|
347
|
+
def reward(self) -> int:
|
|
348
|
+
return self["reward"]
|
|
349
|
+
|
|
350
|
+
@property
|
|
351
|
+
def status(self) -> AgentStatus:
|
|
352
|
+
status = self["status"]
|
|
353
|
+
if status in AgentStatus.__members__:
|
|
354
|
+
return AgentStatus[status]
|
|
355
|
+
return AgentStatus.UNKNOWN
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
class Environment(Generic[TConfiguration, TObservation, TAction]):
|
|
359
|
+
@property
|
|
360
|
+
def specification(self) -> Dict[str, Any]:
|
|
361
|
+
raise NotImplementedError()
|
|
362
|
+
|
|
363
|
+
def interpret(
|
|
364
|
+
self, configuration: TConfiguration, state: List[AgentState[TObservation, TAction]]
|
|
365
|
+
) -> List[AgentState[TObservation, TAction]]:
|
|
366
|
+
raise NotImplementedError()
|
|
367
|
+
|
|
368
|
+
def render_html(self, configuration: TConfiguration, state: List[AgentState[TObservation, TAction]]) -> str:
|
|
369
|
+
raise NotImplementedError()
|
|
370
|
+
|
|
371
|
+
def render_text(self, configuration: TConfiguration, state: List[AgentState[TObservation, TAction]]) -> str:
|
|
372
|
+
raise NotImplementedError()
|
|
373
|
+
|
|
374
|
+
@property
|
|
375
|
+
def builtin_agents(self) -> Dict[str, Agent]:
|
|
376
|
+
"""Override this property to provide default agents that can be referenced by name in this environment, e.g. `{"random": my_random_agent}`"""
|
|
377
|
+
return {}
|