kaggle-environments 0.2.1__py3-none-any.whl → 1.20.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kaggle-environments might be problematic. Click here for more details.
- kaggle_environments/__init__.py +49 -13
- kaggle_environments/agent.py +177 -124
- kaggle_environments/api.py +31 -0
- kaggle_environments/core.py +295 -170
- 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} +21 -14
- 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 +340 -0
- kaggle_environments/schemas.json +23 -18
- kaggle_environments/static/player.html +206 -74
- kaggle_environments/utils.py +46 -73
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/METADATA +36 -114
- kaggle_environments-1.20.1.dist-info/RECORD +211 -0
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/WHEEL +1 -2
- kaggle_environments-1.20.1.dist-info/entry_points.txt +3 -0
- kaggle_environments/envs/battlegeese/battlegeese.py +0 -223
- kaggle_environments/temp.py +0 -14
- kaggle_environments-0.2.1.dist-info/RECORD +0 -32
- kaggle_environments-0.2.1.dist-info/entry_points.txt +0 -3
- kaggle_environments-0.2.1.dist-info/top_level.txt +0 -1
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import json
|
|
3
|
+
import shutil
|
|
4
|
+
import uuid
|
|
5
|
+
from os import path
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from gfootball.env import football_action_set
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def renderer(state, env):
|
|
13
|
+
html_renderer(env)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def run_right_agent(obs):
|
|
17
|
+
# keep running right.
|
|
18
|
+
return [5] * obs.controlled_players
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def run_left_agent(obs):
|
|
22
|
+
# keep running left.
|
|
23
|
+
return [1] * obs.controlled_players
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def do_nothing_agent(obs):
|
|
27
|
+
# do nothing.
|
|
28
|
+
return [0] * obs.controlled_players
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def builtin_ai_agent(obs):
|
|
32
|
+
# execute builtin AI behavior.
|
|
33
|
+
return [19] * obs.controlled_players
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
agents = {
|
|
37
|
+
"run_right": run_right_agent,
|
|
38
|
+
"run_left": run_left_agent,
|
|
39
|
+
"do_nothing": do_nothing_agent,
|
|
40
|
+
"builtin_ai": builtin_ai_agent,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def parse_single_player(obs_raw_entry):
|
|
45
|
+
# Remove pixel information.
|
|
46
|
+
if "frame" in obs_raw_entry:
|
|
47
|
+
del obs_raw_entry["frame"]
|
|
48
|
+
for k, v in obs_raw_entry.items():
|
|
49
|
+
if type(v) == np.ndarray:
|
|
50
|
+
obs_raw_entry[k] = v.tolist()
|
|
51
|
+
return obs_raw_entry
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def try_get_video(env, keep_running=False):
|
|
55
|
+
if not env.football_video_path:
|
|
56
|
+
internal_env = m_envs[env.configuration.id]
|
|
57
|
+
while not hasattr(internal_env, "_env"):
|
|
58
|
+
internal_env = internal_env.env
|
|
59
|
+
if not keep_running and internal_env._env._step == -1:
|
|
60
|
+
# Generate no-op step, so that video is available.
|
|
61
|
+
internal_env.step([0] * (env.configuration.team_1 + env.configuration.team_2))
|
|
62
|
+
trace = internal_env._env._trace
|
|
63
|
+
if trace:
|
|
64
|
+
trace._dump_config["episode_done"]._min_frequency = 0
|
|
65
|
+
dumps = trace.process_pending_dumps(True)
|
|
66
|
+
env.football_video_path = retrieve_video_link(dumps)
|
|
67
|
+
if not env.football_video_path:
|
|
68
|
+
return
|
|
69
|
+
if keep_running:
|
|
70
|
+
trace.write_dump("episode_done")
|
|
71
|
+
if "LiveVideoPath" in env.info and env.info["LiveVideoPath"] is not None:
|
|
72
|
+
target_path = Path(env.info["LiveVideoPath"])
|
|
73
|
+
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
74
|
+
shutil.move(env.football_video_path, target_path)
|
|
75
|
+
env.football_video_path = env.info["LiveVideoPath"]
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def update_observations_and_rewards(configuration, state, obs, rew=None):
|
|
79
|
+
"""Updates agent-visible observations given 'raw' observations from environment.
|
|
80
|
+
Observations in 'obs' are coming directly from the environment and are in 'raw' format.
|
|
81
|
+
"""
|
|
82
|
+
state[0].observation.controlled_players = configuration.team_1
|
|
83
|
+
state[1].observation.controlled_players = configuration.team_2
|
|
84
|
+
|
|
85
|
+
assert len(obs) == configuration.team_1 + configuration.team_2
|
|
86
|
+
if rew is not None:
|
|
87
|
+
state[0].reward = rew
|
|
88
|
+
state[1].reward = -rew
|
|
89
|
+
state[0].observation.players_raw = [parse_single_player(obs[x]) for x in range(configuration.team_1)]
|
|
90
|
+
state[1].observation.players_raw = [
|
|
91
|
+
parse_single_player(obs[x + configuration.team_1]) for x in range(configuration.team_2)
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def mark_invalid(agent, message):
|
|
96
|
+
agent.status = "INVALID"
|
|
97
|
+
agent.reward = -100
|
|
98
|
+
agent.info.debug_info = message
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def maybe_terminate(env, state):
|
|
102
|
+
if state[0].status != "ACTIVE" or state[1].status != "ACTIVE":
|
|
103
|
+
if state[0].status == "ACTIVE":
|
|
104
|
+
state[0].status = "DONE"
|
|
105
|
+
state[0].reward = 100
|
|
106
|
+
state[0].info.debug_info = "Opponent forfeited. You win."
|
|
107
|
+
elif not state[0].reward:
|
|
108
|
+
state[0].reward = -100
|
|
109
|
+
if state[1].status == "ACTIVE":
|
|
110
|
+
state[1].status = "DONE"
|
|
111
|
+
state[1].reward = 100
|
|
112
|
+
state[1].info.debug_info = "Opponent forfeited. You win."
|
|
113
|
+
elif not state[1].reward:
|
|
114
|
+
state[1].reward = -100
|
|
115
|
+
try_get_video(env)
|
|
116
|
+
return True
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def football_env():
|
|
121
|
+
# Use lazy-import to avoid this heavy dependency unless it is really needed.
|
|
122
|
+
return importlib.import_module("gfootball.env")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# Global dictionary with active environments.
|
|
126
|
+
m_envs = {}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def cleanup(env):
|
|
130
|
+
global m_envs
|
|
131
|
+
del m_envs[env.configuration.id]
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def cleanup_all():
|
|
135
|
+
global m_envs
|
|
136
|
+
del m_envs
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def retrieve_video_link(dumps):
|
|
140
|
+
for entry in dumps:
|
|
141
|
+
if entry["name"] == "episode_done":
|
|
142
|
+
print("Received video link.")
|
|
143
|
+
return entry["video"]
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def interpreter(state, env):
|
|
148
|
+
global m_envs
|
|
149
|
+
if "id" not in env.configuration or env.configuration.id is None:
|
|
150
|
+
env.configuration.id = str(uuid.uuid4())
|
|
151
|
+
|
|
152
|
+
if (env.configuration.id not in m_envs) or env.done:
|
|
153
|
+
if env.configuration.id not in m_envs:
|
|
154
|
+
print(
|
|
155
|
+
"Staring a new environment %s: with scenario: %s"
|
|
156
|
+
% (env.configuration.id, env.configuration.scenario_name)
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
other_config_options = {}
|
|
160
|
+
# Use webm to encode videos (so that you can see them in the browser).
|
|
161
|
+
other_config_options["video_format"] = "webm"
|
|
162
|
+
if env.configuration.running_in_notebook:
|
|
163
|
+
assert not env.configuration.render, "Render is not supported inside notebook environment."
|
|
164
|
+
|
|
165
|
+
env.football_video_path = None
|
|
166
|
+
if "TeamNames" in env.info:
|
|
167
|
+
names = env.info["TeamNames"]
|
|
168
|
+
assert len(names) == 2
|
|
169
|
+
other_config_options["custom_display_stats"] = [
|
|
170
|
+
"LEFT PLAYER: %s" % names[0],
|
|
171
|
+
"RIGHT PLAYER: %s" % names[1],
|
|
172
|
+
]
|
|
173
|
+
m_envs[env.configuration.id] = football_env().create_environment(
|
|
174
|
+
env_name=env.configuration.scenario_name,
|
|
175
|
+
stacked=False,
|
|
176
|
+
# We use 'raw' representation to transfer data between server and agents.
|
|
177
|
+
representation="raw",
|
|
178
|
+
logdir=path.join(env.configuration.logdir, env.configuration.id),
|
|
179
|
+
write_goal_dumps=False,
|
|
180
|
+
write_full_episode_dumps=env.configuration.save_video,
|
|
181
|
+
write_video=env.configuration.save_video,
|
|
182
|
+
render=env.configuration.render,
|
|
183
|
+
number_of_left_players_agent_controls=env.configuration.team_1,
|
|
184
|
+
number_of_right_players_agent_controls=env.configuration.team_2,
|
|
185
|
+
other_config_options=other_config_options,
|
|
186
|
+
)
|
|
187
|
+
else:
|
|
188
|
+
print(
|
|
189
|
+
"Resetting environment %s: with scenario: %s" % (env.configuration.id, env.configuration.scenario_name)
|
|
190
|
+
)
|
|
191
|
+
obs = m_envs[env.configuration.id].reset()
|
|
192
|
+
update_observations_and_rewards(configuration=env.configuration, state=state, obs=obs)
|
|
193
|
+
if env.done:
|
|
194
|
+
return state
|
|
195
|
+
|
|
196
|
+
if maybe_terminate(env, state):
|
|
197
|
+
return state
|
|
198
|
+
|
|
199
|
+
# verify actions.
|
|
200
|
+
controlled_players = env.configuration.team_1
|
|
201
|
+
action_set = football_action_set.action_set_dict["default"]
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
for action in state[0].action:
|
|
205
|
+
football_action_set.named_action_from_action_set(action_set, action)
|
|
206
|
+
except Exception:
|
|
207
|
+
mark_invalid(state[0], "Invalid action provided: %s." % state[0].action)
|
|
208
|
+
if len(state[0].action) != env.configuration.team_1:
|
|
209
|
+
mark_invalid(
|
|
210
|
+
state[0],
|
|
211
|
+
"Invalid number of actions provided: Expected %d, got %d."
|
|
212
|
+
% (env.configuration.team_1, len(state[0].action)),
|
|
213
|
+
)
|
|
214
|
+
actions_to_env = state[0].action
|
|
215
|
+
|
|
216
|
+
try:
|
|
217
|
+
for action in state[1].action:
|
|
218
|
+
football_action_set.named_action_from_action_set(action_set, action)
|
|
219
|
+
except Exception:
|
|
220
|
+
mark_invalid(state[1], "Invalid action provided: %s." % state[1].action)
|
|
221
|
+
if len(state[1].action) != env.configuration.team_2:
|
|
222
|
+
mark_invalid(
|
|
223
|
+
state[1],
|
|
224
|
+
"Invalid number of actions provided: Expected %d, got %d."
|
|
225
|
+
% (env.configuration.team_2, len(state[1].action)),
|
|
226
|
+
)
|
|
227
|
+
if env.configuration.team_2:
|
|
228
|
+
actions_to_env = actions_to_env + state[1].action
|
|
229
|
+
|
|
230
|
+
if maybe_terminate(env, state):
|
|
231
|
+
return state
|
|
232
|
+
obs, rew, done, info = m_envs[env.configuration.id].step(actions_to_env)
|
|
233
|
+
|
|
234
|
+
if "dumps" in info:
|
|
235
|
+
env.football_video_path = retrieve_video_link(info["dumps"])
|
|
236
|
+
update_observations_and_rewards(
|
|
237
|
+
configuration=env.configuration, state=state, obs=obs, rew=obs[0]["score"][0] - obs[0]["score"][1]
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
## TODO: pass other information from 'info' to the state/agent.
|
|
241
|
+
if done:
|
|
242
|
+
for agent in range(2):
|
|
243
|
+
state[agent].status = "DONE"
|
|
244
|
+
try_get_video(env)
|
|
245
|
+
|
|
246
|
+
return state
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
dirpath = path.dirname(__file__)
|
|
250
|
+
jsonpath = path.abspath(path.join(dirpath, "football.json"))
|
|
251
|
+
with open(jsonpath) as f:
|
|
252
|
+
specification = json.load(f)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def html_renderer(env):
|
|
256
|
+
try_get_video(env, keep_running=True)
|
|
257
|
+
if not env.football_video_path:
|
|
258
|
+
raise Exception("No video found. Was environment created with save_video enabled?")
|
|
259
|
+
|
|
260
|
+
from base64 import b64encode
|
|
261
|
+
|
|
262
|
+
from IPython.display import HTML, display
|
|
263
|
+
|
|
264
|
+
video = open(env.football_video_path, "rb").read()
|
|
265
|
+
env.football_video_path = None
|
|
266
|
+
data_url = "data:video/webm;base64," + b64encode(video).decode()
|
|
267
|
+
|
|
268
|
+
html = (
|
|
269
|
+
"""
|
|
270
|
+
<video width=800 controls>
|
|
271
|
+
<source src="%s" type="video/webm">
|
|
272
|
+
</video>
|
|
273
|
+
"""
|
|
274
|
+
% data_url
|
|
275
|
+
)
|
|
276
|
+
display(HTML(html))
|
|
277
|
+
return ""
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from functools import wraps
|
|
3
|
+
from typing import *
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Action(Enum):
|
|
7
|
+
Idle = 0
|
|
8
|
+
Left = 1
|
|
9
|
+
TopLeft = 2
|
|
10
|
+
Top = 3
|
|
11
|
+
TopRight = 4
|
|
12
|
+
Right = 5
|
|
13
|
+
BottomRight = 6
|
|
14
|
+
Bottom = 7
|
|
15
|
+
BottomLeft = 8
|
|
16
|
+
LongPass = 9
|
|
17
|
+
HighPass = 10
|
|
18
|
+
ShortPass = 11
|
|
19
|
+
Shot = 12
|
|
20
|
+
Sprint = 13
|
|
21
|
+
ReleaseDirection = 14
|
|
22
|
+
ReleaseSprint = 15
|
|
23
|
+
Slide = 16
|
|
24
|
+
Dribble = 17
|
|
25
|
+
ReleaseDribble = 18
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
sticky_index_to_action = [
|
|
29
|
+
Action.Left,
|
|
30
|
+
Action.TopLeft,
|
|
31
|
+
Action.Top,
|
|
32
|
+
Action.TopRight,
|
|
33
|
+
Action.Right,
|
|
34
|
+
Action.BottomRight,
|
|
35
|
+
Action.Bottom,
|
|
36
|
+
Action.BottomLeft,
|
|
37
|
+
Action.Sprint,
|
|
38
|
+
Action.Dribble,
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class PlayerRole(Enum):
|
|
43
|
+
GoalKeeper = 0
|
|
44
|
+
CenterBack = 1
|
|
45
|
+
LeftBack = 2
|
|
46
|
+
RightBack = 3
|
|
47
|
+
DefenceMidfield = 4
|
|
48
|
+
CentralMidfield = 5
|
|
49
|
+
LeftMidfield = 6
|
|
50
|
+
RIghtMidfield = 7
|
|
51
|
+
AttackMidfield = 8
|
|
52
|
+
CentralFront = 9
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class GameMode(Enum):
|
|
56
|
+
Normal = 0
|
|
57
|
+
KickOff = 1
|
|
58
|
+
GoalKick = 2
|
|
59
|
+
FreeKick = 3
|
|
60
|
+
Corner = 4
|
|
61
|
+
ThrowIn = 5
|
|
62
|
+
Penalty = 6
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def human_readable_agent(agent: Callable[[Dict], Action]):
|
|
66
|
+
"""
|
|
67
|
+
Decorator allowing for more human-friendly implementation of the agent function.
|
|
68
|
+
|
|
69
|
+
@human_readable_agent
|
|
70
|
+
def my_agent(obs):
|
|
71
|
+
...
|
|
72
|
+
return football_action_set.action_right
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
@wraps(agent)
|
|
76
|
+
def agent_wrapper(obs) -> List[int]:
|
|
77
|
+
# Extract observations for the first (and only) player we control.
|
|
78
|
+
obs = obs["players_raw"][0]
|
|
79
|
+
# Turn 'sticky_actions' into a set of active actions (strongly typed).
|
|
80
|
+
obs["sticky_actions"] = {
|
|
81
|
+
sticky_index_to_action[nr] for nr, action in enumerate(obs["sticky_actions"]) if action
|
|
82
|
+
}
|
|
83
|
+
# Turn 'game_mode' into an enum.
|
|
84
|
+
obs["game_mode"] = GameMode(obs["game_mode"])
|
|
85
|
+
# In case of single agent mode, 'designated' is always equal to 'active'.
|
|
86
|
+
if "designated" in obs:
|
|
87
|
+
del obs["designated"]
|
|
88
|
+
# Conver players' roles to enum.
|
|
89
|
+
obs["left_team_roles"] = [PlayerRole(role) for role in obs["left_team_roles"]]
|
|
90
|
+
obs["right_team_roles"] = [PlayerRole(role) for role in obs["right_team_roles"]]
|
|
91
|
+
|
|
92
|
+
action = agent(obs)
|
|
93
|
+
return [action.value]
|
|
94
|
+
|
|
95
|
+
return agent_wrapper
|