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,402 @@
1
+ import { Board } from './kore/Board';
2
+ import { tick as DoNothingTick } from './DoNothingBot';
3
+ import { tick as MinerTick } from './MinerBot';
4
+ import { tick as BotTick } from './Bot';
5
+
6
+ const { spawn } = require('child_process');
7
+ const fs = require('fs');
8
+
9
+ interface StepPlayerInfoRaw {
10
+ action: Record<string, string>;
11
+ observation?: object;
12
+ reward: number;
13
+ status: string;
14
+ }
15
+
16
+ interface Agent {
17
+ name: string;
18
+ status: 'ACTIVE' | 'DONE';
19
+ reward: number;
20
+ tickFunc: (board:Board) => void;
21
+ }
22
+
23
+ const tickFuncMapping = {
24
+ 'miner': MinerTick,
25
+ 'do_nothing': DoNothingTick,
26
+ 'bot': BotTick,
27
+ }
28
+
29
+ const MODE_STEP = 'step' as const;
30
+ const MODE_RUN = 'run' as const;
31
+ type MODE = typeof MODE_STEP | typeof MODE_RUN;
32
+
33
+ const example = 'node --require ts-node/register interpreter.ts step 2 ./main.py miner [out.log] [replay.json]';
34
+
35
+ const DEFAULT_LOG_FILE_NAME = 'out.log';
36
+ const DEFAULT_RESULT_FILE_NAME = 'replay.json';
37
+
38
+ const MAX_CONCURRENT = 5;
39
+
40
+ // agent under test
41
+ const MAIN_AGENT_INDEX = 0;
42
+ // opponent agent
43
+ const OPPONENT_AGENT_INDEX = 1;
44
+ const myArgs = process.argv.slice(2);
45
+
46
+ // TODO: better handling of arguments, named args.
47
+ if (myArgs.length < 3) {
48
+ console.log('Please follow the format in the example below:');
49
+ console.log(example);
50
+ process.exit(1);
51
+ }
52
+
53
+ const mode = myArgs[0];
54
+ if(mode !== MODE_STEP && mode !== MODE_RUN) {
55
+ console.log('Mode must be either step or run. Example:');
56
+ console.log(example);
57
+ process.exit(1);
58
+ }
59
+
60
+ const episodes = parseInt(myArgs[1], 10);
61
+ if (!episodes) {
62
+ console.log('Please provide number of episodes to run. Example:');
63
+ console.log(example);
64
+ process.exit(1);
65
+ }
66
+
67
+ const agentNames = myArgs.slice(2, 4);
68
+ // TODO: support other number of agents
69
+ if (agentNames.length !== 2) {
70
+ console.log('Please provide exactly 2 agents. Example:');
71
+ console.log(example);
72
+ process.exit(1);
73
+ }
74
+
75
+ // validate agent names for step mode
76
+ if(mode === MODE_STEP) {
77
+ for (let i = 0; i < agentNames.length; i++) {
78
+ const agentName = agentNames[i];
79
+ if(!tickFuncMapping[agentName]) {
80
+ console.log(`Agent ${agentName} tick function mapping does not exit. Define the mapping in interpreter.js -> tickFuncMapping.`);
81
+ console.log(example);
82
+ process.exit(1);
83
+ }
84
+ }
85
+ }
86
+
87
+ const userLogfilename = myArgs[4] || DEFAULT_LOG_FILE_NAME;
88
+
89
+ const userResultfilename = myArgs[5] || DEFAULT_RESULT_FILE_NAME;
90
+
91
+ console.log(`Running ${episodes} episodes with agents: ${agentNames.join(' ')}`);
92
+
93
+ if(mode === MODE_RUN) {
94
+ runAgent(episodes, agentNames, () => {
95
+ // post processing
96
+ console.log('run done');
97
+ });
98
+ } else {
99
+ stepAgent(episodes, agentNames, () => {
100
+ // post processing
101
+ console.log('step done');
102
+ });
103
+ }
104
+
105
+ function initEnv(agents: Agent[]): Promise<Board> {
106
+ // get init observation by playing a game between attacker agent and do_nothing agent
107
+ const resultFilename = `${userResultfilename}_init`;
108
+
109
+ const pyArguments = [
110
+ 'run',
111
+ '--environment',
112
+ 'kore_fleets',
113
+ '--agents',
114
+ 'attacker',
115
+ 'do_nothing',
116
+ '--out',
117
+ resultFilename,
118
+ ];
119
+
120
+ return new Promise<Board>((resolve, reject) => {
121
+ const kaggle = spawn('kaggle-environments', pyArguments, { cwd: __dirname });
122
+
123
+ kaggle.stderr.on('data', (data) => {
124
+ console.error(`stderr: ${data}`);
125
+ reject(data);
126
+ });
127
+
128
+ kaggle.on('close', (code) => {
129
+ console.log(`init complete`);
130
+ const result = processResult(resultFilename);
131
+ const { configuration, steps } = result;
132
+ const observation = steps[0][0].observation;
133
+ const board = Board.fromRaw(JSON.stringify(observation), JSON.stringify(configuration));
134
+ resolve(board);
135
+ });
136
+ });
137
+ }
138
+
139
+ // mimic the interpreter function in kore_fleets.py
140
+ function boardTick(board:Board, agents: Agent[]) {
141
+ const players = board.players;
142
+
143
+ // Remove players with invalid status or insufficient potential.
144
+ for (let i = 0; i < players.length; i++) {
145
+ const agent = agents[i];
146
+ const player = players[i];
147
+ const playerKore = player.kore;
148
+ const shipyards = player.shipyards;
149
+ const fleets = player.fleets;
150
+ const canSpawn = shipyards.length > 0 && playerKore >= board.configuration.spawnCost;
151
+
152
+ if(agent.status === 'ACTIVE' && shipyards.length === 0 && fleets.length === 0) {
153
+ agent.status = 'DONE';
154
+ agent.reward = board.step - board.configuration.episodeSteps - 1;
155
+ }
156
+ if(agent.status === 'ACTIVE' && playerKore === 0 && fleets.length === 0 && !canSpawn) {
157
+ agent.status = 'DONE';
158
+ agent.reward = board.step - board.configuration.episodeSteps - 1;
159
+ }
160
+ if(agent.status !== 'ACTIVE' && agent.status !== 'DONE') {
161
+ // TODO: handle this
162
+ }
163
+ }
164
+
165
+ // Check if done (< 2 players and num_agents > 1)
166
+ const activeAgents = agents.filter(agent => agent.status === 'ACTIVE').length;
167
+ if(agents.length > 1 && activeAgents < 2) {
168
+ for (let i = 0; i < agents.length; i++) {
169
+ const agent = agents[i];
170
+ if(agent.status === 'ACTIVE') {
171
+ agent.status = 'DONE';
172
+ }
173
+ }
174
+ }
175
+
176
+ // Update Rewards
177
+ for (let i = 0; i < agents.length; i++) {
178
+ const agent = agents[i];
179
+ if(agent.status === 'ACTIVE') {
180
+ agent.reward = players[i].kore;
181
+ } else if(agent.status !== 'DONE') {
182
+ agent.reward = 0;
183
+ }
184
+ }
185
+
186
+ let end = true;
187
+ if(board.step >= board.configuration.episodeSteps - 1) {
188
+ return true;
189
+ }
190
+ for (let i = 0; i < agents.length; i++) {
191
+ const agent = agents[i];
192
+ if(agent.status === 'ACTIVE') {
193
+ end = false;
194
+ }
195
+ }
196
+ return end;
197
+ }
198
+
199
+ async function stepAgent(episodes: number, agentsNames: string[], callback: Function = () => {}) {
200
+ let completed = 0;
201
+ let wins = 0;
202
+
203
+ for (let index = 0; index < episodes; index++) {
204
+ let agentNamesMutable = agentsNames.slice();
205
+ let episodeMainAgentIndex = MAIN_AGENT_INDEX;
206
+ let episodeOpponentAgentIndex = OPPONENT_AGENT_INDEX;
207
+ // randomize starting position
208
+ if (Math.random() < 0.5) {
209
+ const temp = agentNamesMutable[0];
210
+ agentNamesMutable[0] = agentNamesMutable[1];
211
+ agentNamesMutable[1] = temp;
212
+ episodeMainAgentIndex = OPPONENT_AGENT_INDEX;
213
+ episodeOpponentAgentIndex = MAIN_AGENT_INDEX;
214
+ }
215
+
216
+ const agents: Agent[] = agentNamesMutable.map((name) => {
217
+ return {
218
+ name: name,
219
+ status: 'ACTIVE',
220
+ reward: 0,
221
+ tickFunc: tickFuncMapping[name],
222
+ };
223
+ });
224
+
225
+ let gameBoard = await initEnv(agents);
226
+ while(!boardTick(gameBoard, agents)) {
227
+ // console.log(gameBoard.step);
228
+ for (let i = 0; i < agents.length; i++) {
229
+ const agent = agents[i];
230
+ // rotate the board to the agent's perspective
231
+ // and assign agent action to game board
232
+ gameBoard.currentPlayerId = i;
233
+ agent.tickFunc(gameBoard);
234
+
235
+ gameBoard.currentPlayer.shipyards.forEach(shipyard => {
236
+ // console.log(gameBoard.currentPlayerId, shipyard.position.toString(), shipyard.nextAction);
237
+ })
238
+ }
239
+ gameBoard.currentPlayerId = episodeMainAgentIndex;
240
+ if (gameBoard.step % 100 === 0) {
241
+ console.log(
242
+ `[epi ${index}][step ${pad2(gameBoard.step)}] current player kore:${gameBoard.currentPlayer.kore} action 0: ${
243
+ gameBoard.currentPlayer.shipyards.length ? gameBoard.currentPlayer.shipyards[0].nextAction : 'none'
244
+ } reward: ${agents[episodeMainAgentIndex].reward.toFixed(0)} status: ${agents[episodeMainAgentIndex].status}`
245
+ );
246
+ }
247
+ gameBoard = gameBoard.next();
248
+ }
249
+ console.log(
250
+ `[epi ${index}][step ${pad2(gameBoard.step)}] current player kore:${gameBoard.currentPlayer.kore} action 0: ${
251
+ gameBoard.currentPlayer.shipyards.length ? gameBoard.currentPlayer.shipyards[0].nextAction : 'none'
252
+ } reward: ${agents[episodeMainAgentIndex].reward.toFixed(0)} status: ${agents[episodeMainAgentIndex].status}`
253
+ );
254
+ console.log(agents[episodeMainAgentIndex].name, agents[episodeMainAgentIndex].reward);
255
+ console.log(agents[episodeOpponentAgentIndex].name, agents[episodeOpponentAgentIndex].reward);
256
+ if(agents[episodeMainAgentIndex].reward > agents[episodeOpponentAgentIndex].reward) {
257
+ wins++;
258
+ }
259
+
260
+ completed++;
261
+ console.log(`${completed}/${episodes}`);
262
+ if (completed === episodes) {
263
+ const mainAgentName = agentsNames[MAIN_AGENT_INDEX];
264
+ console.log(`agent ${mainAgentName} wins: ${pad(wins)}/${pad(episodes)}`);
265
+ callback();
266
+ }
267
+ }
268
+ }
269
+
270
+ async function runAgent(episodes: number, agents: string[], callback: Function = () => {}) {
271
+ let running = 0;
272
+ let completed = 0;
273
+ const results = new Array(episodes);
274
+
275
+ const agent = agents[MAIN_AGENT_INDEX];
276
+ const cleanAgentName = agent.replace(/\.py$/g, '').replace(/\W/g, '');
277
+
278
+ for (let index = 0; index < episodes; index++) {
279
+ const resultFilename = `${userResultfilename}_${index}`;
280
+ const logFilename = `${userLogfilename}_${index}`;
281
+ const pyArguments = [
282
+ 'run',
283
+ '--environment',
284
+ 'kore_fleets',
285
+ '--agents',
286
+ ...agents,
287
+ '--log',
288
+ logFilename,
289
+ '--out',
290
+ resultFilename,
291
+ ];
292
+
293
+ while (running >= MAX_CONCURRENT) {
294
+ await sleep(1000);
295
+ }
296
+
297
+ const kaggle = spawn('kaggle-environments', pyArguments, { cwd: __dirname });
298
+ running++;
299
+
300
+ kaggle.stdout.on('data', (data) => {
301
+ console.log(`stdout: ${data}`);
302
+ });
303
+
304
+ kaggle.stderr.on('data', (data) => {
305
+ console.error(`stderr: ${data}`);
306
+ });
307
+
308
+ kaggle.on('close', (code) => {
309
+ completed++;
310
+ console.log(`${completed}/${episodes}`);
311
+ running--;
312
+ const result = processResult(resultFilename);
313
+ processSteps(index, result.configuration, result.steps);
314
+ // ensure consistent result order
315
+ results[index] = result;
316
+ if (completed === episodes) {
317
+ compileRunResults(cleanAgentName, results);
318
+ callback();
319
+ }
320
+ });
321
+ }
322
+ }
323
+
324
+ function sleep(ms) {
325
+ return new Promise((resolve) => setTimeout(resolve, ms));
326
+ }
327
+
328
+ function compileRunResults(agent: string, results: any[]) {
329
+ try {
330
+ let games = 0;
331
+ let wins = 0;
332
+ for (let i = 0; i < results.length; i++) {
333
+ games++;
334
+ const steps = results[i].steps;
335
+ const lastStep = steps[steps.length - 1];
336
+ if (lastStep.length !== 2) {
337
+ throw new Error(`${agent} ${i} has invalid result`);
338
+ }
339
+ const rewards = lastStep.map((r) => r.reward);
340
+ console.log(`game ${pad(i)} rewards: ${rewards.map((r) => r.toFixed(0)).join(', ')}`);
341
+ const [p0, p1] = rewards;
342
+ if (p0 > p1) {
343
+ wins++;
344
+ }
345
+ }
346
+ console.log(`agent ${agent} wins: ${pad(wins)}/${pad(games)}`);
347
+ } catch (e) {
348
+ console.error(e);
349
+ }
350
+ }
351
+
352
+ // an example of getting the obervation, action, reward and status
353
+ function processSteps(episode: number, configuration: object, steps: StepPlayerInfoRaw[][]) {
354
+ for (let i = 0; i < steps.length; i++) {
355
+ const step = steps[i];
356
+ // only the first agent has complete Observation, based analysis of replay.json
357
+ const stepPlayerInfoRaw = step[MAIN_AGENT_INDEX];
358
+ const obervation = stepPlayerInfoRaw.observation;
359
+ // TODO: optimize this conversion thing
360
+ const board = Board.fromRaw(JSON.stringify(obervation), JSON.stringify(configuration));
361
+
362
+ const { action, reward, status } = stepPlayerInfoRaw;
363
+
364
+ let lastTurn = false;
365
+ if (status === 'DONE') {
366
+ lastTurn = true;
367
+ }
368
+
369
+ if (i % 100 === 0 || lastTurn) {
370
+ console.log(
371
+ `[epi ${episode}][step ${pad2(i)}] current player kore:${board.currentPlayer.kore} action 0: ${
372
+ action[Object.keys(action)[0]]
373
+ } reward: ${reward.toFixed(0)} status: ${status}`
374
+ );
375
+ }
376
+ }
377
+ }
378
+
379
+ function processResult(filename: string) {
380
+ try {
381
+ const results = JSON.parse(fs.readFileSync(filename, 'utf8'));
382
+ return results;
383
+ } catch (e) {
384
+ console.error(e);
385
+ }
386
+ }
387
+
388
+ function pad(number) {
389
+ if (number < 10) {
390
+ return '0' + number;
391
+ }
392
+ return number;
393
+ }
394
+
395
+ function pad2(number) {
396
+ if (number < 10) {
397
+ return '00' + number;
398
+ } else if (number < 100) {
399
+ return '0' + number;
400
+ }
401
+ return number;
402
+ }