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
@@ -0,0 +1,107 @@
1
+ const GAME_CONSTANTS = require('./game_constants');
2
+ const DIRECTIONS = GAME_CONSTANTS.DIRECTIONS;
3
+ class GameMap {
4
+ constructor(width, height) {
5
+ this.height = height;
6
+ this.width = width;
7
+ this.map = new Array(this.height);
8
+
9
+ for (let y = 0; y < this.height; y++) {
10
+ this.map[y] = new Array(this.width);
11
+ for (let x = 0; x < this.width; x++) {
12
+ this.map[y][x] = new Cell(x, y);
13
+ }
14
+ }
15
+ }
16
+ getCellByPos(pos) {
17
+ return this.map[pos.y][pos.x];
18
+ }
19
+ getCell(x, y) {
20
+ return this.map[y][x];
21
+ }
22
+ _setResource(type, x, y, amount) {
23
+ const cell = this.getCell(x, y);
24
+ cell.resource = {
25
+ type: type,
26
+ amount: amount
27
+ }
28
+ }
29
+
30
+ }
31
+
32
+ class Cell {
33
+ constructor(x, y) {
34
+ this.pos = new Position(x, y);
35
+ this.resource = null;
36
+ this.citytile = null;
37
+ this.road = 0;
38
+ }
39
+ hasResource() {
40
+ return this.resource !== null && this.resource.amount > 0;
41
+ }
42
+ }
43
+
44
+ class Position {
45
+ constructor(x, y) {
46
+ this.x = x;
47
+ this.y = y;
48
+ }
49
+ isAdjacent(pos) {
50
+ const dx = this.x - pos.x;
51
+ const dy = this.y - pos.y;
52
+ if (Math.abs(dx) + Math.abs(dy) > 1) {
53
+ return false;
54
+ }
55
+ return true;
56
+ }
57
+ equals(pos) {
58
+ return this.x === pos.x && this.y === pos.y;
59
+ }
60
+
61
+ translate(direction, units) {
62
+ switch (direction) {
63
+ case DIRECTIONS.NORTH:
64
+ return new Position(this.x, this.y - units);
65
+ case DIRECTIONS.EAST:
66
+ return new Position(this.x + units, this.y);
67
+ case DIRECTIONS.SOUTH:
68
+ return new Position(this.x, this.y + units);
69
+ case DIRECTIONS.WEST:
70
+ return new Position(this.x - units, this.y);
71
+ case DIRECTIONS.CENTER:
72
+ return new Position(this.x, this.y);
73
+ }
74
+ }
75
+
76
+ /** Returns Manhattan distance to pos from this position */
77
+ distanceTo(pos) {
78
+ return Math.abs(pos.x - this.x) + Math.abs(pos.y - this.y);
79
+ }
80
+
81
+ /** Returns closest direction to targetPos, or null if staying put is best */
82
+ directionTo(targetPos) {
83
+ const checkDirections = [
84
+ DIRECTIONS.NORTH,
85
+ DIRECTIONS.EAST,
86
+ DIRECTIONS.SOUTH,
87
+ DIRECTIONS.WEST,
88
+ ];
89
+ let closestDirection = DIRECTIONS.CENTER;
90
+ let closestDist = this.distanceTo(targetPos);
91
+ checkDirections.forEach((dir) => {
92
+ const newpos = this.translate(dir, 1);
93
+ const dist = targetPos.distanceTo(newpos);
94
+ if (dist < closestDist) {
95
+ closestDist = dist;
96
+ closestDirection = dir;
97
+ }
98
+ });
99
+ return closestDirection;
100
+ }
101
+ }
102
+
103
+ module.exports = {
104
+ GameMap,
105
+ Cell,
106
+ Position,
107
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Parser class to help parse a input line of data
3
+ */
4
+ class Parser {
5
+
6
+ constructor(d = ',') {
7
+ this.delimiter = d;
8
+ return this.parse.bind(this);
9
+ }
10
+ setDelimeter(s) {
11
+ this.delimiter = s;
12
+ }
13
+ parse(str) {
14
+ return new Parsed(str, this.delimiter);
15
+ }
16
+
17
+ }
18
+ class Parsed {
19
+ constructor(str, d) {
20
+ this.str = str;
21
+ this.contents = str.split(d);
22
+
23
+ // remove the last element if its empty string
24
+ if (this.contents[this.contents.length - 1] === '') {
25
+ this.contents = this.contents.slice(0, this.contents.length - 1);
26
+ }
27
+ this.index = 0;
28
+ }
29
+ _nextStr() {
30
+ if (this.index < this.contents.length) {
31
+ return this.contents[this.index++];
32
+ }
33
+ else {
34
+ throw new Error("No more contents to consume from line")
35
+ }
36
+ }
37
+ // Returns the remainder of the line as an array of integers
38
+ nextIntArr() {
39
+ if (this.index < this.contents.length) {
40
+ let remainder = this.contents.slice(this.index, this.contents.length).map((val) => parseInt(val));
41
+ return remainder;
42
+ }
43
+ else {
44
+ throw new Error("No more contents to consume from line")
45
+ }
46
+ }
47
+ nextInt() {
48
+ let str = this._nextStr();
49
+ return parseInt(str);
50
+ }
51
+ // Returns the remainder of the line as an array of floats
52
+ nextFloatArr() {
53
+ if (this.index < this.contents.length) {
54
+ let remainder = this.contents.slice(this.index++).map((val) => parseFloat(val));
55
+ return remainder;
56
+ }
57
+ else {
58
+ throw new Error("No more contents to consume from line")
59
+ }
60
+ }
61
+ nextFloat() {
62
+ let str = this._nextStr();
63
+ return parseFloat(str);
64
+ }
65
+ // Returns the remainder of the line as an array of strings
66
+ nextStrArr() {
67
+ if (this.index < this.contents.length) {
68
+ let remainder = this.contents.slice(this.index++);
69
+ return remainder;
70
+ }
71
+ else {
72
+ throw new Error("No more contents to consume from line")
73
+ }
74
+ }
75
+ nextStr() {
76
+ return this._nextStr();
77
+ }
78
+ }
79
+ module.exports = Parser
@@ -0,0 +1,88 @@
1
+ const kit = require('./lux/kit');
2
+ const GAME_CONSTANTS = require('./lux/game_constants');
3
+ const DIRECTIONS = GAME_CONSTANTS.DIRECTIONS;
4
+ // create a new agent
5
+ const agent = new kit.Agent();
6
+ const annotate = kit.annotate;
7
+
8
+ // first initialize the agent, and then proceed to go in a loop waiting for updates and running the AI
9
+ agent.initialize().then(async () => {
10
+ while (true) {
11
+ /** Do not edit! **/
12
+ // wait for updates
13
+ await agent.update();
14
+
15
+ const actions = [];
16
+ const gameState = agent.gameState;
17
+ /** AI Code Goes Below! **/
18
+
19
+ const player = gameState.players[gameState.id];
20
+ const opponent = gameState.players[(gameState.id + 1) % 2];
21
+ const gameMap = gameState.map;
22
+
23
+ const resourceTiles = [];
24
+ for (let y = 0; y < gameMap.height; y++) {
25
+ for (let x = 0; x < gameMap.width; x++) {
26
+ const cell = gameMap.getCell(x, y);
27
+ if (cell.hasResource()) {
28
+ resourceTiles.push(cell);
29
+ }
30
+ }
31
+ }
32
+
33
+ // we iterate over all our units and do something with them
34
+ for (let i = 0; i < player.units.length; i++) {
35
+ const unit = player.units[i];
36
+ if (unit.isWorker() && unit.canAct()) {
37
+ if (unit.getCargoSpaceLeft() > 0) {
38
+ // if the unit is a worker and we have space in cargo, lets find the nearest resource tile and try to mine it
39
+ let closestResourceTile = null;
40
+ let closestDist = 9999999;
41
+ resourceTiles.forEach((cell) => {
42
+ if (cell.resource.type === GAME_CONSTANTS.RESOURCE_TYPES.COAL && !player.researchedCoal()) return;
43
+ if (cell.resource.type === GAME_CONSTANTS.RESOURCE_TYPES.URANIUM && !player.researchedUranium()) return;
44
+ const dist = cell.pos.distanceTo(unit.pos);
45
+ if (dist < closestDist) {
46
+ closestDist = dist;
47
+ closestResourceTile = cell;
48
+ }
49
+ })
50
+ if (closestResourceTile != null) {
51
+ const dir = unit.pos.directionTo(closestResourceTile.pos);
52
+ // move the unit in the direction towards the closest resource tile's position.
53
+ actions.push(unit.move(dir));
54
+ }
55
+ } else {
56
+ // if unit is a worker and there is no cargo space left, and we have cities, lets return to them
57
+ if (player.cities.size > 0) {
58
+ const city = player.cities.values().next().value
59
+ let closestDist = 999999;
60
+ let closestCityTile = null;
61
+
62
+ city.citytiles.forEach((citytile) => {
63
+ const dist = citytile.pos.distanceTo(unit.pos);
64
+ if (dist < closestDist) {
65
+ closestCityTile = citytile;
66
+ closestDist = dist;
67
+ }
68
+ });
69
+ if (closestCityTile != null) {
70
+ const dir = unit.pos.directionTo(closestCityTile.pos);
71
+ actions.push(unit.move(dir));
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ // you can add debug annotations using the functions in the annotate object
79
+ // actions.push(annotate.circle(0, 0))
80
+
81
+ /** AI Code Goes Above! **/
82
+
83
+ /** Do not edit! **/
84
+ console.log(actions.join(","));
85
+ // end turn
86
+ agent.endTurn();
87
+ }
88
+ });
@@ -0,0 +1,75 @@
1
+ import atexit
2
+ import os
3
+ import sys
4
+ from queue import Empty, Queue
5
+ from subprocess import PIPE, Popen
6
+ from threading import Thread
7
+
8
+ agent_processes = [None, None]
9
+ t = None
10
+ q = None
11
+
12
+
13
+ def cleanup_process():
14
+ global agent_processes
15
+ for proc in agent_processes:
16
+ if proc is not None:
17
+ proc.kill()
18
+
19
+
20
+ def enqueue_output(out, queue):
21
+ for line in iter(out.readline, b""):
22
+ queue.put(line)
23
+ out.close()
24
+
25
+
26
+ def js_agent(observation, configuration):
27
+ """
28
+ a wrapper around a js agent
29
+ """
30
+ global agent_processes, t, q
31
+
32
+ agent_process = agent_processes[observation.player]
33
+ ### Do not edit ###
34
+ if agent_process is None:
35
+ if "__raw_path__" in configuration:
36
+ cwd = os.path.dirname(configuration["__raw_path__"])
37
+ else:
38
+ cwd = os.path.dirname(__file__)
39
+ agent_process = Popen(["node", "main.js"], stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd)
40
+ agent_processes[observation.player] = agent_process
41
+ atexit.register(cleanup_process)
42
+
43
+ # following 4 lines from https://stackoverflow.com/questions/375427/a-non-blocking-read-on-a-subprocess-pipe-in-python
44
+ q = Queue()
45
+ t = Thread(target=enqueue_output, args=(agent_process.stderr, q))
46
+ t.daemon = True # thread dies with the program
47
+ t.start()
48
+ if observation.step == 0:
49
+ # fixes bug where updates array is shared, but the first update is agent dependent actually
50
+ observation["updates"][0] = f"{observation.player}"
51
+
52
+ # print observations to agent
53
+ agent_process.stdin.write(("\n".join(observation["updates"]) + "\n").encode())
54
+ agent_process.stdin.flush()
55
+
56
+ # wait for data written to stdout
57
+ agent1res = (agent_process.stdout.readline()).decode()
58
+ _end_res = (agent_process.stdout.readline()).decode()
59
+
60
+ while True:
61
+ try:
62
+ line = q.get_nowait()
63
+ except Empty:
64
+ # no standard error received, break
65
+ break
66
+ else:
67
+ # standard error output received, print it out
68
+ print(line.decode(), file=sys.stderr, end="")
69
+
70
+ outputs = agent1res.split("\n")[0].split(",")
71
+ actions = []
72
+ for cmd in outputs:
73
+ if cmd != "":
74
+ actions.append(cmd)
75
+ return actions
@@ -0,0 +1,20 @@
1
+ def circle(x: int, y: int) -> str:
2
+ return f"dc {x} {y}"
3
+
4
+
5
+ def x(x: int, y: int) -> str:
6
+ return f"dx {x} {y}"
7
+
8
+
9
+ def line(x1: int, y1: int, x2: int, y2: int) -> str:
10
+ return f"dl {x1} {y1} {x2} {y2}"
11
+
12
+
13
+ # text at cell on map
14
+ def text(x: int, y: int, message: str, fontsize: int = 16) -> str:
15
+ return f"dt {x} {y} {fontsize} '{message}'"
16
+
17
+
18
+ # text besides map
19
+ def sidetext(message: str) -> str:
20
+ return f"dst '{message}'"
@@ -0,0 +1,25 @@
1
+ class Constants:
2
+ class INPUT_CONSTANTS:
3
+ RESEARCH_POINTS = "rp"
4
+ RESOURCES = "r"
5
+ UNITS = "u"
6
+ CITY = "c"
7
+ CITY_TILES = "ct"
8
+ ROADS = "ccd"
9
+ DONE = "D_DONE"
10
+
11
+ class DIRECTIONS:
12
+ NORTH = "n"
13
+ WEST = "w"
14
+ SOUTH = "s"
15
+ EAST = "e"
16
+ CENTER = "c"
17
+
18
+ class UNIT_TYPES:
19
+ WORKER = 0
20
+ CART = 1
21
+
22
+ class RESOURCE_TYPES:
23
+ WOOD = "wood"
24
+ URANIUM = "uranium"
25
+ COAL = "coal"
@@ -0,0 +1,86 @@
1
+ from .constants import Constants
2
+ from .game_map import GameMap
3
+ from .game_objects import City, Player, Unit
4
+
5
+ INPUT_CONSTANTS = Constants.INPUT_CONSTANTS
6
+
7
+
8
+ class Game:
9
+ def _initialize(self, messages):
10
+ """
11
+ initialize state
12
+ """
13
+ self.id = int(messages[0])
14
+ self.turn = -1
15
+ # get some other necessary initial input
16
+ mapInfo = messages[1].split(" ")
17
+ self.map_width = int(mapInfo[0])
18
+ self.map_height = int(mapInfo[1])
19
+ self.map = GameMap(self.map_width, self.map_height)
20
+ self.players = [Player(0), Player(1)]
21
+
22
+ def _end_turn(self):
23
+ print("D_FINISH")
24
+
25
+ def _reset_player_states(self):
26
+ self.players[0].units = []
27
+ self.players[0].cities = {}
28
+ self.players[0].city_tile_count = 0
29
+ self.players[1].units = []
30
+ self.players[1].cities = {}
31
+ self.players[1].city_tile_count = 0
32
+
33
+ def _update(self, messages):
34
+ """
35
+ update state
36
+ """
37
+ self.map = GameMap(self.map_width, self.map_height)
38
+ self.turn += 1
39
+ self._reset_player_states()
40
+
41
+ for update in messages:
42
+ if update == "D_DONE":
43
+ break
44
+ strs = update.split(" ")
45
+ input_identifier = strs[0]
46
+ if input_identifier == INPUT_CONSTANTS.RESEARCH_POINTS:
47
+ team = int(strs[1])
48
+ self.players[team].research_points = int(strs[2])
49
+ elif input_identifier == INPUT_CONSTANTS.RESOURCES:
50
+ r_type = strs[1]
51
+ x = int(strs[2])
52
+ y = int(strs[3])
53
+ amt = int(float(strs[4]))
54
+ self.map._setResource(r_type, x, y, amt)
55
+ elif input_identifier == INPUT_CONSTANTS.UNITS:
56
+ unittype = int(strs[1])
57
+ team = int(strs[2])
58
+ unitid = strs[3]
59
+ x = int(strs[4])
60
+ y = int(strs[5])
61
+ cooldown = float(strs[6])
62
+ wood = int(strs[7])
63
+ coal = int(strs[8])
64
+ uranium = int(strs[9])
65
+ self.players[team].units.append(Unit(team, unittype, unitid, x, y, cooldown, wood, coal, uranium))
66
+ elif input_identifier == INPUT_CONSTANTS.CITY:
67
+ team = int(strs[1])
68
+ cityid = strs[2]
69
+ fuel = float(strs[3])
70
+ lightupkeep = float(strs[4])
71
+ self.players[team].cities[cityid] = City(team, cityid, fuel, lightupkeep)
72
+ elif input_identifier == INPUT_CONSTANTS.CITY_TILES:
73
+ team = int(strs[1])
74
+ cityid = strs[2]
75
+ x = int(strs[3])
76
+ y = int(strs[4])
77
+ cooldown = float(strs[5])
78
+ city = self.players[team].cities[cityid]
79
+ citytile = city._add_city_tile(x, y, cooldown)
80
+ self.map.get_cell(x, y).citytile = citytile
81
+ self.players[team].city_tile_count += 1
82
+ elif input_identifier == INPUT_CONSTANTS.ROADS:
83
+ x = int(strs[1])
84
+ y = int(strs[2])
85
+ road = float(strs[3])
86
+ self.map.get_cell(x, y).road = road
@@ -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,7 @@
1
+ import json
2
+ from os import path
3
+
4
+ dir_path = path.dirname(__file__)
5
+ constants_path = path.abspath(path.join(dir_path, "game_constants.json"))
6
+ with open(constants_path) as f:
7
+ GAME_CONSTANTS = json.load(f)
@@ -0,0 +1,106 @@
1
+ from typing import List
2
+
3
+ from .constants import Constants
4
+
5
+ DIRECTIONS = Constants.DIRECTIONS
6
+ RESOURCE_TYPES = Constants.RESOURCE_TYPES
7
+
8
+
9
+ class Resource:
10
+ def __init__(self, r_type: str, amount: int):
11
+ self.type = r_type
12
+ self.amount = amount
13
+
14
+
15
+ class Cell:
16
+ def __init__(self, x, y):
17
+ self.pos = Position(x, y)
18
+ self.resource: Resource = None
19
+ self.citytile = None
20
+ self.road = 0
21
+
22
+ def has_resource(self):
23
+ return self.resource is not None and self.resource.amount > 0
24
+
25
+
26
+ class GameMap:
27
+ def __init__(self, width, height):
28
+ self.height = height
29
+ self.width = width
30
+ self.map: List[List[Cell]] = [None] * height
31
+ for y in range(0, self.height):
32
+ self.map[y] = [None] * width
33
+ for x in range(0, self.width):
34
+ self.map[y][x] = Cell(x, y)
35
+
36
+ def get_cell_by_pos(self, pos) -> Cell:
37
+ return self.map[pos.y][pos.x]
38
+
39
+ def get_cell(self, x, y) -> Cell:
40
+ return self.map[y][x]
41
+
42
+ def _setResource(self, r_type, x, y, amount):
43
+ """
44
+ do not use this function, this is for internal tracking of state
45
+ """
46
+ cell = self.get_cell(x, y)
47
+ cell.resource = Resource(r_type, amount)
48
+
49
+
50
+ class Position:
51
+ def __init__(self, x, y):
52
+ self.x = x
53
+ self.y = y
54
+
55
+ def __sub__(self, pos) -> int:
56
+ return abs(pos.x - self.x) + abs(pos.y - self.y)
57
+
58
+ def distance_to(self, pos):
59
+ """
60
+ Returns Manhattan (L1/grid) distance to pos
61
+ """
62
+ return self - pos
63
+
64
+ def is_adjacent(self, pos):
65
+ return (self - pos) <= 1
66
+
67
+ def __eq__(self, pos) -> bool:
68
+ return self.x == pos.x and self.y == pos.y
69
+
70
+ def equals(self, pos):
71
+ return self == pos
72
+
73
+ def translate(self, direction, units) -> "Position":
74
+ if direction == DIRECTIONS.NORTH:
75
+ return Position(self.x, self.y - units)
76
+ elif direction == DIRECTIONS.EAST:
77
+ return Position(self.x + units, self.y)
78
+ elif direction == DIRECTIONS.SOUTH:
79
+ return Position(self.x, self.y + units)
80
+ elif direction == DIRECTIONS.WEST:
81
+ return Position(self.x - units, self.y)
82
+ elif direction == DIRECTIONS.CENTER:
83
+ return Position(self.x, self.y)
84
+
85
+ def direction_to(self, target_pos: "Position") -> DIRECTIONS:
86
+ """
87
+ Return closest position to target_pos from this position
88
+ """
89
+ check_dirs = [
90
+ DIRECTIONS.NORTH,
91
+ DIRECTIONS.EAST,
92
+ DIRECTIONS.SOUTH,
93
+ DIRECTIONS.WEST,
94
+ ]
95
+ closest_dist = self.distance_to(target_pos)
96
+ closest_dir = DIRECTIONS.CENTER
97
+ for direction in check_dirs:
98
+ newpos = self.translate(direction, 1)
99
+ dist = target_pos.distance_to(newpos)
100
+ if dist < closest_dist:
101
+ closest_dir = direction
102
+ closest_dist = dist
103
+ return closest_dir
104
+
105
+ def __str__(self) -> str:
106
+ return f"({self.x}, {self.y})"