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.

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 +295 -170
  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} +21 -14
  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 +340 -0
  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.1.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 -223
  210. kaggle_environments/temp.py +0 -14
  211. kaggle_environments-0.2.1.dist-info/METADATA +0 -393
  212. kaggle_environments-0.2.1.dist-info/RECORD +0 -32
  213. kaggle_environments-0.2.1.dist-info/entry_points.txt +0 -3
  214. kaggle_environments-0.2.1.dist-info/top_level.txt +0 -1
  215. {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,231 @@
1
+ import atexit
2
+ import json
3
+ import math
4
+ import random
5
+ import sys
6
+ from os import path
7
+ from queue import Empty, Queue
8
+ from subprocess import PIPE, Popen
9
+ from threading import Thread
10
+
11
+ from .agents import agents as all_agents
12
+ from .test_agents.python.lux.game import Game
13
+
14
+ t = None
15
+ q = None
16
+ dimension_process = None
17
+ game_state = Game()
18
+ prev_step = 0
19
+
20
+
21
+ def cleanup_dimensions():
22
+ global dimension_process
23
+ if dimension_process is not None:
24
+ dimension_process.kill()
25
+
26
+
27
+ def enqueue_output(out, queue):
28
+ for line in iter(out.readline, b""):
29
+ queue.put(line)
30
+ out.close()
31
+
32
+
33
+ def interpreter(state, env):
34
+ global dimension_process, game_state, t, q, prev_step
35
+ player1 = state[0]
36
+ player2 = state[1]
37
+
38
+ ### 1.1: Initialize dimensions in the background within the orchestrator if we haven't already ###
39
+ if dimension_process is None:
40
+ # dimension_process = Popen(["ts-node", "-P", path.abspath(path.join(dir_path, "dimensions/tsconfig.json")), path.abspath(path.join(dir_path, "dimensions/run.ts"))], stdin=PIPE, stdout=PIPE)
41
+ try:
42
+ dimension_process = Popen(
43
+ ["node", path.abspath(path.join(dir_path, "dimensions/main.js"))], stdin=PIPE, stdout=PIPE, stderr=PIPE
44
+ )
45
+ except FileNotFoundError:
46
+ import warnings
47
+
48
+ warnings.warn("Node not installed")
49
+ return state
50
+
51
+ # following 4 lines from https://stackoverflow.com/questions/375427/a-non-blocking-read-on-a-subprocess-pipe-in-python
52
+ q = Queue()
53
+ t = Thread(target=enqueue_output, args=(dimension_process.stdout, q))
54
+ t.daemon = True # thread dies with the program
55
+ t.start()
56
+ atexit.register(cleanup_dimensions)
57
+
58
+ # filter out actions such as debug annotations so they aren't saved
59
+ filter_actions(state, env)
60
+
61
+ ### 1.2: Initialize a blank state game if new episode is starting ###
62
+ if env.done:
63
+ # TODO: allow resetting to a specific state
64
+ # print("Initialize game", "steps", len(env.steps), "prev_step", prev_step)
65
+ # last_state = None
66
+ # if prev_step >= len(env.steps):
67
+ # last_state = env.steps[-1]
68
+ # prev_step = len(env.steps)
69
+ # print("prev_step now", prev_step)
70
+ if "seed" in env.configuration:
71
+ seed = env.configuration["seed"]
72
+ else:
73
+ seed = math.floor(random.random() * 1e9)
74
+ env.configuration["seed"] = seed
75
+ if "loglevel" in env.configuration:
76
+ loglevel = env.configuration["loglevel"]
77
+ else:
78
+ loglevel = 0 # warnings, 1: errors, 0: none
79
+ env.configuration["loglevel"] = loglevel
80
+ if "annotations" in env.configuration:
81
+ annotations = env.configuration["annotations"]
82
+ else:
83
+ annotations = False # warnings, 1: errors, 0: none
84
+ env.configuration["annotations"] = annotations
85
+
86
+ if "width" in env.configuration:
87
+ width = env.configuration["width"]
88
+ else:
89
+ width = -1 # -1 for randomly selected
90
+ env.configuration["width"] = width
91
+ if "height" in env.configuration:
92
+ height = env.configuration["height"]
93
+ else:
94
+ height = -1 # -1 for randomly selected
95
+ env.configuration["height"] = height
96
+
97
+ initiate = {
98
+ "type": "start",
99
+ "agent_names": [], # unsure if this is provided?
100
+ "config": env.configuration,
101
+ }
102
+ # if last_state is not None:
103
+ # initiate["state"] = last_state
104
+ dimension_process.stdin.write((json.dumps(initiate) + "\n").encode())
105
+ dimension_process.stdin.flush()
106
+
107
+ agent1res = get_message(dimension_process)
108
+ agent2res = get_message(dimension_process)
109
+ match_obs_meta = get_message(dimension_process)
110
+
111
+ player1.observation.player = 0
112
+ player2.observation.player = 1
113
+ player1.observation.updates = agent1res
114
+
115
+ # player2.observation.updates = agent2res # duplicated and not added
116
+ player1.observation.globalCityIDCount = match_obs_meta["globalCityIDCount"]
117
+ player1.observation.globalUnitIDCount = match_obs_meta["globalUnitIDCount"]
118
+ player1.observation.width = match_obs_meta["width"]
119
+ player1.observation.height = match_obs_meta["height"]
120
+
121
+ game_state = Game()
122
+ game_state._initialize(agent1res)
123
+
124
+ return state
125
+ # print("prev_step", prev_step, "stored steps", len(env.steps))
126
+ # prev_step += 1
127
+
128
+ ### 2. : Pass in actions (json representation along with id of who made that action), agent information (id, status) to dimensions via stdin
129
+ dimension_process.stdin.write((json.dumps(state) + "\n").encode())
130
+ dimension_process.stdin.flush()
131
+
132
+ ### 3.1 : Receive and parse the observations returned by dimensions via stdout
133
+ agent1res = json.loads(dimension_process.stderr.readline())
134
+ agent2res = json.loads(dimension_process.stderr.readline())
135
+ game_state._update(agent1res)
136
+
137
+ # receive meta info such as global ID and map sizes for purposes of being able to start from specific state
138
+ match_obs_meta = json.loads(dimension_process.stderr.readline())
139
+ match_status = json.loads(dimension_process.stderr.readline())
140
+
141
+ while True:
142
+ try:
143
+ line = q.get_nowait()
144
+ except Empty:
145
+ # no standard error received, break
146
+ break
147
+ else:
148
+ # standard error output received, print it out
149
+ print(line.decode(), file=sys.stderr, end="")
150
+
151
+ ### 3.2 : Send observations to each agent through here. Like dimensions, first observation can include initialization stuff, then we do the looping
152
+
153
+ player1.observation.updates = agent1res
154
+
155
+ player1.observation.globalCityIDCount = match_obs_meta["globalCityIDCount"]
156
+ player1.observation.globalUnitIDCount = match_obs_meta["globalUnitIDCount"]
157
+ player1.observation.width = match_obs_meta["width"]
158
+ player1.observation.height = match_obs_meta["height"]
159
+ # player2.observation.updates = agent2res # duplicated and not added
160
+
161
+ player1.observation.player = 0
162
+ player2.observation.player = 1
163
+
164
+ ### 3.3 : handle rewards
165
+ # reward here is defined as the sum of number of city tiles
166
+ player1.reward = compute_reward(game_state.players[0])
167
+ player2.reward = compute_reward(game_state.players[1])
168
+ player1.observation.reward = int(player1.reward)
169
+ player2.observation.reward = int(player2.reward)
170
+
171
+ ### 3.4 Handle finished match status
172
+ if match_status["status"] == "finished":
173
+ if player1.status == "ACTIVE":
174
+ player1.status = "DONE"
175
+ if player2.status == "ACTIVE":
176
+ player2.status = "DONE"
177
+ return state
178
+
179
+
180
+ def get_message(dimension_process):
181
+ raw = dimension_process.stderr.readline()
182
+ try:
183
+ res = json.loads(raw)
184
+ return res
185
+ except Exception:
186
+ print("Engine Exception")
187
+ err_stack = dimension_process.stderr.readlines(100)
188
+ # err_stack = [raw, *err_stack]
189
+ # print(err_stack)
190
+ for m in err_stack:
191
+ if len(m) < 1000:
192
+ print(m.decode(), file=sys.stderr)
193
+ else:
194
+ print("...", file=sys.stderr)
195
+
196
+
197
+ def filter_actions(state, env):
198
+ enable_annotations = env.configuration["annotations"]
199
+ if not enable_annotations:
200
+ for team in range(len(state)):
201
+ filtered = []
202
+ if state[team] is not None and state[team].action is not None:
203
+ for l in state[team].action:
204
+ if len(l) > 0 and l[0] != "d":
205
+ filtered.append(l)
206
+ state[team].action = filtered
207
+
208
+
209
+ def compute_reward(player):
210
+ ct_count = sum([len(v.citytiles) for k, v in player.cities.items()])
211
+ unit_count = len(game_state.players[player.team].units)
212
+ # max board size is 32 x 32 => 1024 max city tiles and units, so this should keep it strictly so we break by city tiles then unit count
213
+ return ct_count * 10000 + unit_count
214
+
215
+
216
+ def renderer(state, env):
217
+ raise NotImplementedError("To render the replay, please set the render mode to json or html")
218
+
219
+
220
+ dir_path = path.dirname(__file__)
221
+ json_path = path.abspath(path.join(dir_path, "lux_ai_2021.json"))
222
+ with open(json_path) as json_file:
223
+ specification = json.load(json_file)
224
+
225
+
226
+ def html_renderer():
227
+ html_path = path.abspath(path.join(dir_path, "index.html"))
228
+ return ("html_path", html_path)
229
+
230
+
231
+ agents = all_agents
@@ -0,0 +1,6 @@
1
+ /**
2
+ * All game constants
3
+ */
4
+ const GAME_CONSTANTS = require('./game_constants.json');
5
+
6
+ module.exports = GAME_CONSTANTS;
@@ -0,0 +1,59 @@
1
+ {
2
+ "UNIT_TYPES": {
3
+ "WORKER": 0,
4
+ "CART": 1
5
+ },
6
+ "RESOURCE_TYPES": {
7
+ "WOOD": "wood",
8
+ "COAL": "coal",
9
+ "URANIUM": "uranium"
10
+ },
11
+ "DIRECTIONS": {
12
+ "NORTH": "n",
13
+ "WEST": "w",
14
+ "EAST": "e",
15
+ "SOUTH": "s",
16
+ "CENTER": "c"
17
+ },
18
+ "PARAMETERS": {
19
+ "DAY_LENGTH": 30,
20
+ "NIGHT_LENGTH": 10,
21
+ "MAX_DAYS": 360,
22
+ "LIGHT_UPKEEP": {
23
+ "CITY": 30,
24
+ "WORKER": 4,
25
+ "CART": 10
26
+ },
27
+ "WOOD_GROWTH_RATE": 1.01,
28
+ "MAX_WOOD_AMOUNT": 500,
29
+ "CITY_BUILD_COST": 100,
30
+ "CITY_ADJACENCY_BONUS": 5,
31
+ "RESOURCE_CAPACITY": {
32
+ "WORKER": 100,
33
+ "CART": 2000
34
+ },
35
+ "WORKER_COLLECTION_RATE": {
36
+ "WOOD": 20,
37
+ "COAL": 5,
38
+ "URANIUM": 2
39
+ },
40
+ "RESOURCE_TO_FUEL_RATE": {
41
+ "WOOD": 1,
42
+ "COAL": 10,
43
+ "URANIUM": 40
44
+ },
45
+ "RESEARCH_REQUIREMENTS": {
46
+ "COAL": 50,
47
+ "URANIUM": 200
48
+ },
49
+ "CITY_ACTION_COOLDOWN": 10,
50
+ "UNIT_ACTION_COOLDOWN": {
51
+ "CART": 3,
52
+ "WORKER": 2
53
+ },
54
+ "MAX_ROAD": 6,
55
+ "MIN_ROAD": 0,
56
+ "CART_ROAD_DEVELOPMENT_RATE": 0.5,
57
+ "PILLAGE_RATE": 0.5
58
+ }
59
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * All game objects for access by user
3
+ */
4
+ const {
5
+ Position
6
+ } = require("./map");
7
+ const GAME_CONSTANTS = require("./game_constants");
8
+
9
+ /**
10
+ * holds all data related to a player
11
+ */
12
+ class Player {
13
+ constructor(teamid) {
14
+ this.team = teamid;
15
+ this.researchPoints = 0;
16
+ // map unit id to the unit
17
+ this.units = [];
18
+ this.cities = new Map();
19
+ this.cityTileCount = 0;
20
+ }
21
+ researchedCoal() {
22
+ return this.researchPoints >= GAME_CONSTANTS.PARAMETERS.RESEARCH_REQUIREMENTS.COAL;
23
+ }
24
+ researchedUranium() {
25
+ return this.researchPoints >= GAME_CONSTANTS.PARAMETERS.RESEARCH_REQUIREMENTS.URANIUM;
26
+ }
27
+ }
28
+
29
+ // all data related to a city
30
+ class City {
31
+ constructor(teamid, cityid, fuel, lightUpkeep) {
32
+ this.cityid = cityid;
33
+ this.team = teamid;
34
+ this.fuel = fuel;
35
+ this.citytiles = [];
36
+ this.lightUpkeep = lightUpkeep;
37
+ }
38
+ addCityTile(x, y, cooldown) {
39
+ const ct = new CityTile(this.team, this.cityid, x, y, cooldown)
40
+ this.citytiles.push(ct);
41
+ return ct;
42
+ }
43
+ getLightUpkeep() {
44
+ return this.lightUpkeep;
45
+ }
46
+ }
47
+
48
+ /** CityTile and Unit are both actionable and can return action strings to send to engine */
49
+ class CityTile {
50
+ constructor(teamid, cityid, x, y, cooldown) {
51
+ this.cityid = cityid;
52
+ this.team = teamid;
53
+ this.pos = new Position(x, y);
54
+ this.cooldown = cooldown;
55
+ }
56
+ /** Whether or not this unit can research or build */
57
+ canAct() {
58
+ return this.cooldown < 1;
59
+ }
60
+ /** returns command to ask this tile to research this turn */
61
+ research() {
62
+ return `r ${this.pos.x} ${this.pos.y}`;
63
+ }
64
+ /** returns command to ask this tile to build a worker this turn */
65
+ buildWorker() {
66
+ return `bw ${this.pos.x} ${this.pos.y}`;
67
+ }
68
+ /** returns command to ask this tile to build a cart this turn */
69
+ buildCart() {
70
+ return `bc ${this.pos.x} ${this.pos.y}`;
71
+ }
72
+ }
73
+
74
+ class Unit {
75
+ constructor(teamid, type, unitid, x, y, cooldown, wood, coal, uranium) {
76
+ this.pos = new Position(x, y);
77
+ this.team = teamid;
78
+ this.id = unitid;
79
+ this.type = type;
80
+ this.cooldown = cooldown;
81
+ this.cargo = {
82
+ wood,
83
+ coal,
84
+ uranium
85
+ }
86
+ }
87
+ isWorker() {
88
+ return this.type === GAME_CONSTANTS.UNIT_TYPES.WORKER;
89
+ }
90
+
91
+ isCart() {
92
+ return this.type === GAME_CONSTANTS.UNIT_TYPES.CART;
93
+ }
94
+
95
+ getCargoSpaceLeft() {
96
+ const spaceused = this.cargo.wood + this.cargo.coal + this.cargo.uranium;
97
+ if (this.type === GAME_CONSTANTS.UNIT_TYPES.WORKER) {
98
+ return GAME_CONSTANTS.PARAMETERS.RESOURCE_CAPACITY.WORKER - spaceused;
99
+ } else {
100
+ return GAME_CONSTANTS.PARAMETERS.RESOURCE_CAPACITY.CART - spaceused;
101
+ }
102
+ }
103
+
104
+ /** whether or not the unit can build where it is right now */
105
+ canBuild(gameMap) {
106
+ let cell = gameMap.getCellByPos(this.pos);
107
+ if (!cell.hasResource() && this.canAct() && (this.cargo.wood + this.cargo.coal + this.cargo.uranium) >= GAME_CONSTANTS.PARAMETERS.CITY_BUILD_COST) {
108
+ return true;
109
+ }
110
+ return false;
111
+ }
112
+
113
+ /** whether or not the unit can act or not. This does not check for potential collisions into other units or enemy cities */
114
+ canAct() {
115
+ return this.cooldown < 1;
116
+ }
117
+
118
+ /** return the command to move unit in the given direction */
119
+ move(dir) {
120
+ return `m ${this.id} ${dir}`;
121
+ }
122
+
123
+ /** return the command to transfer a resource from a source unit to a destination unit as specified by their ids or the units themselves */
124
+ transfer(destUnit, resourceType, amount) {
125
+ let destID = typeof destUnit === "string" ? destUnit : destUnit.id;
126
+ return `t ${this.id} ${destID} ${resourceType} ${amount}`;
127
+ }
128
+
129
+ /** return the command to build a city right under the worker */
130
+ buildCity() {
131
+ return `bcity ${this.id}`;
132
+ }
133
+
134
+ /** return the command to pillage whatever is underneath the worker */
135
+ pillage() {
136
+ return `p ${this.id}`;
137
+ }
138
+ }
139
+
140
+ module.exports = {
141
+ Player,
142
+ City,
143
+ Unit,
144
+ CityTile,
145
+ }
@@ -0,0 +1,14 @@
1
+ /** all constants related to any input from match engine */
2
+ const INPUT_CONSTANTS = {
3
+ DONE: 'D_DONE',
4
+ RESEARCH_POINTS: 'rp',
5
+ RESOURCES: 'r',
6
+ UNITS: 'u',
7
+ CITY: 'c',
8
+ CITY_TILES: 'ct',
9
+ ROADS: 'ccd',
10
+ }
11
+
12
+ module.exports = {
13
+ INPUT_CONSTANTS,
14
+ }
@@ -0,0 +1,209 @@
1
+ const fs = require('fs');
2
+ const readline = require('readline');
3
+
4
+ // Create parser and use ',' as the delimiter between commands being sent by the `Match` and `MatchEngine`
5
+ const Parser = require('./parser');
6
+ const {
7
+ GameMap
8
+ } = require('./map');
9
+ const {
10
+ INPUT_CONSTANTS
11
+ } = require('./io');
12
+ const {
13
+ Player,
14
+ City,
15
+ Unit,
16
+ } = require('./game_objects');
17
+ const GAME_CONSTANTS = require('./game_constants');
18
+ const parse = new Parser(' ');
19
+
20
+ /**
21
+ * Agent for sequential `Designs`
22
+ */
23
+ class Agent {
24
+ _setup() {
25
+
26
+ // Prepare to read input
27
+ const rl = readline.createInterface({
28
+ input: process.stdin,
29
+ output: null,
30
+ });
31
+
32
+ let buffer = [];
33
+ let currentResolve;
34
+ const makePromise = function () {
35
+ return new Promise((resolve) => {
36
+ currentResolve = resolve;
37
+ });
38
+ };
39
+ // on each line, push line to buffer
40
+ rl.on('line', (line) => {
41
+ buffer.push(line);
42
+ currentResolve();
43
+ currentPromise = makePromise();
44
+ });
45
+
46
+ // The current promise for retrieving the next line
47
+ let currentPromise = makePromise();
48
+
49
+ // with await, we pause process until there is input
50
+ const getLine = async () => {
51
+ return new Promise(async (resolve) => {
52
+ while (buffer.length === 0) {
53
+ // pause while buffer is empty, continue if new line read
54
+ await currentPromise;
55
+ }
56
+ // once buffer is not empty, resolve the most recent line in stdin, and remove it
57
+ resolve(parse(buffer.shift()));
58
+ });
59
+ };
60
+ this.getLine = getLine;
61
+ }
62
+
63
+ /**
64
+ * Constructor for a new agent
65
+ * User should edit this according to the `Design` this agent will compete under
66
+ */
67
+ constructor() {
68
+ this._setup(); // DO NOT REMOVE
69
+ }
70
+
71
+ /**
72
+ * Initialize Agent for the `Match`
73
+ * User should edit this according to their `Design`
74
+ */
75
+ async initialize() {
76
+
77
+ // get agent ID
78
+ const id = (await this.getLine()).nextInt();
79
+ // get some other necessary initial input
80
+ let mapInfo = (await this.getLine());
81
+ let width = mapInfo.nextInt();
82
+ let height = mapInfo.nextInt();
83
+ const map = new GameMap(width, height);
84
+ const players = [new Player(0), new Player(1)];
85
+
86
+ this.gameState = {
87
+ id,
88
+ map,
89
+ players,
90
+ turn: -1,
91
+ };
92
+ }
93
+ /**
94
+ * Updates agent's own known state of `Match`
95
+ * User should edit this according to their `Design`.
96
+ */
97
+ async update() {
98
+ this.gameState.turn++;
99
+ // wait for the engine to send any updates
100
+ await this.retrieveUpdates();
101
+ }
102
+
103
+ resetPlayerStates() {
104
+ let players = this.gameState.players;
105
+ players[0].units = [];
106
+ players[0].cities = new Map();
107
+ players[0].cityTileCount = 0;
108
+ players[1].units = [];
109
+ players[1].cities = new Map();
110
+ players[1].cityTileCount = 0;
111
+ }
112
+ async retrieveUpdates() {
113
+ this.resetPlayerStates();
114
+ // TODO: this can be optimized. we only reset because some resources get removed
115
+ this.gameState.map = new GameMap(this.gameState.map.width, this.gameState.map.height);
116
+ while (true) {
117
+ let update = (await this.getLine());
118
+ if (update.str === INPUT_CONSTANTS.DONE) {
119
+ break;
120
+ }
121
+ const inputIdentifier = update.nextStr();
122
+ switch (inputIdentifier) {
123
+ case INPUT_CONSTANTS.RESEARCH_POINTS: {
124
+ const team = update.nextInt();
125
+ this.gameState.players[team].researchPoints = update.nextInt();
126
+ break;
127
+ }
128
+ case INPUT_CONSTANTS.RESOURCES: {
129
+ const type = update.nextStr();
130
+ const x = update.nextInt();
131
+ const y = update.nextInt();
132
+ const amt = update.nextInt();
133
+ this.gameState.map._setResource(type, x, y, amt);
134
+ break;
135
+ }
136
+ case INPUT_CONSTANTS.UNITS: {
137
+ const unittype = update.nextInt();
138
+ const team = update.nextInt();
139
+ const unitid = update.nextStr();
140
+ const x = update.nextInt();
141
+ const y = update.nextInt();
142
+ const cooldown = update.nextFloat();
143
+ const wood = update.nextInt();
144
+ const coal = update.nextInt();
145
+ const uranium = update.nextInt();
146
+ this.gameState.players[team].units.push(new Unit(team, unittype, unitid, x, y, cooldown, wood, coal, uranium));
147
+ break;
148
+ }
149
+ case INPUT_CONSTANTS.CITY: {
150
+ const team = update.nextInt();
151
+ const cityid = update.nextStr();
152
+ const fuel = update.nextFloat();
153
+ const lightUpkeep = update.nextFloat();
154
+ this.gameState.players[team].cities.set(cityid, new City(team, cityid, fuel, lightUpkeep));
155
+ break;
156
+ }
157
+ case INPUT_CONSTANTS.CITY_TILES: {
158
+ const team = update.nextInt();
159
+ const cityid = update.nextStr();
160
+ const x = update.nextInt();
161
+ const y = update.nextInt();
162
+ const cooldown = update.nextFloat();
163
+ const city = this.gameState.players[team].cities.get(cityid);
164
+ const citytile = city.addCityTile(x, y, cooldown);
165
+ this.gameState.map.getCell(x, y).citytile = citytile;
166
+ this.gameState.players[team].cityTileCount += 1;
167
+ break;
168
+ }
169
+ case INPUT_CONSTANTS.ROADS: {
170
+ const x = update.nextInt();
171
+ const y = update.nextInt();
172
+ const road = update.nextFloat();
173
+ this.gameState.map.getCell(x, y).road = road;
174
+ break;
175
+ }
176
+ }
177
+ }
178
+ }
179
+
180
+ /**
181
+ * End a turn
182
+ */
183
+ endTurn() {
184
+ console.log('D_FINISH');
185
+ }
186
+ }
187
+
188
+ const annotate = {
189
+ circle: (x, y) => {
190
+ return `dc ${x} ${y}`
191
+ },
192
+ x: (x, y) => {
193
+ return `dx ${x} ${y}`
194
+ },
195
+ line: (x1, y1, x2, y2) => {
196
+ return `dl ${x1} ${y1} ${x2} ${y2}`
197
+ },
198
+ text: (x1, y1, message, fontsize = 16) => {
199
+ return `dt ${x1} ${y1} ${fontsize} '${message}'`
200
+ },
201
+ sidetext: (message) => {
202
+ return `dst '${message}'`
203
+ }
204
+ }
205
+
206
+ module.exports = {
207
+ Agent,
208
+ annotate
209
+ };