kaggle-environments 0.2.1__py3-none-any.whl → 1.20.1__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 (214) 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-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/METADATA +36 -114
  206. kaggle_environments-1.20.1.dist-info/RECORD +211 -0
  207. {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/WHEEL +1 -2
  208. kaggle_environments-1.20.1.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/RECORD +0 -32
  212. kaggle_environments-0.2.1.dist-info/entry_points.txt +0 -3
  213. kaggle_environments-0.2.1.dist-info/top_level.txt +0 -1
  214. {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,514 @@
1
+ import {Cell} from "./Cell";
2
+ import {Configuration} from "./Configuration";
3
+ import {Direction} from "./Direction";
4
+ import {Fleet} from "./Fleet";
5
+ import {Observation} from "./Observation";
6
+ import {Pair} from "./Pair";
7
+ import {Player} from "./Player";
8
+ import {Point} from "./Point";
9
+ import {Shipyard} from "./Shipyard";
10
+ import {ShipyardAction} from "./ShipyardAction";
11
+
12
+ export class Board {
13
+
14
+ public readonly shipyards: Map<string, Shipyard>;
15
+ public readonly fleets: Map<string, Fleet>;
16
+ public readonly players: Player[];
17
+ public currentPlayerId: number;
18
+ public readonly configuration: Configuration;
19
+ public step: number;
20
+ public readonly remainingOverageTime: number;
21
+ public readonly cells: Cell[];
22
+ public readonly size: number;
23
+
24
+ private uidCounter: number;
25
+
26
+ private constructor(shipyards: Map<string, Shipyard>, fleets: Map<string, Fleet>, players: Player[], currentPlayerId: number, configuration: Configuration, step: number, remainingOverageTime: number, cells: Cell[], size: number) {
27
+ this.shipyards = new Map<string, Shipyard>();
28
+ shipyards.forEach((shipyard, shipyardId) => this.shipyards.set(shipyardId, shipyard.cloneToBoard(this)));
29
+ this.fleets = new Map<string, Fleet>();
30
+ fleets.forEach((fleet, fleetId) => this.fleets.set(fleetId, fleet.cloneToBoard(this)));
31
+ this.players = players.map(player => player.cloneToBoard(this));
32
+ this.currentPlayerId = currentPlayerId;
33
+ this.configuration = configuration;
34
+ this.step = step;
35
+ this.remainingOverageTime = remainingOverageTime;
36
+ this.cells = cells.map(cell => cell.cloneToBoard(this));
37
+ this.size = size;
38
+ }
39
+
40
+ public cloneBoard(): Board {
41
+ return new Board(this.shipyards, this.fleets, this.players, this.currentPlayerId, this.configuration, this.step, this.remainingOverageTime, this.cells, this.size);
42
+ }
43
+
44
+ /**
45
+ * Creates a board from the provided observation, configuration, and nextActions as specified by
46
+ * https://github.com/Kaggle/kaggle-environments/blob/master/kaggle_environments/envs/kore/kore.json
47
+ * Board tracks players (by id), fleets (by id), shipyards (by id), and cells (by position).
48
+ * Each entity contains both key values (e.g. fleet.player_id) as well as entity references (e.g. fleet.player).
49
+ * References are deep and chainable e.g.
50
+ * [fleet.kore for player in board.players for fleet in player.fleets]
51
+ * fleet.player.shipyards()[0].cell.north.east.fleet
52
+ * Consumers should not set or modify any attributes except and Shipyard.nextAction
53
+ */
54
+ public static fromRaw(rawObservation: string, rawConfiguration: string): Board {
55
+ const observation = new Observation(rawObservation);
56
+
57
+ const step = observation.step;
58
+ const remainingOverageTime = observation.remainingOverageTime;
59
+ const configuration = new Configuration(rawConfiguration);
60
+ const currentPlayerId = observation.player;
61
+ const players = new Array<Player>(observation.playerHlt.length);
62
+ const fleets = new Map<string, Fleet>();
63
+ const shipyards = new Map<string, Shipyard>();
64
+ const cells = new Array<Cell>(observation.kore.length);
65
+ const size = configuration.size;
66
+
67
+ const board = new Board(shipyards, fleets, players, currentPlayerId, configuration, step, remainingOverageTime, cells, size)
68
+
69
+ // Create a cell for every point in a size x size grid
70
+ for (let x = 0; x < size; x++) {
71
+ for (let y = 0; y < size; y++) {
72
+ const position = new Point(x, y);
73
+ const kore = observation.kore[position.toIndex(size)];
74
+ // We'll populate the cell's fleets and shipyards in _add_fleet and addShipyard
75
+ board.cells[position.toIndex(size)] = new Cell(position, kore, "", "", board);
76
+ }
77
+
78
+ }
79
+
80
+
81
+ for (let playerId = 0; playerId < observation.playerHlt.length; playerId++) {
82
+ let playerKore = observation.playerHlt[playerId];
83
+ const playerShipyards = observation.playerShipyards[playerId];
84
+ const playerFleets = observation.playerFleets[playerId];
85
+ board.players[playerId] = new Player(playerId, playerKore, [], [], board);
86
+ //player_actions = nextActions[player_id] or {}
87
+
88
+ playerFleets.forEach((fleetStrs, fleetId) => {
89
+ const fleetPosIdx = parseInt(fleetStrs[0]);
90
+ const fleetKore = parseFloat(fleetStrs[1]);
91
+ const shipCount = parseInt(fleetStrs[2]);
92
+ const directionIdx = parseInt(fleetStrs[3]);
93
+ const flightPlan = fleetStrs[4];
94
+
95
+ const fleetPosition = Point.fromIndex(fleetPosIdx, size);
96
+ const fleetDirection = Direction.fromIndex(directionIdx);
97
+ board.addFleet(new Fleet(fleetId, shipCount, fleetDirection, fleetPosition, fleetKore, flightPlan, playerId, board));
98
+ })
99
+
100
+ playerShipyards.forEach((shipyardInts, shipyardId) => {
101
+ const shipyardPosIdx = shipyardInts[0];
102
+ const shipCount = shipyardInts[1];
103
+ const turnsControlled = shipyardInts[2];
104
+ const shipyardPosition = Point.fromIndex(shipyardPosIdx, size);
105
+ board.addShipyard(new Shipyard(shipyardId, shipCount, shipyardPosition, playerId, turnsControlled, board, undefined));
106
+ })
107
+ }
108
+ return board;
109
+ }
110
+
111
+ public getCellAtPosition(position: Point): Cell {
112
+ return this.cells[position.toIndex(this.size)];
113
+ }
114
+
115
+ public addFleet(fleet: Fleet): void {
116
+ fleet.player.fleetIds.push(fleet.id);
117
+ fleet.cell.fleetId = fleet.id;
118
+ this.fleets.set(fleet.id, fleet);
119
+ }
120
+
121
+ public addShipyard(shipyard: Shipyard): void {
122
+ shipyard.player.shipyardIds.push(shipyard.id);
123
+ shipyard.cell.shipyardId = shipyard.id;
124
+ shipyard.cell.kore = 0;
125
+ this.shipyards.set(shipyard.id, shipyard);
126
+ }
127
+
128
+ public deleteFleet(fleet: Fleet): void {
129
+ const fleetIds = fleet.player.fleetIds
130
+ fleetIds.splice(fleetIds.indexOf(fleet.id), 1);
131
+ if (fleet.cell.fleetId == fleet.id) {
132
+ fleet.cell.fleetId = "";
133
+ }
134
+ this.fleets.delete(fleet.id);
135
+ }
136
+
137
+ public deleteShipyard(shipyard: Shipyard): void {
138
+ const shipyardsIds = shipyard.player.shipyardIds;
139
+ shipyardsIds.splice(shipyardsIds.indexOf(shipyard.id), 1);
140
+ if (shipyard.cell.shipyardId == shipyard.id) {
141
+ shipyard.cell.shipyardId = "";
142
+ }
143
+ this.shipyards.delete(shipyard.id);
144
+ }
145
+
146
+ public getFleetAtPoint(position: Point): Fleet | undefined {
147
+ const matches = Array.from(this.fleets.values()).filter(fleet => fleet.position.equals(position));
148
+ return matches.length > 0 ? matches[0] : undefined;
149
+ }
150
+
151
+ public getShipyardAtPoint(position: Point): Shipyard | undefined {
152
+ const matches = Array.from(this.shipyards.values()).filter(shipyard => shipyard.position.equals(position));
153
+ return matches.length > 0 ? matches[0] : undefined;
154
+ }
155
+
156
+ /**
157
+ * Returns the current player (generally this is you).
158
+ * @return
159
+ */
160
+ public get currentPlayer(): Player {
161
+ return this.players[this.currentPlayerId];
162
+ }
163
+
164
+ /**
165
+ * Returns all players that aren't the current player.
166
+ * You can get all opponent fleets with [fleet for fleet in player.fleets for player in board.opponents]
167
+ */
168
+ public get opponents(): Player[] {
169
+ return this.players.filter(player => player.id != this.currentPlayerId);
170
+ }
171
+
172
+ private createUid(): string {
173
+ this.uidCounter += 1;
174
+ return `${this.step + 1}-${this.uidCounter - 1}`;
175
+ }
176
+
177
+ private isValidFlightPlan(flightPlan: string): boolean {
178
+ const allowed = "NESWC0123456789";
179
+ let matches = 0;
180
+ for (let i = 0; i < flightPlan.length; i++) {
181
+ const c = flightPlan.substring(i, i +1);
182
+ if (allowed.indexOf(c) === -1) {
183
+ return false;
184
+ }
185
+ }
186
+ return true;
187
+ }
188
+
189
+ private findFirstNonDigit(candidateStr: string): number {
190
+ if (candidateStr.length == 0) return 0;
191
+ for (let i = 0; i < candidateStr.length; i++) {
192
+ if (isNaN(Number(candidateStr.charAt(i)))) {
193
+ return i;
194
+ }
195
+ }
196
+ return candidateStr.length + 1;
197
+ }
198
+
199
+ private combineFleets(board: Board, fid1: string, fid2: string): string {
200
+ let f1 = board.fleets.get(fid1);
201
+ let f2 = board.fleets.get(fid2);
202
+ if (f1.lessThanOtherAlliedFleet(f2)) {
203
+ const temp = f1;
204
+ f1 = f2;
205
+ f2 = temp;
206
+ const tempS = fid1;
207
+ fid1 = fid2;
208
+ fid2 = tempS;
209
+ }
210
+ f1.kore += f2.kore;
211
+ f1.shipCount += f2.shipCount;
212
+ board.deleteFleet(f2);
213
+ return fid1;
214
+ }
215
+
216
+ /**
217
+ * Accepts the list of fleets at a particular position (must not be empty).
218
+ * Returns the fleet with the most ships or None in the case of a tie along with all other fleets.
219
+ */
220
+ public resolveCollision(fleets: Fleet[]): Pair<(Fleet | undefined), Fleet[]> {
221
+ if (fleets.length == 1) {
222
+ return new Pair<Fleet | undefined, Fleet[]>(fleets[0], []);
223
+ }
224
+ const fleetsByShips = new Map<number, Fleet[]>();
225
+ for (let fleet of fleets) {
226
+ const ships = fleet.shipCount;
227
+ if (!fleetsByShips.has(ships)) {
228
+ fleetsByShips.set(ships, []);
229
+ }
230
+ fleetsByShips.get(ships).push(fleet);
231
+ }
232
+ let mostShips = Math.max(...Array.from(fleetsByShips.keys()));
233
+ const largestFleets = fleetsByShips.get(mostShips);
234
+ if (largestFleets.length == 1) {
235
+ // There was a winner, return it
236
+ const winner = largestFleets[0];
237
+ return new Pair<(Fleet | undefined), Fleet[]>(winner, fleets.filter(f => !(f.id == winner.id)));
238
+ }
239
+ // There was a tie for most ships, all are deleted
240
+ return new Pair<(Fleet | undefined), Fleet[]>(undefined, fleets);
241
+ }
242
+
243
+
244
+ /**
245
+ * Returns a new board with the current board's next actions applied.
246
+ * The current board is unmodified.
247
+ * This can form a kore interpreter, e.g.
248
+ * next_observation = Board(current_observation, configuration, actions).next().observation
249
+ */
250
+ public next(): Board {
251
+ // Create a copy of the board to modify so we don't affect the current board
252
+ const board = this.cloneBoard();
253
+ const configuration = board.configuration;
254
+ const converstCost = configuration.convertCost;
255
+ const spawnCost = configuration.spawnCost;
256
+ this.uidCounter = 0;
257
+
258
+ // Process actions and store the results in the fleets and shipyards lists for collision checking
259
+ for (let player of board.players) {
260
+ // shipyard actions
261
+ for (let shipyard of player.shipyards) {
262
+ if (!shipyard.nextAction) {
263
+ continue;
264
+ }
265
+ const nextAction: ShipyardAction = shipyard.nextAction;
266
+
267
+ if (nextAction.shipCount == 0) {
268
+ continue;
269
+ }
270
+
271
+ if (nextAction.actionType == ShipyardAction.SPAWN && player.kore >= spawnCost * nextAction.shipCount && nextAction.shipCount <= shipyard.maxSpawn) {
272
+ player.kore -= spawnCost * nextAction.shipCount;
273
+ shipyard.shipCount += nextAction.shipCount;
274
+ } else if (nextAction.actionType == ShipyardAction.LAUNCH && shipyard.shipCount >= nextAction.shipCount) {
275
+ let flightPlan = nextAction.flightPlan;
276
+ if (flightPlan.length == 0 || !this.isValidFlightPlan(flightPlan)) {
277
+ continue;
278
+ }
279
+ shipyard.shipCount -= nextAction.shipCount;
280
+ const direction = Direction.fromChar(flightPlan.charAt(0));
281
+ const maxFlightPlanLen = Fleet.maxFlightPlanLenForShipCount(nextAction.shipCount);
282
+ if (flightPlan.length > maxFlightPlanLen) {
283
+ flightPlan = flightPlan.substring(0, maxFlightPlanLen);
284
+ }
285
+ board.addFleet(new Fleet(this.createUid(), nextAction.shipCount, direction, shipyard.position, 0, flightPlan, player.id, board));
286
+ }
287
+
288
+ }
289
+ // clear next action and increase turns controlled
290
+ for (let shipyard of player.shipyards) {
291
+ shipyard.nextAction = undefined;
292
+ shipyard.turnsControlled += 1;
293
+ }
294
+
295
+
296
+ // update fleets
297
+ for (let fleet of player.fleets) {
298
+ // remove any errant 0s
299
+ while (fleet.flightPlan.length > 0 && fleet.flightPlan.startsWith("0") ) {
300
+ fleet.flightPlan = fleet.flightPlan.substring(1);
301
+ }
302
+ if (fleet.flightPlan.length > 0 && fleet.flightPlan.startsWith("C") && fleet.shipCount >= converstCost && fleet.cell.shipyardId.length == 0) {
303
+ player.kore += fleet.kore;
304
+ fleet.cell.kore = 0;
305
+ board.addShipyard(new Shipyard(this.createUid(), fleet.shipCount - converstCost, fleet.position, player.id, 0, board, undefined));
306
+ board.deleteFleet(fleet);
307
+ continue;
308
+ }
309
+ // remove all converts
310
+ while (fleet.flightPlan.length > 0 && fleet.flightPlan.startsWith("C")) {
311
+ // couldn't build, remove the Convert and continue with flight plan
312
+ fleet.flightPlan = fleet.flightPlan.substring(1);
313
+ }
314
+
315
+ if (fleet.flightPlan.length > 0 && "NESW".indexOf(fleet.flightPlan.charAt(0)) > -1) {
316
+ fleet.direction = Direction.fromChar(fleet.flightPlan.charAt(0));
317
+ fleet.flightPlan = fleet.flightPlan.substring(1);
318
+ } else if (fleet.flightPlan.length > 0) {
319
+ const idx = this.findFirstNonDigit(fleet.flightPlan);
320
+ let digits = parseInt(fleet.flightPlan.substring(0, idx));
321
+ const rest = fleet.flightPlan.substring(idx);
322
+ digits -= 1;
323
+ if (digits > 0) {
324
+ fleet.flightPlan = digits.toString() + rest;
325
+ } else {
326
+ fleet.flightPlan = rest;
327
+ }
328
+ }
329
+
330
+ // continue moving in the fleet's direction
331
+ fleet.cell.fleetId = "";
332
+ fleet.position = fleet.position.translate(fleet.direction, configuration.size);
333
+ // We don't set the new cell's fleet_id here as it would be overwritten by another fleet in the case of collision.
334
+ }
335
+
336
+ const fleetsByLoc = new Map<number, Fleet[]>();
337
+ for (let fleet of player.fleets) {
338
+ const locIdx = fleet.position.toIndex(configuration.size);
339
+ if (!fleetsByLoc.has(locIdx)) {
340
+ fleetsByLoc.set(locIdx, []);
341
+ }
342
+ fleetsByLoc.get(locIdx).push(fleet);
343
+ }
344
+
345
+ for (let fleets of Array.from(fleetsByLoc.values())) {
346
+ fleets.sort((a, b) => {
347
+ if (a.shipCount != b.shipCount) {
348
+ return a.shipCount > b.shipCount ? -1 : 1;
349
+ }
350
+ if (a.kore != b.kore) {
351
+ return a.kore > b.kore ? -1 : 1;
352
+ }
353
+ return a.direction.toIndex() > a.direction.toIndex() ? 1 : -1;
354
+ })
355
+ let fid = fleets[0].id;
356
+ for (let i = 1; i < fleets.length; i++) {
357
+ fid = this.combineFleets(board, fid, fleets[i].id);
358
+ }
359
+
360
+ }
361
+ }
362
+
363
+
364
+ // Check for fleet to fleet collisions
365
+ const fleetCollisionGroups = new Map<number, Fleet[]>();
366
+ board.fleets.forEach(fleet => {
367
+ const posIdx = fleet.position.toIndex(board.size);
368
+ if (!fleetCollisionGroups.has(posIdx)) {
369
+ fleetCollisionGroups.set(posIdx, [fleet]);
370
+ } else {
371
+ fleetCollisionGroups.get(posIdx).push(fleet);
372
+ }
373
+ });
374
+ fleetCollisionGroups.forEach((collidedFleets, positionIdx) => {
375
+ const position = Point.fromIndex(positionIdx, configuration.size);
376
+ const pair = this.resolveCollision(collidedFleets);
377
+ const winnerOptional = pair.first;
378
+ const deleted = pair.second;
379
+ const shipyardOpt = board.getShipyardAtPoint(position);
380
+ if (winnerOptional) {
381
+ const winner: Fleet = winnerOptional;
382
+ winner.cell.fleetId = winner.id;
383
+ const maxEnemySize = deleted.length > 0 ? deleted.map(f => f.shipCount).reduce((a, b) => a > b ? a : b, 0) : 0;
384
+ winner.shipCount -= maxEnemySize;
385
+ }
386
+ for (let fleet of deleted) {
387
+ board.deleteFleet(fleet);
388
+ if (winnerOptional) {
389
+ // Winner takes deleted fleets' kore
390
+ (winnerOptional as Fleet).kore += fleet.kore;
391
+ } else if (!winnerOptional && shipyardOpt) {
392
+ // Desposit the kore into the shipyard
393
+ (shipyardOpt as Shipyard).player.kore += fleet.kore;
394
+ } else if (!winnerOptional) {
395
+ // Desposit the kore on the square
396
+ board.getCellAtPosition(position).kore += fleet.kore;
397
+ }
398
+ }
399
+ });
400
+
401
+ // Check for fleet to shipyard collisions
402
+ for (let shipyard of Array.from(board.shipyards.values())) {
403
+ const optFleet = shipyard.cell.fleet;
404
+ if (optFleet && (optFleet as Fleet).playerId != shipyard.playerId) {
405
+ const fleet = optFleet as Fleet;
406
+ if (fleet.shipCount > shipyard.shipCount) {
407
+ const count = fleet.shipCount - shipyard.shipCount;
408
+ board.deleteShipyard(shipyard);
409
+ board.addShipyard(new Shipyard(this.createUid(), count, shipyard.position, fleet.player.id, 1, board, undefined));
410
+ fleet.player.kore += fleet.kore;
411
+ board.deleteFleet(fleet);
412
+ } else {
413
+ shipyard.shipCount -= fleet.shipCount;
414
+ shipyard.player.kore += fleet.kore;
415
+ board.deleteFleet(fleet);
416
+ }
417
+ }
418
+ }
419
+
420
+ // Deposit kore from fleets into shipyards
421
+ for (let shipyard of Array.from(board.shipyards.values())) {
422
+ const optFleet = shipyard.cell.fleet;
423
+ if (optFleet && (optFleet as Fleet).playerId == shipyard.playerId) {
424
+ const fleet = optFleet as Fleet;
425
+ shipyard.player.kore += fleet.kore;
426
+ shipyard.shipCount += fleet.shipCount;
427
+ board.deleteFleet(fleet);
428
+ }
429
+ }
430
+
431
+ // apply fleet to fleet damage on all orthagonally adjacent cells
432
+ const incomingFleetDmg = new Map<string, Pair<string, number>[]>();
433
+ for (const fleet of Array.from(board.fleets.values())) {
434
+ for (const direction of Direction.listDirections()) {
435
+ const currPos = fleet.position.translate(direction, board.configuration.size);
436
+ const optFleet = board.getFleetAtPoint(currPos);
437
+ if (optFleet && (optFleet as Fleet).playerId != fleet.playerId) {
438
+ const toAttack = optFleet as Fleet;
439
+ if (!incomingFleetDmg.has(toAttack.id)) {
440
+ incomingFleetDmg.set(toAttack.id, []);
441
+ }
442
+ incomingFleetDmg.get(toAttack.id).push(new Pair(fleet.id, fleet.shipCount));
443
+ }
444
+ }
445
+ }
446
+
447
+ // dump 1/2 kore to the cell of killed flets
448
+ // mark the other 1/2 kore to go to attacking fleet proportionally
449
+ const toDistrubute = new Map<string, Pair<number, number>[]>();
450
+ incomingFleetDmg.forEach((attackers, fleetId) => {
451
+ const totalDamage = attackers.map(pair => pair.second).reduce((a, b) => a + b, 0);
452
+ const fleet = board.fleets.get(fleetId);
453
+ if (totalDamage >= fleet.shipCount) {
454
+ fleet.cell.kore += fleet.kore / 2;
455
+ attackers.forEach(p => {
456
+ const attackerId = p.first;
457
+ const attackerDmg = p.second;
458
+ if (!toDistrubute.has(attackerId)) {
459
+ toDistrubute.set(attackerId, []);
460
+ }
461
+ const toGet = fleet.kore / 2 * attackerDmg / totalDamage;
462
+ toDistrubute.get(attackerId).push(new Pair(fleet.cell.position.toIndex(board.configuration.size), toGet));
463
+ })
464
+ board.deleteFleet(fleet);
465
+ } else {
466
+ fleet.shipCount -= totalDamage;
467
+ }
468
+
469
+ });
470
+
471
+ // give kore claimed above to surviving fleets, otherwise add it back to the tile where the fleet died.
472
+ toDistrubute.forEach((resourceFromLocs, fleetId) => {
473
+ resourceFromLocs.forEach(p => {
474
+ const cellIdx = p.first;
475
+ const kore = p.second;
476
+ if (!board.fleets.has(fleetId)) {
477
+ board.cells[cellIdx].kore += kore;
478
+ } else {
479
+ const fleet = board.fleets.get(fleetId);
480
+ fleet.kore += kore;
481
+ }
482
+ });
483
+ });
484
+
485
+ // Collect kore from cells into fleets
486
+ for (const fleet of Array.from(board.fleets.values())) {
487
+ const cell = fleet.cell;
488
+ const deltaKore = Board.roundToThreePlaces(cell.kore * Math.min(fleet.collectionRate, .99));
489
+ if (deltaKore > 0) {
490
+ fleet.kore += deltaKore;
491
+ cell.kore -= deltaKore;
492
+ }
493
+ }
494
+
495
+ // Regenerate kore in cells
496
+ for (let cell of board.cells) {
497
+ if (cell.fleetId === "" && cell.shipyardId === "") {
498
+ if (cell.kore < configuration.maxRegenCellKore) {
499
+ const nextKore = Board.roundToThreePlaces(cell.kore * (1 + configuration.regenRate) * 1000.0) / 1000.0;
500
+ cell.kore = nextKore;
501
+ }
502
+ }
503
+ }
504
+
505
+ board.step += 1;
506
+
507
+ return board;
508
+ }
509
+
510
+ private static roundToThreePlaces(num: number): number {
511
+ return Math.round(num * 1000.0) / 1000.0;
512
+ }
513
+
514
+ }
@@ -0,0 +1,63 @@
1
+ import {Board} from "./Board";
2
+ import {Direction} from "./Direction";
3
+ import {Fleet} from "./Fleet";
4
+ import {Point} from "./Point";
5
+ import {Shipyard} from "./Shipyard";
6
+
7
+ export class Cell {
8
+
9
+ public readonly position: Point;
10
+ public kore: number;
11
+ public shipyardId: string;
12
+ public fleetId: string;
13
+ public readonly board: Board;
14
+
15
+ public constructor(position: Point, kore: number, shipyardId: string, fleetId: string, board: Board) {
16
+ this.position = position;
17
+ this.kore = kore;
18
+ this.shipyardId = shipyardId;
19
+ this.fleetId = fleetId;
20
+ this.board = board;
21
+ }
22
+
23
+ public cloneToBoard(board: Board): Cell {
24
+ return new Cell(this.position, this.kore, this.shipyardId, this.fleetId, board);
25
+ }
26
+
27
+ public get fleet(): Fleet | undefined {
28
+ if (this.board.fleets.has(this.fleetId)) {
29
+ return this.board.fleets.get(this.fleetId);
30
+ }
31
+ return undefined;
32
+ }
33
+
34
+
35
+ public get shipyard(): Shipyard | undefined {
36
+ if (this.board.shipyards.has(this.shipyardId)) {
37
+ return this.board.shipyards.get(this.shipyardId);
38
+ }
39
+ return undefined;
40
+ }
41
+
42
+ public neighbor(offset: Point): Cell {
43
+ const next = this.position.translate(offset, this.board.size);
44
+ return this.board.getCellAtPosition(next);
45
+ }
46
+
47
+
48
+ public north(): Cell {
49
+ return this.neighbor(Direction.NORTH);
50
+ }
51
+
52
+ public south(): Cell {
53
+ return this.neighbor((Direction.SOUTH));
54
+ }
55
+
56
+ public east(): Cell {
57
+ return this.neighbor(Direction.EAST);
58
+ }
59
+
60
+ public west(): Cell {
61
+ return this.neighbor(Direction.WEST);
62
+ }
63
+ }
@@ -0,0 +1,25 @@
1
+ export class Configuration {
2
+
3
+ public readonly agentTimeout: number;
4
+ public readonly startingKore: number;
5
+ public readonly size: number;
6
+ public readonly spawnCost: number;
7
+ public readonly convertCost: number;
8
+ public readonly regenRate: number;
9
+ public readonly maxRegenCellKore: number;
10
+ public readonly randomSeed: number;
11
+ public readonly episodeSteps: number;
12
+
13
+ public constructor(rawConfiguration: string) {
14
+ const config = JSON.parse(rawConfiguration);
15
+ this.agentTimeout = config.agentTimeout;
16
+ this.startingKore = config.startingKore;
17
+ this.size = config.size;
18
+ this.spawnCost = config.spawnCost;
19
+ this.convertCost = config.convertCost;
20
+ this.regenRate = config.regenRate;
21
+ this.maxRegenCellKore = config.maxRegenCellKore;
22
+ this.randomSeed = config.randomSeed;
23
+ this.episodeSteps = config.episodeSteps;
24
+ }
25
+ }