kaggle-environments 0.2.0__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.

Files changed (215) hide show
  1. kaggle_environments/__init__.py +49 -13
  2. kaggle_environments/agent.py +177 -124
  3. kaggle_environments/api.py +31 -0
  4. kaggle_environments/core.py +298 -173
  5. kaggle_environments/envs/cabt/cabt.js +164 -0
  6. kaggle_environments/envs/cabt/cabt.json +28 -0
  7. kaggle_environments/envs/cabt/cabt.py +186 -0
  8. kaggle_environments/envs/cabt/cg/__init__.py +0 -0
  9. kaggle_environments/envs/cabt/cg/cg.dll +0 -0
  10. kaggle_environments/envs/cabt/cg/game.py +75 -0
  11. kaggle_environments/envs/cabt/cg/libcg.so +0 -0
  12. kaggle_environments/envs/cabt/cg/sim.py +48 -0
  13. kaggle_environments/envs/cabt/test_cabt.py +120 -0
  14. kaggle_environments/envs/chess/chess.js +4289 -0
  15. kaggle_environments/envs/chess/chess.json +60 -0
  16. kaggle_environments/envs/chess/chess.py +4241 -0
  17. kaggle_environments/envs/chess/test_chess.py +60 -0
  18. kaggle_environments/envs/connectx/connectx.ipynb +3186 -0
  19. kaggle_environments/envs/connectx/connectx.js +1 -1
  20. kaggle_environments/envs/connectx/connectx.json +15 -1
  21. kaggle_environments/envs/connectx/connectx.py +6 -23
  22. kaggle_environments/envs/connectx/test_connectx.py +70 -24
  23. kaggle_environments/envs/football/football.ipynb +75 -0
  24. kaggle_environments/envs/football/football.json +91 -0
  25. kaggle_environments/envs/football/football.py +277 -0
  26. kaggle_environments/envs/football/helpers.py +95 -0
  27. kaggle_environments/envs/football/test_football.py +360 -0
  28. kaggle_environments/envs/halite/__init__.py +0 -0
  29. kaggle_environments/envs/halite/halite.ipynb +44741 -0
  30. kaggle_environments/envs/halite/halite.js +199 -83
  31. kaggle_environments/envs/halite/halite.json +31 -18
  32. kaggle_environments/envs/halite/halite.py +164 -303
  33. kaggle_environments/envs/halite/helpers.py +720 -0
  34. kaggle_environments/envs/halite/test_halite.py +190 -0
  35. kaggle_environments/envs/hungry_geese/__init__.py +0 -0
  36. kaggle_environments/envs/{battlegeese/battlegeese.js → hungry_geese/hungry_geese.js} +38 -22
  37. kaggle_environments/envs/{battlegeese/battlegeese.json → hungry_geese/hungry_geese.json} +22 -15
  38. kaggle_environments/envs/hungry_geese/hungry_geese.py +316 -0
  39. kaggle_environments/envs/hungry_geese/test_hungry_geese.py +0 -0
  40. kaggle_environments/envs/identity/identity.json +6 -5
  41. kaggle_environments/envs/identity/identity.py +15 -2
  42. kaggle_environments/envs/kore_fleets/__init__.py +0 -0
  43. kaggle_environments/envs/kore_fleets/helpers.py +1005 -0
  44. kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +114 -0
  45. kaggle_environments/envs/kore_fleets/kore_fleets.js +658 -0
  46. kaggle_environments/envs/kore_fleets/kore_fleets.json +164 -0
  47. kaggle_environments/envs/kore_fleets/kore_fleets.py +555 -0
  48. kaggle_environments/envs/kore_fleets/starter_bots/java/Bot.java +54 -0
  49. kaggle_environments/envs/kore_fleets/starter_bots/java/README.md +26 -0
  50. kaggle_environments/envs/kore_fleets/starter_bots/java/jars/hamcrest-core-1.3.jar +0 -0
  51. kaggle_environments/envs/kore_fleets/starter_bots/java/jars/junit-4.13.2.jar +0 -0
  52. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Board.java +518 -0
  53. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Cell.java +61 -0
  54. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Configuration.java +24 -0
  55. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Direction.java +166 -0
  56. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Fleet.java +72 -0
  57. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/KoreJson.java +97 -0
  58. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Observation.java +72 -0
  59. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Pair.java +13 -0
  60. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Player.java +68 -0
  61. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Point.java +65 -0
  62. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Shipyard.java +70 -0
  63. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/ShipyardAction.java +59 -0
  64. kaggle_environments/envs/kore_fleets/starter_bots/java/main.py +73 -0
  65. kaggle_environments/envs/kore_fleets/starter_bots/java/test/BoardTest.java +567 -0
  66. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ConfigurationTest.java +25 -0
  67. kaggle_environments/envs/kore_fleets/starter_bots/java/test/KoreJsonTest.java +62 -0
  68. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ObservationTest.java +46 -0
  69. kaggle_environments/envs/kore_fleets/starter_bots/java/test/PointTest.java +21 -0
  70. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ShipyardTest.java +22 -0
  71. kaggle_environments/envs/kore_fleets/starter_bots/java/test/configuration.json +1 -0
  72. kaggle_environments/envs/kore_fleets/starter_bots/java/test/fullob.json +1 -0
  73. kaggle_environments/envs/kore_fleets/starter_bots/java/test/observation.json +1 -0
  74. kaggle_environments/envs/kore_fleets/starter_bots/python/__init__.py +0 -0
  75. kaggle_environments/envs/kore_fleets/starter_bots/python/main.py +27 -0
  76. kaggle_environments/envs/kore_fleets/starter_bots/ts/Bot.ts +34 -0
  77. kaggle_environments/envs/kore_fleets/starter_bots/ts/DoNothingBot.ts +12 -0
  78. kaggle_environments/envs/kore_fleets/starter_bots/ts/MinerBot.ts +62 -0
  79. kaggle_environments/envs/kore_fleets/starter_bots/ts/README.md +55 -0
  80. kaggle_environments/envs/kore_fleets/starter_bots/ts/interpreter.ts +402 -0
  81. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Board.ts +514 -0
  82. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Cell.ts +63 -0
  83. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Configuration.ts +25 -0
  84. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Direction.ts +169 -0
  85. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Fleet.ts +76 -0
  86. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/KoreIO.ts +70 -0
  87. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Observation.ts +45 -0
  88. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Pair.ts +11 -0
  89. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Player.ts +68 -0
  90. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Point.ts +65 -0
  91. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Shipyard.ts +72 -0
  92. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/ShipyardAction.ts +58 -0
  93. kaggle_environments/envs/kore_fleets/starter_bots/ts/main.py +73 -0
  94. kaggle_environments/envs/kore_fleets/starter_bots/ts/miner.py +73 -0
  95. kaggle_environments/envs/kore_fleets/starter_bots/ts/package.json +23 -0
  96. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/BoardTest.ts +551 -0
  97. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ConfigurationTest.ts +16 -0
  98. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ObservationTest.ts +33 -0
  99. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/PointTest.ts +17 -0
  100. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ShipyardTest.ts +18 -0
  101. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/configuration.json +1 -0
  102. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/fullob.json +1 -0
  103. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/observation.json +1 -0
  104. kaggle_environments/envs/kore_fleets/starter_bots/ts/tsconfig.json +22 -0
  105. kaggle_environments/envs/kore_fleets/test_kore_fleets.py +331 -0
  106. kaggle_environments/envs/lux_ai_2021/README.md +3 -0
  107. kaggle_environments/envs/lux_ai_2021/__init__.py +0 -0
  108. kaggle_environments/envs/lux_ai_2021/agents.py +11 -0
  109. kaggle_environments/envs/lux_ai_2021/dimensions/754.js +2 -0
  110. kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
  111. kaggle_environments/envs/lux_ai_2021/dimensions/main.js +1 -0
  112. kaggle_environments/envs/lux_ai_2021/index.html +43 -0
  113. kaggle_environments/envs/lux_ai_2021/lux_ai_2021.json +100 -0
  114. kaggle_environments/envs/lux_ai_2021/lux_ai_2021.py +231 -0
  115. kaggle_environments/envs/lux_ai_2021/test_agents/__init__.py +0 -0
  116. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.js +6 -0
  117. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.json +59 -0
  118. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_objects.js +145 -0
  119. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/io.js +14 -0
  120. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/kit.js +209 -0
  121. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/map.js +107 -0
  122. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/parser.js +79 -0
  123. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.js +88 -0
  124. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.py +75 -0
  125. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -0
  126. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/__init__.py +0 -0
  127. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/annotate.py +20 -0
  128. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/constants.py +25 -0
  129. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game.py +86 -0
  130. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.json +59 -0
  131. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.py +7 -0
  132. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_map.py +106 -0
  133. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_objects.py +154 -0
  134. kaggle_environments/envs/lux_ai_2021/test_agents/python/random_agent.py +38 -0
  135. kaggle_environments/envs/lux_ai_2021/test_agents/python/simple_agent.py +82 -0
  136. kaggle_environments/envs/lux_ai_2021/test_lux.py +19 -0
  137. kaggle_environments/envs/lux_ai_2021/testing.md +23 -0
  138. kaggle_environments/envs/lux_ai_2021/todo.md.og +18 -0
  139. kaggle_environments/envs/lux_ai_s3/README.md +21 -0
  140. kaggle_environments/envs/lux_ai_s3/agents.py +5 -0
  141. kaggle_environments/envs/lux_ai_s3/index.html +42 -0
  142. kaggle_environments/envs/lux_ai_s3/lux_ai_s3.json +47 -0
  143. kaggle_environments/envs/lux_ai_s3/lux_ai_s3.py +178 -0
  144. kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
  145. kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +819 -0
  146. kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +9 -0
  147. kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
  148. kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +141 -0
  149. kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +222 -0
  150. kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +27 -0
  151. kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +464 -0
  152. kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
  153. kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +156 -0
  154. kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +78 -0
  155. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/__init__.py +0 -0
  156. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/kit.py +31 -0
  157. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/utils.py +17 -0
  158. kaggle_environments/envs/lux_ai_s3/test_agents/python/main.py +66 -0
  159. kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
  160. kaggle_environments/envs/mab/__init__.py +0 -0
  161. kaggle_environments/envs/mab/agents.py +12 -0
  162. kaggle_environments/envs/mab/mab.js +100 -0
  163. kaggle_environments/envs/mab/mab.json +74 -0
  164. kaggle_environments/envs/mab/mab.py +146 -0
  165. kaggle_environments/envs/open_spiel/__init__.py +0 -0
  166. kaggle_environments/envs/open_spiel/games/__init__.py +0 -0
  167. kaggle_environments/envs/open_spiel/games/chess/chess.js +441 -0
  168. kaggle_environments/envs/open_spiel/games/chess/image_config.jsonl +20 -0
  169. kaggle_environments/envs/open_spiel/games/chess/openings.jsonl +20 -0
  170. kaggle_environments/envs/open_spiel/games/connect_four/__init__.py +0 -0
  171. kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js +284 -0
  172. kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py +86 -0
  173. kaggle_environments/envs/open_spiel/games/go/__init__.py +0 -0
  174. kaggle_environments/envs/open_spiel/games/go/go.js +481 -0
  175. kaggle_environments/envs/open_spiel/games/go/go_proxy.py +99 -0
  176. kaggle_environments/envs/open_spiel/games/tic_tac_toe/__init__.py +0 -0
  177. kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe.js +345 -0
  178. kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe_proxy.py +98 -0
  179. kaggle_environments/envs/open_spiel/games/universal_poker/__init__.py +0 -0
  180. kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker.js +431 -0
  181. kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker_proxy.py +159 -0
  182. kaggle_environments/envs/open_spiel/html_playthrough_generator.py +31 -0
  183. kaggle_environments/envs/open_spiel/observation.py +128 -0
  184. kaggle_environments/envs/open_spiel/open_spiel.py +565 -0
  185. kaggle_environments/envs/open_spiel/proxy.py +138 -0
  186. kaggle_environments/envs/open_spiel/test_open_spiel.py +191 -0
  187. kaggle_environments/envs/rps/__init__.py +0 -0
  188. kaggle_environments/envs/rps/agents.py +84 -0
  189. kaggle_environments/envs/rps/helpers.py +25 -0
  190. kaggle_environments/envs/rps/rps.js +117 -0
  191. kaggle_environments/envs/rps/rps.json +63 -0
  192. kaggle_environments/envs/rps/rps.py +90 -0
  193. kaggle_environments/envs/rps/test_rps.py +110 -0
  194. kaggle_environments/envs/rps/utils.py +7 -0
  195. kaggle_environments/envs/tictactoe/test_tictactoe.py +43 -77
  196. kaggle_environments/envs/tictactoe/tictactoe.ipynb +1397 -0
  197. kaggle_environments/envs/tictactoe/tictactoe.json +10 -2
  198. kaggle_environments/envs/tictactoe/tictactoe.py +1 -1
  199. kaggle_environments/errors.py +2 -4
  200. kaggle_environments/helpers.py +377 -0
  201. kaggle_environments/main.py +214 -50
  202. kaggle_environments/schemas.json +23 -18
  203. kaggle_environments/static/player.html +206 -74
  204. kaggle_environments/utils.py +46 -73
  205. kaggle_environments-1.20.0.dist-info/METADATA +25 -0
  206. kaggle_environments-1.20.0.dist-info/RECORD +211 -0
  207. {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info}/WHEEL +1 -2
  208. kaggle_environments-1.20.0.dist-info/entry_points.txt +3 -0
  209. kaggle_environments/envs/battlegeese/battlegeese.py +0 -219
  210. kaggle_environments/temp.py +0 -14
  211. kaggle_environments-0.2.0.dist-info/METADATA +0 -393
  212. kaggle_environments-0.2.0.dist-info/RECORD +0 -33
  213. kaggle_environments-0.2.0.dist-info/entry_points.txt +0 -3
  214. kaggle_environments-0.2.0.dist-info/top_level.txt +0 -1
  215. {kaggle_environments-0.2.0.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.",
@@ -122,5 +122,5 @@ with open(jsonpath) as f:
122
122
 
123
123
  def html_renderer():
124
124
  jspath = path.abspath(path.join(path.dirname(__file__), "tictactoe.js"))
125
- with open(jspath) as f:
125
+ with open(jspath, encoding="utf-8") as f:
126
126
  return f.read()
@@ -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 status in codes:
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 {}