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.
- kaggle_environments/__init__.py +49 -13
- kaggle_environments/agent.py +177 -124
- kaggle_environments/api.py +31 -0
- kaggle_environments/core.py +298 -173
- kaggle_environments/envs/cabt/cabt.js +164 -0
- kaggle_environments/envs/cabt/cabt.json +28 -0
- kaggle_environments/envs/cabt/cabt.py +186 -0
- kaggle_environments/envs/cabt/cg/__init__.py +0 -0
- kaggle_environments/envs/cabt/cg/cg.dll +0 -0
- kaggle_environments/envs/cabt/cg/game.py +75 -0
- kaggle_environments/envs/cabt/cg/libcg.so +0 -0
- kaggle_environments/envs/cabt/cg/sim.py +48 -0
- kaggle_environments/envs/cabt/test_cabt.py +120 -0
- kaggle_environments/envs/chess/chess.js +4289 -0
- kaggle_environments/envs/chess/chess.json +60 -0
- kaggle_environments/envs/chess/chess.py +4241 -0
- kaggle_environments/envs/chess/test_chess.py +60 -0
- kaggle_environments/envs/connectx/connectx.ipynb +3186 -0
- kaggle_environments/envs/connectx/connectx.js +1 -1
- kaggle_environments/envs/connectx/connectx.json +15 -1
- kaggle_environments/envs/connectx/connectx.py +6 -23
- kaggle_environments/envs/connectx/test_connectx.py +70 -24
- kaggle_environments/envs/football/football.ipynb +75 -0
- kaggle_environments/envs/football/football.json +91 -0
- kaggle_environments/envs/football/football.py +277 -0
- kaggle_environments/envs/football/helpers.py +95 -0
- kaggle_environments/envs/football/test_football.py +360 -0
- kaggle_environments/envs/halite/__init__.py +0 -0
- kaggle_environments/envs/halite/halite.ipynb +44741 -0
- kaggle_environments/envs/halite/halite.js +199 -83
- kaggle_environments/envs/halite/halite.json +31 -18
- kaggle_environments/envs/halite/halite.py +164 -303
- kaggle_environments/envs/halite/helpers.py +720 -0
- kaggle_environments/envs/halite/test_halite.py +190 -0
- kaggle_environments/envs/hungry_geese/__init__.py +0 -0
- kaggle_environments/envs/{battlegeese/battlegeese.js → hungry_geese/hungry_geese.js} +38 -22
- kaggle_environments/envs/{battlegeese/battlegeese.json → hungry_geese/hungry_geese.json} +22 -15
- kaggle_environments/envs/hungry_geese/hungry_geese.py +316 -0
- kaggle_environments/envs/hungry_geese/test_hungry_geese.py +0 -0
- kaggle_environments/envs/identity/identity.json +6 -5
- kaggle_environments/envs/identity/identity.py +15 -2
- kaggle_environments/envs/kore_fleets/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/helpers.py +1005 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +114 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.js +658 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.json +164 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.py +555 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/Bot.java +54 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/README.md +26 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/hamcrest-core-1.3.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/junit-4.13.2.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Board.java +518 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Cell.java +61 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Configuration.java +24 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Direction.java +166 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Fleet.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/KoreJson.java +97 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Observation.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Pair.java +13 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Player.java +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Point.java +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Shipyard.java +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/ShipyardAction.java +59 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/BoardTest.java +567 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ConfigurationTest.java +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/KoreJsonTest.java +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ObservationTest.java +46 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/PointTest.java +21 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ShipyardTest.java +22 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/main.py +27 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/Bot.ts +34 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/DoNothingBot.ts +12 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/MinerBot.ts +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/README.md +55 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/interpreter.ts +402 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Board.ts +514 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Cell.ts +63 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Configuration.ts +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Direction.ts +169 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Fleet.ts +76 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/KoreIO.ts +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Observation.ts +45 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Pair.ts +11 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Player.ts +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Point.ts +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Shipyard.ts +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/ShipyardAction.ts +58 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/miner.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/package.json +23 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/BoardTest.ts +551 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ConfigurationTest.ts +16 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ObservationTest.ts +33 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/PointTest.ts +17 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ShipyardTest.ts +18 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/tsconfig.json +22 -0
- kaggle_environments/envs/kore_fleets/test_kore_fleets.py +331 -0
- kaggle_environments/envs/lux_ai_2021/README.md +3 -0
- kaggle_environments/envs/lux_ai_2021/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/agents.py +11 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js +2 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/main.js +1 -0
- kaggle_environments/envs/lux_ai_2021/index.html +43 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.json +100 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.py +231 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.js +6 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_objects.js +145 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/io.js +14 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/kit.js +209 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/map.js +107 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/parser.js +79 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.js +88 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.py +75 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/annotate.py +20 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/constants.py +25 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game.py +86 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.py +7 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_map.py +106 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_objects.py +154 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/random_agent.py +38 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/simple_agent.py +82 -0
- kaggle_environments/envs/lux_ai_2021/test_lux.py +19 -0
- kaggle_environments/envs/lux_ai_2021/testing.md +23 -0
- kaggle_environments/envs/lux_ai_2021/todo.md.og +18 -0
- kaggle_environments/envs/lux_ai_s3/README.md +21 -0
- kaggle_environments/envs/lux_ai_s3/agents.py +5 -0
- kaggle_environments/envs/lux_ai_s3/index.html +42 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.json +47 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.py +178 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +819 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +9 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +141 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +222 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +27 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +464 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +156 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +78 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/kit.py +31 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/utils.py +17 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/main.py +66 -0
- kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
- kaggle_environments/envs/mab/__init__.py +0 -0
- kaggle_environments/envs/mab/agents.py +12 -0
- kaggle_environments/envs/mab/mab.js +100 -0
- kaggle_environments/envs/mab/mab.json +74 -0
- kaggle_environments/envs/mab/mab.py +146 -0
- kaggle_environments/envs/open_spiel/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/chess/chess.js +441 -0
- kaggle_environments/envs/open_spiel/games/chess/image_config.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/chess/openings.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/connect_four/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js +284 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py +86 -0
- kaggle_environments/envs/open_spiel/games/go/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/go/go.js +481 -0
- kaggle_environments/envs/open_spiel/games/go/go_proxy.py +99 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe.js +345 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe_proxy.py +98 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker.js +431 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker_proxy.py +159 -0
- kaggle_environments/envs/open_spiel/html_playthrough_generator.py +31 -0
- kaggle_environments/envs/open_spiel/observation.py +128 -0
- kaggle_environments/envs/open_spiel/open_spiel.py +565 -0
- kaggle_environments/envs/open_spiel/proxy.py +138 -0
- kaggle_environments/envs/open_spiel/test_open_spiel.py +191 -0
- kaggle_environments/envs/rps/__init__.py +0 -0
- kaggle_environments/envs/rps/agents.py +84 -0
- kaggle_environments/envs/rps/helpers.py +25 -0
- kaggle_environments/envs/rps/rps.js +117 -0
- kaggle_environments/envs/rps/rps.json +63 -0
- kaggle_environments/envs/rps/rps.py +90 -0
- kaggle_environments/envs/rps/test_rps.py +110 -0
- kaggle_environments/envs/rps/utils.py +7 -0
- kaggle_environments/envs/tictactoe/test_tictactoe.py +43 -77
- kaggle_environments/envs/tictactoe/tictactoe.ipynb +1397 -0
- kaggle_environments/envs/tictactoe/tictactoe.json +10 -2
- kaggle_environments/envs/tictactoe/tictactoe.py +1 -1
- kaggle_environments/errors.py +2 -4
- kaggle_environments/helpers.py +377 -0
- kaggle_environments/main.py +214 -50
- kaggle_environments/schemas.json +23 -18
- kaggle_environments/static/player.html +206 -74
- kaggle_environments/utils.py +46 -73
- kaggle_environments-1.20.0.dist-info/METADATA +25 -0
- kaggle_environments-1.20.0.dist-info/RECORD +211 -0
- {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info}/WHEEL +1 -2
- kaggle_environments-1.20.0.dist-info/entry_points.txt +3 -0
- kaggle_environments/envs/battlegeese/battlegeese.py +0 -219
- kaggle_environments/temp.py +0 -14
- kaggle_environments-0.2.0.dist-info/METADATA +0 -393
- kaggle_environments-0.2.0.dist-info/RECORD +0 -33
- kaggle_environments-0.2.0.dist-info/entry_points.txt +0 -3
- kaggle_environments-0.2.0.dist-info/top_level.txt +0 -1
- {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
|
+
}
|