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,78 @@
|
|
|
1
|
+
if __package__ == "":
|
|
2
|
+
from lux.utils import direction_to
|
|
3
|
+
else:
|
|
4
|
+
from .lux.utils import direction_to
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Agent:
|
|
9
|
+
def __init__(self, player: str, env_cfg) -> None:
|
|
10
|
+
self.player = player
|
|
11
|
+
self.opp_player = "player_1" if self.player == "player_0" else "player_0"
|
|
12
|
+
self.team_id = 0 if self.player == "player_0" else 1
|
|
13
|
+
self.opp_team_id = 1 if self.team_id == 0 else 0
|
|
14
|
+
np.random.seed(0)
|
|
15
|
+
self.env_cfg = env_cfg
|
|
16
|
+
|
|
17
|
+
self.relic_node_positions = []
|
|
18
|
+
self.discovered_relic_nodes_ids = set()
|
|
19
|
+
self.unit_explore_locations = dict()
|
|
20
|
+
|
|
21
|
+
def act(self, step: int, obs, remainingOverageTime: int = 60):
|
|
22
|
+
"""implement this function to decide what actions to send to each available unit.
|
|
23
|
+
|
|
24
|
+
step is the current timestep number of the game starting from 0 going up to max_steps_in_match * match_count_per_episode - 1.
|
|
25
|
+
"""
|
|
26
|
+
unit_mask = np.array(obs["units_mask"][self.team_id]) # shape (max_units, )
|
|
27
|
+
unit_positions = np.array(obs["units"]["position"][self.team_id]) # shape (max_units, 2)
|
|
28
|
+
unit_energys = np.array(obs["units"]["energy"][self.team_id]) # shape (max_units, 1)
|
|
29
|
+
observed_relic_node_positions = np.array(obs["relic_nodes"]) # shape (max_relic_nodes, 2)
|
|
30
|
+
observed_relic_nodes_mask = np.array(obs["relic_nodes_mask"]) # shape (max_relic_nodes, )
|
|
31
|
+
team_points = np.array(
|
|
32
|
+
obs["team_points"]
|
|
33
|
+
) # points of each team, team_points[self.team_id] is the points of the your team
|
|
34
|
+
|
|
35
|
+
# ids of units you can control at this timestep
|
|
36
|
+
available_unit_ids = np.where(unit_mask)[0]
|
|
37
|
+
# visible relic nodes
|
|
38
|
+
visible_relic_node_ids = set(np.where(observed_relic_nodes_mask)[0])
|
|
39
|
+
|
|
40
|
+
actions = np.zeros((self.env_cfg["max_units"], 3), dtype=int)
|
|
41
|
+
|
|
42
|
+
# basic strategy here is simply to have some units randomly explore and some units collecting as much energy as possible
|
|
43
|
+
# and once a relic node is found, we send all units to move randomly around the first relic node to gain points
|
|
44
|
+
# and information about where relic nodes are found are saved for the next match
|
|
45
|
+
|
|
46
|
+
# save any new relic nodes that we discover for the rest of the game.
|
|
47
|
+
for id in visible_relic_node_ids:
|
|
48
|
+
if id not in self.discovered_relic_nodes_ids:
|
|
49
|
+
self.discovered_relic_nodes_ids.add(id)
|
|
50
|
+
self.relic_node_positions.append(observed_relic_node_positions[id])
|
|
51
|
+
|
|
52
|
+
# unit ids range from 0 to max_units - 1
|
|
53
|
+
for unit_id in available_unit_ids:
|
|
54
|
+
unit_pos = unit_positions[unit_id]
|
|
55
|
+
unit_energy = unit_energys[unit_id]
|
|
56
|
+
if len(self.relic_node_positions) > 0:
|
|
57
|
+
nearest_relic_node_position = self.relic_node_positions[0]
|
|
58
|
+
manhattan_distance = abs(unit_pos[0] - nearest_relic_node_position[0]) + abs(
|
|
59
|
+
unit_pos[1] - nearest_relic_node_position[1]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# if close to the relic node we want to hover around it and hope to gain points
|
|
63
|
+
if manhattan_distance <= 4:
|
|
64
|
+
random_direction = np.random.randint(0, 5)
|
|
65
|
+
actions[unit_id] = [random_direction, 0, 0]
|
|
66
|
+
else:
|
|
67
|
+
# otherwise we want to move towards the relic node
|
|
68
|
+
actions[unit_id] = [direction_to(unit_pos, nearest_relic_node_position), 0, 0]
|
|
69
|
+
else:
|
|
70
|
+
# randomly explore by picking a random location on the map and moving there for about 20 steps
|
|
71
|
+
if step % 20 == 0 or unit_id not in self.unit_explore_locations:
|
|
72
|
+
rand_loc = (
|
|
73
|
+
np.random.randint(0, self.env_cfg["map_width"]),
|
|
74
|
+
np.random.randint(0, self.env_cfg["map_height"]),
|
|
75
|
+
)
|
|
76
|
+
self.unit_explore_locations[unit_id] = rand_loc
|
|
77
|
+
actions[unit_id] = [direction_to(unit_pos, self.unit_explore_locations[unit_id]), 0, 0]
|
|
78
|
+
return actions
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def to_json(obj):
|
|
5
|
+
if isinstance(obj, np.ndarray):
|
|
6
|
+
return obj.tolist()
|
|
7
|
+
elif isinstance(obj, np.integer):
|
|
8
|
+
return int(obj)
|
|
9
|
+
elif isinstance(obj, np.floating):
|
|
10
|
+
return float(obj)
|
|
11
|
+
elif isinstance(obj, list) or isinstance(obj, tuple):
|
|
12
|
+
return [to_json(s) for s in obj]
|
|
13
|
+
elif isinstance(obj, dict):
|
|
14
|
+
out = {}
|
|
15
|
+
for k in obj:
|
|
16
|
+
out[k] = to_json(obj[k])
|
|
17
|
+
return out
|
|
18
|
+
else:
|
|
19
|
+
return obj
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def from_json(state):
|
|
23
|
+
if isinstance(state, list):
|
|
24
|
+
return np.array(state)
|
|
25
|
+
elif isinstance(state, dict):
|
|
26
|
+
out = {}
|
|
27
|
+
for k in state:
|
|
28
|
+
out[k] = from_json(state[k])
|
|
29
|
+
return out
|
|
30
|
+
else:
|
|
31
|
+
return state
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# direction (0 = center, 1 = up, 2 = right, 3 = down, 4 = left)
|
|
2
|
+
def direction_to(src, target):
|
|
3
|
+
ds = target - src
|
|
4
|
+
dx = ds[0]
|
|
5
|
+
dy = ds[1]
|
|
6
|
+
if dx == 0 and dy == 0:
|
|
7
|
+
return 0
|
|
8
|
+
if abs(dx) > abs(dy):
|
|
9
|
+
if dx > 0:
|
|
10
|
+
return 2
|
|
11
|
+
else:
|
|
12
|
+
return 4
|
|
13
|
+
else:
|
|
14
|
+
if dy > 0:
|
|
15
|
+
return 3
|
|
16
|
+
else:
|
|
17
|
+
return 1
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from argparse import Namespace
|
|
3
|
+
|
|
4
|
+
if __package__ == "":
|
|
5
|
+
from agent import Agent
|
|
6
|
+
from lux.kit import from_json
|
|
7
|
+
else:
|
|
8
|
+
from .agent import Agent
|
|
9
|
+
from .lux.kit import from_json
|
|
10
|
+
### DO NOT REMOVE THE FOLLOWING CODE ###
|
|
11
|
+
agent_dict = dict() # store potentially multiple dictionaries as kaggle imports code directly
|
|
12
|
+
agent_prev_obs = dict()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def agent_fn(observation, configurations):
|
|
16
|
+
"""
|
|
17
|
+
agent definition for kaggle submission.
|
|
18
|
+
"""
|
|
19
|
+
global agent_dict
|
|
20
|
+
obs = observation.obs
|
|
21
|
+
if type(obs) == str:
|
|
22
|
+
obs = json.loads(obs)
|
|
23
|
+
step = observation.step
|
|
24
|
+
player = observation.player
|
|
25
|
+
remainingOverageTime = observation.remainingOverageTime
|
|
26
|
+
if step == 0:
|
|
27
|
+
agent_dict[player] = Agent(player, configurations["env_cfg"])
|
|
28
|
+
agent = agent_dict[player]
|
|
29
|
+
actions = agent.act(step, from_json(obs), remainingOverageTime)
|
|
30
|
+
return dict(action=actions.tolist())
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
|
|
35
|
+
def read_input():
|
|
36
|
+
"""
|
|
37
|
+
Reads input from stdin
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
return input()
|
|
41
|
+
except EOFError as eof:
|
|
42
|
+
raise SystemExit(eof)
|
|
43
|
+
|
|
44
|
+
step = 0
|
|
45
|
+
player_id = 0
|
|
46
|
+
env_cfg = None
|
|
47
|
+
i = 0
|
|
48
|
+
while True:
|
|
49
|
+
inputs = read_input()
|
|
50
|
+
raw_input = json.loads(inputs)
|
|
51
|
+
observation = Namespace(
|
|
52
|
+
**dict(
|
|
53
|
+
step=raw_input["step"],
|
|
54
|
+
obs=raw_input["obs"],
|
|
55
|
+
remainingOverageTime=raw_input["remainingOverageTime"],
|
|
56
|
+
player=raw_input["player"],
|
|
57
|
+
info=raw_input["info"],
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
if i == 0:
|
|
61
|
+
env_cfg = raw_input["info"]["env_cfg"]
|
|
62
|
+
player_id = raw_input["player"]
|
|
63
|
+
i += 1
|
|
64
|
+
actions = agent_fn(observation, dict(env_cfg=env_cfg))
|
|
65
|
+
# send actions to engine
|
|
66
|
+
print(json.dumps(actions))
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import random
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def random_agent(observation, configuration):
|
|
5
|
+
return random.randrange(configuration.banditCount - 1)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def round_robin_agent(observation, configuration):
|
|
9
|
+
return observation.step % configuration.banditCount
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
agents = {"random": random_agent, "round_robin": round_robin_agent}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
async function renderer(context) {
|
|
2
|
+
const {
|
|
3
|
+
act,
|
|
4
|
+
agents,
|
|
5
|
+
environment,
|
|
6
|
+
frame,
|
|
7
|
+
height = 400,
|
|
8
|
+
interactive,
|
|
9
|
+
isInteractive,
|
|
10
|
+
parent,
|
|
11
|
+
step,
|
|
12
|
+
update,
|
|
13
|
+
width = 400,
|
|
14
|
+
} = context;
|
|
15
|
+
|
|
16
|
+
// Common Dimensions.
|
|
17
|
+
const maxWidth = 960;
|
|
18
|
+
const maxHeight = 280;
|
|
19
|
+
const canvasSize = Math.min(height, width);
|
|
20
|
+
const unit = 8;
|
|
21
|
+
const offset = canvasSize > 400 ? canvasSize * 0.1 : unit / 2;
|
|
22
|
+
const cellSize = (canvasSize - offset * 2) / 3;
|
|
23
|
+
|
|
24
|
+
// Canvas Setup.
|
|
25
|
+
let canvas = parent.querySelector("canvas");
|
|
26
|
+
if (!canvas) {
|
|
27
|
+
canvas = document.createElement("canvas");
|
|
28
|
+
parent.appendChild(canvas);
|
|
29
|
+
|
|
30
|
+
if (interactive) {
|
|
31
|
+
canvas.addEventListener("click", evt => {
|
|
32
|
+
if (!isInteractive()) return;
|
|
33
|
+
const rect = evt.target.getBoundingClientRect();
|
|
34
|
+
const x = evt.clientX - rect.left - offset;
|
|
35
|
+
const y = evt.clientY - rect.top - offset;
|
|
36
|
+
act(Math.floor(x / cellSize) + Math.floor(y / cellSize) * 3);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
canvas.style.cursor = isInteractive() ? "pointer" : "default";
|
|
42
|
+
|
|
43
|
+
// Canvas setup and reset.
|
|
44
|
+
let c = canvas.getContext("2d");
|
|
45
|
+
canvas.width = Math.min(maxWidth, width);
|
|
46
|
+
canvas.height = Math.min(maxHeight, height);
|
|
47
|
+
c.clearRect(0, 0, canvas.width, canvas.height);
|
|
48
|
+
|
|
49
|
+
// ------------------------------------------------------------------------------------//
|
|
50
|
+
|
|
51
|
+
if (step < environment.steps.length - 1) {
|
|
52
|
+
const state = environment.steps[step + 1]
|
|
53
|
+
const last_state = environment.steps[step]
|
|
54
|
+
|
|
55
|
+
const p1_move = state[0].observation.lastActions[0];
|
|
56
|
+
const p2_move = state[0].observation.lastActions[1];
|
|
57
|
+
|
|
58
|
+
const info = environment.info;
|
|
59
|
+
const player1_text = info?.TeamNames?.[0] || "Player 1";
|
|
60
|
+
const player2_text = info?.TeamNames?.[1] || "Player 2";
|
|
61
|
+
|
|
62
|
+
const ctx = canvas.getContext("2d");
|
|
63
|
+
const padding = 20;
|
|
64
|
+
const row_width = (Math.min(maxWidth, width) - padding * 2) / 3;
|
|
65
|
+
const label_x = padding;
|
|
66
|
+
const player1_x = padding + row_width;
|
|
67
|
+
const player2_x = padding + 2 * row_width;
|
|
68
|
+
const label_y = 40;
|
|
69
|
+
const sign_id_y = 80;
|
|
70
|
+
const result_y = 120;
|
|
71
|
+
const score_y = 160;
|
|
72
|
+
|
|
73
|
+
ctx.font = "30px sans-serif";
|
|
74
|
+
ctx.fillStyle = "#FFFFFF";
|
|
75
|
+
|
|
76
|
+
// Player Row
|
|
77
|
+
ctx.fillText(player1_text, player1_x, label_y)
|
|
78
|
+
ctx.fillText(player2_text, player2_x, label_y)
|
|
79
|
+
|
|
80
|
+
// Action Id Row
|
|
81
|
+
ctx.fillText("Action:", label_x, sign_id_y);
|
|
82
|
+
ctx.fillText(p1_move, player1_x, sign_id_y);
|
|
83
|
+
ctx.fillText(p2_move, player2_x, sign_id_y);
|
|
84
|
+
|
|
85
|
+
// Result Row
|
|
86
|
+
ctx.fillText("Result:", label_x, result_y);
|
|
87
|
+
if (state[0].reward - last_state[0].reward > 0) {
|
|
88
|
+
ctx.fillText("Win", player1_x, result_y);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (state[1].reward - last_state[1].reward > 0) {
|
|
92
|
+
ctx.fillText("Win", player2_x, result_y);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Reward Row
|
|
96
|
+
ctx.fillText("Reward:", label_x, score_y);
|
|
97
|
+
ctx.fillText(state[0].reward, player1_x, score_y);
|
|
98
|
+
ctx.fillText(state[1].reward, player2_x, score_y);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mab",
|
|
3
|
+
"title": "Adversarial Multi-armed Bandit",
|
|
4
|
+
"description": "Adversarial Multi-armed Bandit",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"agents": [2, 3, 4, 5, 6, 7, 8],
|
|
7
|
+
"configuration": {
|
|
8
|
+
"episodeSteps": 2000,
|
|
9
|
+
"actTimeout": 0.25,
|
|
10
|
+
"banditCount": {
|
|
11
|
+
"description": "Number of bandits available to choose from. Max action is this number -1.",
|
|
12
|
+
"type": "integer",
|
|
13
|
+
"minimum": 2,
|
|
14
|
+
"default": 100
|
|
15
|
+
},
|
|
16
|
+
"decayRate": {
|
|
17
|
+
"description": "Rate that reward chance threshold increases per step that a bandit is chosen by an agent.",
|
|
18
|
+
"type": "number",
|
|
19
|
+
"minimum": 0,
|
|
20
|
+
"default": 0.97
|
|
21
|
+
},
|
|
22
|
+
"sampleResolution": {
|
|
23
|
+
"description": "Maximum value that can be returned by a bandit.",
|
|
24
|
+
"type": "integer",
|
|
25
|
+
"minimum": 1,
|
|
26
|
+
"default": 100
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"reward": {
|
|
30
|
+
"description": "The total reward each player has accumulated from the bandits across all steps.",
|
|
31
|
+
"type": "number",
|
|
32
|
+
"minimum": 0,
|
|
33
|
+
"default": 0
|
|
34
|
+
},
|
|
35
|
+
"observation": {
|
|
36
|
+
"remainingOverageTime": 60,
|
|
37
|
+
"agentIndex": {
|
|
38
|
+
"description": "The current agent's index within observation.lastActions.",
|
|
39
|
+
"type": "integer",
|
|
40
|
+
"defaults": [0, 1, 2, 3, 4, 5, 6, 7]
|
|
41
|
+
},
|
|
42
|
+
"reward": {
|
|
43
|
+
"description": "Current reward of the agent.",
|
|
44
|
+
"type": "number",
|
|
45
|
+
"minimum": 0,
|
|
46
|
+
"default": 0
|
|
47
|
+
},
|
|
48
|
+
"lastActions": {
|
|
49
|
+
"description": "Bandits chosen by each agent on the last step. None on the first step.",
|
|
50
|
+
"type": "array",
|
|
51
|
+
"shared": true,
|
|
52
|
+
"items": {
|
|
53
|
+
"type": "number",
|
|
54
|
+
"minimum": 0
|
|
55
|
+
},
|
|
56
|
+
"default": []
|
|
57
|
+
},
|
|
58
|
+
"thresholds": {
|
|
59
|
+
"description": "Probability values for each machine payout on this step. Hidden from agents at runtime.",
|
|
60
|
+
"type": "array",
|
|
61
|
+
"shared": true,
|
|
62
|
+
"hidden": true,
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "number",
|
|
65
|
+
"minimum": 0
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"action": {
|
|
70
|
+
"description": "Choice of bandit for the step (min bandit = 0, max bandit = configuration.banditCount - 1)",
|
|
71
|
+
"type": "integer",
|
|
72
|
+
"minimum": 0
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from os import path
|
|
3
|
+
from random import SystemRandom
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
import kaggle_environments.helpers
|
|
7
|
+
|
|
8
|
+
from .agents import agents as all_agents
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Observation(kaggle_environments.helpers.Observation):
|
|
12
|
+
@property
|
|
13
|
+
def agent_index(self) -> float:
|
|
14
|
+
"""The current agent's index within observation.last_actions."""
|
|
15
|
+
return self["agentIndex"]
|
|
16
|
+
|
|
17
|
+
"""This provides bindings for the observation type described at https://github.com/Kaggle/kaggle-environments/blob/master/kaggle_environments/envs/mab/mab.json"""
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def last_actions(self) -> List[int]:
|
|
21
|
+
"""Bandit chosen by opponent last step. None on the first step."""
|
|
22
|
+
return self["lastActions"]
|
|
23
|
+
|
|
24
|
+
@last_actions.setter
|
|
25
|
+
def last_actions(self, value):
|
|
26
|
+
self["lastActions"] = value
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def reward(self) -> float:
|
|
30
|
+
"""Current reward of the agent."""
|
|
31
|
+
return self["reward"]
|
|
32
|
+
|
|
33
|
+
@reward.setter
|
|
34
|
+
def reward(self, value):
|
|
35
|
+
self["reward"] = value
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def thresholds(self) -> List[float]:
|
|
39
|
+
"""Probability values for each machine payout on this step. This value is None at agent runtime."""
|
|
40
|
+
return self["thresholds"] if "thresholds" in self else None
|
|
41
|
+
|
|
42
|
+
@thresholds.setter
|
|
43
|
+
def thresholds(self, value):
|
|
44
|
+
self["thresholds"] = value
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Configuration(kaggle_environments.helpers.Configuration):
|
|
48
|
+
"""This provides bindings for the configuration type described at https://github.com/Kaggle/kaggle-environments/blob/master/kaggle_environments/envs/mab/mab.json"""
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def bandit_count(self) -> int:
|
|
52
|
+
"""Number of bandits available to choose from. Max action is this number -1."""
|
|
53
|
+
return self["banditCount"]
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def decay_rate(self) -> float:
|
|
57
|
+
"""Rate that reward chance threshold increases per step that a bandit is chosen by an agent."""
|
|
58
|
+
return self["decayRate"]
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def sample_resolution(self) -> int:
|
|
62
|
+
"""Maximum value that can be returned by a bandit."""
|
|
63
|
+
return self["sampleResolution"]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# SystemRandom is used to provide stronger randoms than builtin twister
|
|
67
|
+
random = SystemRandom()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def interpreter(agents, env):
|
|
71
|
+
configuration = Configuration(env.configuration)
|
|
72
|
+
shared_agent = agents[0]
|
|
73
|
+
# Assign shared_agent.observation so that changes that we make to the shared observation are propagated back to the agent state.
|
|
74
|
+
shared_agent.observation = shared_observation = Observation(shared_agent.observation)
|
|
75
|
+
|
|
76
|
+
def sample():
|
|
77
|
+
"""Obtain a value between 0 and sampleResolution to check against a bandit threshold."""
|
|
78
|
+
return random.randint(0, configuration.sample_resolution)
|
|
79
|
+
|
|
80
|
+
if env.done:
|
|
81
|
+
# Initialize thresholds
|
|
82
|
+
shared_observation.last_actions = None
|
|
83
|
+
shared_observation.thresholds = [sample() for _ in range(configuration.bandit_count)]
|
|
84
|
+
return agents
|
|
85
|
+
|
|
86
|
+
# Provide actions in the next observation so agents can monitor opponents.
|
|
87
|
+
shared_observation.last_actions = [agent.action for agent in agents]
|
|
88
|
+
thresholds = shared_observation.thresholds
|
|
89
|
+
|
|
90
|
+
for agent in agents:
|
|
91
|
+
if (
|
|
92
|
+
agent.action is not None
|
|
93
|
+
and isinstance(agent.action, int)
|
|
94
|
+
and 0 <= agent.action < configuration.bandit_count
|
|
95
|
+
):
|
|
96
|
+
# If the sample is less than the threshold the agent gains reward, otherwise nothing
|
|
97
|
+
agent.reward += 1 if sample() < thresholds[agent.action] else 0
|
|
98
|
+
agent.observation.reward = agent.reward
|
|
99
|
+
else:
|
|
100
|
+
agent.status = "INVALID"
|
|
101
|
+
agent.reward = -1
|
|
102
|
+
|
|
103
|
+
initial_thresholds = env.steps[0][0].observation.thresholds
|
|
104
|
+
action_histogram = kaggle_environments.helpers.histogram(shared_observation.last_actions)
|
|
105
|
+
|
|
106
|
+
for index, threshold in enumerate(thresholds):
|
|
107
|
+
# Every time a threshold is selected it is multiplied by (decay_rate) for each agent that selected it.
|
|
108
|
+
# When a threshold is not selected it is reduced by (decay_rate) ^ 0 (i.e. no recovery).
|
|
109
|
+
action_count = action_histogram[index] if index in action_histogram else 0
|
|
110
|
+
update_rate = (configuration.decay_rate) ** action_count
|
|
111
|
+
thresholds[index] = min(threshold * update_rate, initial_thresholds[index])
|
|
112
|
+
|
|
113
|
+
active_agents = [agent for agent in agents if agent.status == "ACTIVE" or agent.status == "INACTIVE"]
|
|
114
|
+
|
|
115
|
+
if len(active_agents) <= 1:
|
|
116
|
+
for agent in active_agents:
|
|
117
|
+
agent.status = "DONE"
|
|
118
|
+
|
|
119
|
+
return agents
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def renderer(steps, env):
|
|
123
|
+
rounds_played = len(env.steps)
|
|
124
|
+
board = ""
|
|
125
|
+
|
|
126
|
+
for i in range(1, rounds_played):
|
|
127
|
+
actions = [agent.action for agent in steps[i]]
|
|
128
|
+
rewards = [agent.reward for agent in steps[i]]
|
|
129
|
+
board += f"Round {i} Actions: {actions}, Rewards: {rewards}\n"
|
|
130
|
+
|
|
131
|
+
return board
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
dir_path = path.dirname(__file__)
|
|
135
|
+
json_path = path.abspath(path.join(dir_path, "mab.json"))
|
|
136
|
+
with open(json_path) as json_file:
|
|
137
|
+
specification = json.load(json_file)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def html_renderer():
|
|
141
|
+
js_path = path.abspath(path.join(dir_path, "mab.js"))
|
|
142
|
+
with open(js_path, encoding="utf-8") as js_file:
|
|
143
|
+
return js_file.read()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
agents = all_agents
|
|
File without changes
|
|
File without changes
|