kaggle-environments 0.2.1__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 +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-1.20.0.dist-info/METADATA +25 -0
- kaggle_environments-1.20.0.dist-info/RECORD +211 -0
- {kaggle_environments-0.2.1.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 -223
- kaggle_environments/temp.py +0 -14
- kaggle_environments-0.2.1.dist-info/METADATA +0 -393
- 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.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
# Copyright 2022 Kaggle Inc
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import copy
|
|
16
|
+
import json
|
|
17
|
+
import math
|
|
18
|
+
from os import path
|
|
19
|
+
from random import randint, random, randrange, sample, seed
|
|
20
|
+
|
|
21
|
+
import numpy as np
|
|
22
|
+
|
|
23
|
+
from kaggle_environments import utils
|
|
24
|
+
from kaggle_environments.helpers import Direction, Point
|
|
25
|
+
|
|
26
|
+
from .helpers import Board, ShipyardAction, board_agent
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_col_row(size, pos):
|
|
30
|
+
return pos % size, pos // size
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_to_pos(size, pos, direction):
|
|
34
|
+
col, row = get_col_row(size, pos)
|
|
35
|
+
if direction == "NORTH":
|
|
36
|
+
return pos - size if pos >= size else size**2 - size + col
|
|
37
|
+
elif direction == "SOUTH":
|
|
38
|
+
return col if pos + size >= size**2 else pos + size
|
|
39
|
+
elif direction == "EAST":
|
|
40
|
+
return pos + 1 if col < size - 1 else row * size
|
|
41
|
+
elif direction == "WEST":
|
|
42
|
+
return pos - 1 if col > 0 else (row + 1) * size - 1
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def check_path(board, start, dirs, dist_a, dist_b, collection_rate):
|
|
46
|
+
kore = 0
|
|
47
|
+
npv = 0.98
|
|
48
|
+
current = start
|
|
49
|
+
steps = 2 * (dist_a + dist_b + 2)
|
|
50
|
+
for idx, d in enumerate(dirs):
|
|
51
|
+
for _ in range((dist_a if idx % 2 == 0 else dist_b) + 1):
|
|
52
|
+
current = current.translate(d.to_point(), board.configuration.size)
|
|
53
|
+
kore += int((board.cells.get(current).kore or 0) * collection_rate)
|
|
54
|
+
return math.pow(npv, steps) * kore / (2 * (dist_a + dist_b + 2))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def check_location(board, loc, me):
|
|
58
|
+
if board.cells.get(loc).shipyard and board.cells.get(loc).shipyard.player.id == me.id:
|
|
59
|
+
return 0
|
|
60
|
+
kore = 0
|
|
61
|
+
for i in range(-3, 4):
|
|
62
|
+
for j in range(-3, 4):
|
|
63
|
+
pos = loc.translate(Point(i, j), board.configuration.size)
|
|
64
|
+
kore += board.cells.get(pos).kore or 0
|
|
65
|
+
return kore
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_closest_enemy_shipyard(board, position, me):
|
|
69
|
+
min_dist = 1000000
|
|
70
|
+
enemy_shipyard = None
|
|
71
|
+
for shipyard in board.shipyards.values():
|
|
72
|
+
if shipyard.player_id == me.id:
|
|
73
|
+
continue
|
|
74
|
+
dist = position.distance_to(shipyard.position, board.configuration.size)
|
|
75
|
+
if dist < min_dist:
|
|
76
|
+
min_dist = dist
|
|
77
|
+
enemy_shipyard = shipyard
|
|
78
|
+
return enemy_shipyard
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def get_shortest_flight_path_between(position_a, position_b, size, trailing_digits=False):
|
|
82
|
+
mag_x = 1 if position_b.x > position_a.x else -1
|
|
83
|
+
abs_x = abs(position_b.x - position_a.x)
|
|
84
|
+
dir_x = mag_x if abs_x < size / 2 else -mag_x
|
|
85
|
+
mag_y = 1 if position_b.y > position_a.y else -1
|
|
86
|
+
abs_y = abs(position_b.y - position_a.y)
|
|
87
|
+
dir_y = mag_y if abs_y < size / 2 else -mag_y
|
|
88
|
+
flight_path_x = ""
|
|
89
|
+
if abs_x > 0:
|
|
90
|
+
flight_path_x += "E" if dir_x == 1 else "W"
|
|
91
|
+
flight_path_x += str(abs_x - 1) if (abs_x - 1) > 0 else ""
|
|
92
|
+
flight_path_y = ""
|
|
93
|
+
if abs_y > 0:
|
|
94
|
+
flight_path_y += "N" if dir_y == 1 else "S"
|
|
95
|
+
flight_path_y += str(abs_y - 1) if (abs_y - 1) > 0 else ""
|
|
96
|
+
if not len(flight_path_x) == len(flight_path_y):
|
|
97
|
+
if len(flight_path_x) < len(flight_path_y):
|
|
98
|
+
return flight_path_x + (flight_path_y if trailing_digits else flight_path_y[0])
|
|
99
|
+
else:
|
|
100
|
+
return flight_path_y + (flight_path_x if trailing_digits else flight_path_x[0])
|
|
101
|
+
return (
|
|
102
|
+
flight_path_y + (flight_path_x if trailing_digits or not flight_path_x else flight_path_x[0])
|
|
103
|
+
if random() < 0.5
|
|
104
|
+
else flight_path_x + (flight_path_y if trailing_digits or not flight_path_y else flight_path_y[0])
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@board_agent
|
|
109
|
+
def attacker_agent(board):
|
|
110
|
+
me = board.current_player
|
|
111
|
+
remaining_kore = me.kore
|
|
112
|
+
shipyards = me.shipyards
|
|
113
|
+
size = board.configuration.size
|
|
114
|
+
spawn_cost = board.configuration.spawn_cost
|
|
115
|
+
# randomize shipyard order
|
|
116
|
+
shipyards = sample(shipyards, len(shipyards))
|
|
117
|
+
for idx, shipyard in enumerate(shipyards):
|
|
118
|
+
closest_enemy_shipyard = get_closest_enemy_shipyard(board, shipyard.position, me)
|
|
119
|
+
if closest_enemy_shipyard and (remaining_kore >= spawn_cost or shipyard.ship_count >= 50):
|
|
120
|
+
if shipyard.ship_count >= 50:
|
|
121
|
+
flight_plan = get_shortest_flight_path_between(shipyard.position, closest_enemy_shipyard.position, size)
|
|
122
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(50, flight_plan)
|
|
123
|
+
elif remaining_kore >= spawn_cost:
|
|
124
|
+
shipyard.next_action = ShipyardAction.spawn_ships(
|
|
125
|
+
min(shipyard.max_spawn, int(remaining_kore / spawn_cost))
|
|
126
|
+
)
|
|
127
|
+
elif shipyard.ship_count >= 21:
|
|
128
|
+
best_h = 0
|
|
129
|
+
best_gap1 = 5
|
|
130
|
+
best_gap2 = 5
|
|
131
|
+
start_dir = board.step % 4
|
|
132
|
+
dirs = Direction.list_directions()[start_dir:] + Direction.list_directions()[:start_dir]
|
|
133
|
+
for gap1 in range(0, 10):
|
|
134
|
+
for gap2 in range(0, 10):
|
|
135
|
+
h = check_path(board, shipyard.position, dirs, gap1, gap2, 0.2)
|
|
136
|
+
if h > best_h:
|
|
137
|
+
best_h = h
|
|
138
|
+
best_gap1 = gap1
|
|
139
|
+
best_gap2 = gap2
|
|
140
|
+
gap1 = str(best_gap1)
|
|
141
|
+
gap2 = str(best_gap2)
|
|
142
|
+
flight_plan = Direction.list_directions()[start_dir].to_char()
|
|
143
|
+
if int(gap1):
|
|
144
|
+
flight_plan += gap1
|
|
145
|
+
next_dir = (start_dir + 1) % 4
|
|
146
|
+
flight_plan += Direction.list_directions()[next_dir].to_char()
|
|
147
|
+
if int(gap2):
|
|
148
|
+
flight_plan += gap2
|
|
149
|
+
next_dir = (next_dir + 1) % 4
|
|
150
|
+
flight_plan += Direction.list_directions()[next_dir].to_char()
|
|
151
|
+
if int(gap1):
|
|
152
|
+
flight_plan += gap1
|
|
153
|
+
next_dir = (next_dir + 1) % 4
|
|
154
|
+
flight_plan += Direction.list_directions()[next_dir].to_char()
|
|
155
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(21, flight_plan)
|
|
156
|
+
elif shipyard.ship_count > 0 and len(shipyards) > 1:
|
|
157
|
+
flight_plan = get_shortest_flight_path_between(
|
|
158
|
+
shipyard.position, shipyards[(idx + 1) % len(shipyards)].position, size
|
|
159
|
+
)
|
|
160
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(shipyard.ship_count, flight_plan)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@board_agent
|
|
164
|
+
def balanced_agent(board):
|
|
165
|
+
me = board.current_player
|
|
166
|
+
me = board.current_player
|
|
167
|
+
remaining_kore = me.kore
|
|
168
|
+
shipyards = me.shipyards
|
|
169
|
+
convert_cost = board.configuration.convert_cost
|
|
170
|
+
size = board.configuration.size
|
|
171
|
+
spawn_cost = board.configuration.spawn_cost
|
|
172
|
+
|
|
173
|
+
# randomize shipyard order
|
|
174
|
+
shipyards = sample(shipyards, len(shipyards))
|
|
175
|
+
for shipyard in shipyards:
|
|
176
|
+
closest_enemy_shipyard = get_closest_enemy_shipyard(board, shipyard.position, me)
|
|
177
|
+
invading_fleet_size = 100
|
|
178
|
+
dist_to_closest_enemy_shipyard = (
|
|
179
|
+
100 if not closest_enemy_shipyard else shipyard.position.distance_to(closest_enemy_shipyard.position, size)
|
|
180
|
+
)
|
|
181
|
+
if (
|
|
182
|
+
closest_enemy_shipyard
|
|
183
|
+
and (closest_enemy_shipyard.ship_count < 20 or dist_to_closest_enemy_shipyard < 15)
|
|
184
|
+
and (remaining_kore >= spawn_cost or shipyard.ship_count >= invading_fleet_size)
|
|
185
|
+
):
|
|
186
|
+
if shipyard.ship_count >= invading_fleet_size:
|
|
187
|
+
flight_plan = get_shortest_flight_path_between(shipyard.position, closest_enemy_shipyard.position, size)
|
|
188
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(invading_fleet_size, flight_plan)
|
|
189
|
+
elif remaining_kore >= spawn_cost:
|
|
190
|
+
shipyard.next_action = ShipyardAction.spawn_ships(
|
|
191
|
+
min(shipyard.max_spawn, int(remaining_kore / spawn_cost))
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
elif remaining_kore > 500 and shipyard.max_spawn > 5:
|
|
195
|
+
if shipyard.ship_count >= convert_cost + 7:
|
|
196
|
+
start_dir = randint(0, 3)
|
|
197
|
+
next_dir = (start_dir + 1) % 4
|
|
198
|
+
best_kore = 0
|
|
199
|
+
best_gap1 = 0
|
|
200
|
+
best_gap2 = 0
|
|
201
|
+
for gap1 in range(5, 15, 3):
|
|
202
|
+
for gap2 in range(5, 15, 3):
|
|
203
|
+
gap2 = randint(3, 9)
|
|
204
|
+
diff1 = Direction.from_index(start_dir).to_point() * gap1
|
|
205
|
+
diff2 = Direction.from_index(next_dir).to_point() * gap2
|
|
206
|
+
diff = diff1 + diff2
|
|
207
|
+
pos = shipyard.position.translate(diff, board.configuration.size)
|
|
208
|
+
h = check_location(board, pos, me)
|
|
209
|
+
if h > best_kore:
|
|
210
|
+
best_kore = h
|
|
211
|
+
best_gap1 = gap1
|
|
212
|
+
best_gap2 = gap2
|
|
213
|
+
gap1 = str(best_gap1)
|
|
214
|
+
gap2 = str(best_gap2)
|
|
215
|
+
flight_plan = Direction.list_directions()[start_dir].to_char() + gap1
|
|
216
|
+
flight_plan += Direction.list_directions()[next_dir].to_char() + gap2
|
|
217
|
+
flight_plan += "C"
|
|
218
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(
|
|
219
|
+
max(convert_cost + 7, int(shipyard.ship_count / 2)), flight_plan
|
|
220
|
+
)
|
|
221
|
+
elif remaining_kore >= spawn_cost:
|
|
222
|
+
shipyard.next_action = ShipyardAction.spawn_ships(
|
|
223
|
+
min(shipyard.max_spawn, int(remaining_kore / spawn_cost))
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# launch a large fleet if able
|
|
227
|
+
elif shipyard.ship_count >= 21:
|
|
228
|
+
best_h = 0
|
|
229
|
+
best_gap1 = 5
|
|
230
|
+
best_gap2 = 5
|
|
231
|
+
start_dir = board.step % 4
|
|
232
|
+
dirs = Direction.list_directions()[start_dir:] + Direction.list_directions()[:start_dir]
|
|
233
|
+
for gap1 in range(0, 10):
|
|
234
|
+
for gap2 in range(0, 10):
|
|
235
|
+
h = check_path(board, shipyard.position, dirs, gap1, gap2, 0.2)
|
|
236
|
+
if h > best_h:
|
|
237
|
+
best_h = h
|
|
238
|
+
best_gap1 = gap1
|
|
239
|
+
best_gap2 = gap2
|
|
240
|
+
gap1 = str(best_gap1)
|
|
241
|
+
gap2 = str(best_gap2)
|
|
242
|
+
flight_plan = Direction.list_directions()[start_dir].to_char()
|
|
243
|
+
if int(gap1):
|
|
244
|
+
flight_plan += gap1
|
|
245
|
+
next_dir = (start_dir + 1) % 4
|
|
246
|
+
flight_plan += Direction.list_directions()[next_dir].to_char()
|
|
247
|
+
if int(gap2):
|
|
248
|
+
flight_plan += gap2
|
|
249
|
+
next_dir = (next_dir + 1) % 4
|
|
250
|
+
flight_plan += Direction.list_directions()[next_dir].to_char()
|
|
251
|
+
if int(gap1):
|
|
252
|
+
flight_plan += gap1
|
|
253
|
+
next_dir = (next_dir + 1) % 4
|
|
254
|
+
flight_plan += Direction.list_directions()[next_dir].to_char()
|
|
255
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(21, flight_plan)
|
|
256
|
+
# else spawn if possible
|
|
257
|
+
elif remaining_kore > board.configuration.spawn_cost * shipyard.max_spawn:
|
|
258
|
+
remaining_kore -= board.configuration.spawn_cost
|
|
259
|
+
if remaining_kore >= spawn_cost:
|
|
260
|
+
shipyard.next_action = ShipyardAction.spawn_ships(
|
|
261
|
+
min(shipyard.max_spawn, int(remaining_kore / spawn_cost))
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
@board_agent
|
|
266
|
+
def do_nothing_agent(board):
|
|
267
|
+
pass
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
@board_agent
|
|
271
|
+
def random_agent(board):
|
|
272
|
+
me = board.current_player
|
|
273
|
+
remaining_kore = me.kore
|
|
274
|
+
shipyards = me.shipyards
|
|
275
|
+
# randomize shipyard order
|
|
276
|
+
shipyards = sample(shipyards, len(shipyards))
|
|
277
|
+
for shipyard in shipyards:
|
|
278
|
+
# 25% chance to launch a large fleet
|
|
279
|
+
if randint(0, 3) == 0 and shipyard.ship_count > 10:
|
|
280
|
+
dir_str = Direction.random_direction().to_char()
|
|
281
|
+
dir2_str = Direction.random_direction().to_char()
|
|
282
|
+
flight_plan = dir_str + str(randint(1, 10)) + dir2_str
|
|
283
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(
|
|
284
|
+
min(10, math.floor(shipyard.ship_count / 2)), flight_plan
|
|
285
|
+
)
|
|
286
|
+
# else spawn if possible
|
|
287
|
+
elif remaining_kore > board.configuration.spawn_cost * shipyard.max_spawn:
|
|
288
|
+
remaining_kore -= board.configuration.spawn_cost
|
|
289
|
+
shipyard.next_action = ShipyardAction.spawn_ships(shipyard.max_spawn)
|
|
290
|
+
# else launch a small fleet
|
|
291
|
+
elif shipyard.ship_count >= 2:
|
|
292
|
+
dir_str = Direction.random_direction().to_char()
|
|
293
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(2, dir_str)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
@board_agent
|
|
297
|
+
def miner_agent(board):
|
|
298
|
+
me = board.current_player
|
|
299
|
+
remaining_kore = me.kore
|
|
300
|
+
shipyards = me.shipyards
|
|
301
|
+
convert_cost = board.configuration.convert_cost
|
|
302
|
+
spawn_cost = board.configuration.spawn_cost
|
|
303
|
+
# randomize shipyard order
|
|
304
|
+
shipyards = sample(shipyards, len(shipyards))
|
|
305
|
+
for shipyard in shipyards:
|
|
306
|
+
if remaining_kore > 1000 and shipyard.max_spawn > 5:
|
|
307
|
+
if shipyard.ship_count >= convert_cost + 10:
|
|
308
|
+
gap1 = str(randint(3, 9))
|
|
309
|
+
gap2 = str(randint(3, 9))
|
|
310
|
+
start_dir = randint(0, 3)
|
|
311
|
+
flight_plan = Direction.list_directions()[start_dir].to_char() + gap1
|
|
312
|
+
next_dir = (start_dir + 1) % 4
|
|
313
|
+
flight_plan += Direction.list_directions()[next_dir].to_char() + gap2
|
|
314
|
+
next_dir = (next_dir + 1) % 4
|
|
315
|
+
flight_plan += "C"
|
|
316
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(
|
|
317
|
+
max(convert_cost + 10, int(shipyard.ship_count / 2)), flight_plan
|
|
318
|
+
)
|
|
319
|
+
elif remaining_kore >= spawn_cost:
|
|
320
|
+
shipyard.next_action = ShipyardAction.spawn_ships(
|
|
321
|
+
min(shipyard.max_spawn, int(remaining_kore / spawn_cost))
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
# launch a large fleet if able
|
|
325
|
+
|
|
326
|
+
elif shipyard.ship_count >= 21:
|
|
327
|
+
gap1 = str(randint(3, 9))
|
|
328
|
+
gap2 = str(randint(3, 9))
|
|
329
|
+
start_dir = randint(0, 3)
|
|
330
|
+
flight_plan = Direction.list_directions()[start_dir].to_char() + gap1
|
|
331
|
+
next_dir = (start_dir + 1) % 4
|
|
332
|
+
flight_plan += Direction.list_directions()[next_dir].to_char() + gap2
|
|
333
|
+
next_dir = (next_dir + 1) % 4
|
|
334
|
+
flight_plan += Direction.list_directions()[next_dir].to_char() + gap1
|
|
335
|
+
next_dir = (next_dir + 1) % 4
|
|
336
|
+
flight_plan += Direction.list_directions()[next_dir].to_char()
|
|
337
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(21, flight_plan)
|
|
338
|
+
# else spawn if possible
|
|
339
|
+
elif remaining_kore > board.configuration.spawn_cost * shipyard.max_spawn:
|
|
340
|
+
remaining_kore -= board.configuration.spawn_cost
|
|
341
|
+
if remaining_kore >= spawn_cost:
|
|
342
|
+
shipyard.next_action = ShipyardAction.spawn_ships(
|
|
343
|
+
min(shipyard.max_spawn, int(remaining_kore / spawn_cost))
|
|
344
|
+
)
|
|
345
|
+
# else launch a small fleet
|
|
346
|
+
elif shipyard.ship_count >= 2:
|
|
347
|
+
dir_str = Direction.random_direction().to_char()
|
|
348
|
+
shipyard.next_action = ShipyardAction.launch_fleet_with_flight_plan(2, dir_str)
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
agents = {
|
|
352
|
+
"random": random_agent,
|
|
353
|
+
"miner": miner_agent,
|
|
354
|
+
"do_nothing": do_nothing_agent,
|
|
355
|
+
"balanced": balanced_agent,
|
|
356
|
+
"attacker": attacker_agent,
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def populate_board(state, env):
|
|
361
|
+
obs = state[0].observation
|
|
362
|
+
config = env.configuration
|
|
363
|
+
size = env.configuration.size
|
|
364
|
+
uid_counter = 0
|
|
365
|
+
|
|
366
|
+
# Set seed for random number generators
|
|
367
|
+
if not hasattr(config, "randomSeed"):
|
|
368
|
+
max_int_32 = (1 << 31) - 1
|
|
369
|
+
config.randomSeed = randrange(max_int_32)
|
|
370
|
+
|
|
371
|
+
np.random.seed(config.randomSeed)
|
|
372
|
+
seed(config.randomSeed)
|
|
373
|
+
|
|
374
|
+
# This is a consistent way to generate unique strings to form ship and shipyard ids
|
|
375
|
+
def create_uid():
|
|
376
|
+
nonlocal uid_counter
|
|
377
|
+
uid_counter += 1
|
|
378
|
+
return f"{obs.step}-{uid_counter}"
|
|
379
|
+
|
|
380
|
+
# Distribute Kore evenly into quartiles.
|
|
381
|
+
half = math.ceil(size / 2)
|
|
382
|
+
grid = [[0] * half for _ in range(half)]
|
|
383
|
+
|
|
384
|
+
# Randomly place a few kore "seeds".
|
|
385
|
+
for i in range(half):
|
|
386
|
+
# random distribution across entire quartile
|
|
387
|
+
grid[randint(0, half - 1)][randint(0, half - 1)] = i**2
|
|
388
|
+
|
|
389
|
+
# as well as a particular distribution weighted toward the center of the map
|
|
390
|
+
grid[randint(half // 2, half - 1)][randint(half // 2, half - 1)] = i**2
|
|
391
|
+
|
|
392
|
+
# Spread the seeds radially.
|
|
393
|
+
radius_grid = copy.deepcopy(grid)
|
|
394
|
+
for r in range(half):
|
|
395
|
+
for c in range(half):
|
|
396
|
+
value = grid[r][c]
|
|
397
|
+
if value == 0:
|
|
398
|
+
continue
|
|
399
|
+
|
|
400
|
+
# keep initial seed values, but constrain radius of clusters
|
|
401
|
+
radius = min(round((value / half) ** 0.5), 1)
|
|
402
|
+
for r2 in range(r - radius + 1, r + radius):
|
|
403
|
+
for c2 in range(c - radius + 1, c + radius):
|
|
404
|
+
if 0 <= r2 < half and 0 <= c2 < half:
|
|
405
|
+
distance = (abs(r2 - r) ** 2 + abs(c2 - c) ** 2) ** 0.5
|
|
406
|
+
radius_grid[r2][c2] += int(value / max(1, distance) ** distance)
|
|
407
|
+
|
|
408
|
+
# add some random sprouts of kore
|
|
409
|
+
radius_grid = np.asarray(radius_grid)
|
|
410
|
+
add_grid = np.random.gumbel(0, 300.0, size=(half, half)).astype(int)
|
|
411
|
+
sparse_radius_grid = np.random.binomial(1, 0.5, size=(half, half))
|
|
412
|
+
add_grid = np.clip(add_grid, 0, a_max=None) * sparse_radius_grid
|
|
413
|
+
radius_grid += add_grid
|
|
414
|
+
|
|
415
|
+
# add another set of random locations to the center corner
|
|
416
|
+
corner_grid = np.random.gumbel(0, 500.0, size=(half // 4, half // 4)).astype(int)
|
|
417
|
+
corner_grid = np.clip(corner_grid, 0, a_max=None)
|
|
418
|
+
radius_grid[half - (half // 4) :, half - (half // 4) :] += corner_grid
|
|
419
|
+
|
|
420
|
+
# make it assomptocially symmetric
|
|
421
|
+
for i in range(half):
|
|
422
|
+
for j in range(half):
|
|
423
|
+
if i + j < half:
|
|
424
|
+
radius_grid[i][j] = radius_grid[j][i]
|
|
425
|
+
|
|
426
|
+
# Normalize the available kore against the defined configuration starting kore.
|
|
427
|
+
total = sum([sum(row) for row in radius_grid])
|
|
428
|
+
obs.kore = [0] * (size**2)
|
|
429
|
+
for r, row in enumerate(radius_grid):
|
|
430
|
+
for c, val in enumerate(row):
|
|
431
|
+
val = int(val * config.startingKore / total / 4)
|
|
432
|
+
obs.kore[size * r + c] = val
|
|
433
|
+
obs.kore[size * r + (size - c - 1)] = val
|
|
434
|
+
obs.kore[size * (size - 1) - (size * r) + c] = val
|
|
435
|
+
obs.kore[size * (size - 1) - (size * r) + (size - c - 1)] = val
|
|
436
|
+
|
|
437
|
+
# Distribute the starting shipyards evenly.
|
|
438
|
+
num_agents = len(state)
|
|
439
|
+
starting_positions = [0] * num_agents
|
|
440
|
+
if num_agents == 1:
|
|
441
|
+
starting_positions[0] = size * (size // 2) + size // 2
|
|
442
|
+
elif num_agents == 2:
|
|
443
|
+
starting_positions[0] = size * (size // 2 - size // 4) + size // 4
|
|
444
|
+
starting_positions[1] = size * (size // 2 + size // 4) + math.ceil(3 * size / 4) - 1
|
|
445
|
+
elif num_agents == 4:
|
|
446
|
+
starting_positions[0] = size * (size // 4 + 1) + size // 4 - 1
|
|
447
|
+
starting_positions[1] = size * (size // 4 - 1) + 3 * size // 4 - 1
|
|
448
|
+
starting_positions[2] = size * (3 * size // 4 + 1) + size // 4 + 1
|
|
449
|
+
starting_positions[3] = size * (3 * size // 4 - 1) + 3 * size // 4 + 1
|
|
450
|
+
|
|
451
|
+
# clear the kore on the starting square
|
|
452
|
+
for pos in starting_positions:
|
|
453
|
+
obs.kore[pos] = 0
|
|
454
|
+
|
|
455
|
+
# Initialize the players.
|
|
456
|
+
obs.players = []
|
|
457
|
+
for i in range(num_agents):
|
|
458
|
+
shipyards = {create_uid(): [starting_positions[i], 0, 0]}
|
|
459
|
+
obs.players.append([state[0].reward, shipyards, {}])
|
|
460
|
+
|
|
461
|
+
return state
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def interpreter(state, env):
|
|
465
|
+
obs = state[0].observation
|
|
466
|
+
config = env.configuration
|
|
467
|
+
|
|
468
|
+
# Initialize the board (place cell kore and starting ships).
|
|
469
|
+
if env.done:
|
|
470
|
+
return populate_board(state, env)
|
|
471
|
+
|
|
472
|
+
# Interpreter invoked here
|
|
473
|
+
actions = [agent.action for agent in state]
|
|
474
|
+
board = Board(obs, config, actions)
|
|
475
|
+
board = board.next()
|
|
476
|
+
state[0].observation = obs = utils.structify(board.observation)
|
|
477
|
+
|
|
478
|
+
# Remove players with invalid status or insufficient potential.
|
|
479
|
+
for index, agent in enumerate(state):
|
|
480
|
+
player_kore, shipyards, fleets = obs.players[index]
|
|
481
|
+
ships_in_shipyards = [int(s[1]) for s in shipyards.values()]
|
|
482
|
+
can_spawn = len(shipyards) > 0 and player_kore >= config.spawnCost
|
|
483
|
+
if agent.status == "ACTIVE" and len(shipyards) == 0 and len(fleets) == 0:
|
|
484
|
+
# Agent can no longer gather any kore
|
|
485
|
+
agent.status = "DONE"
|
|
486
|
+
agent.reward = board.step - board.configuration.episode_steps - 1
|
|
487
|
+
if agent.status == "ACTIVE" and ships_in_shipyards == 0 and len(fleets) == 0 and not can_spawn:
|
|
488
|
+
# Agent can no longer gather any kore
|
|
489
|
+
agent.status = "DONE"
|
|
490
|
+
agent.reward = board.step - board.configuration.episode_steps - 1
|
|
491
|
+
if agent.status != "ACTIVE" and agent.status != "DONE":
|
|
492
|
+
obs.players[index] = [0, {}, {}]
|
|
493
|
+
|
|
494
|
+
# Check if done (< 2 players and num_agents > 1)
|
|
495
|
+
if len(state) > 1 and sum(1 for agent in state if agent.status == "ACTIVE") < 2:
|
|
496
|
+
for agent in state:
|
|
497
|
+
if agent.status == "ACTIVE":
|
|
498
|
+
agent.status = "DONE"
|
|
499
|
+
|
|
500
|
+
# Update Rewards.
|
|
501
|
+
for index, agent in enumerate(state):
|
|
502
|
+
if agent.status == "ACTIVE":
|
|
503
|
+
agent.reward = obs.players[index][0]
|
|
504
|
+
elif agent.status != "DONE":
|
|
505
|
+
agent.reward = 0
|
|
506
|
+
|
|
507
|
+
return state
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def renderer(state, env):
|
|
511
|
+
config = env.configuration
|
|
512
|
+
size = config.size
|
|
513
|
+
obs = state[0].observation
|
|
514
|
+
|
|
515
|
+
board = [[h, -1, -1, -1] for h in obs.kore]
|
|
516
|
+
for index, player in enumerate(obs.players):
|
|
517
|
+
_, shipyards, fleets = player
|
|
518
|
+
for shipyard in shipyards.values():
|
|
519
|
+
shipyard_pos, _, _ = shipyard
|
|
520
|
+
board[shipyard_pos][1] = index
|
|
521
|
+
for fleet in fleets.values():
|
|
522
|
+
fleet_pos, fleet_kore, ship_count, _, _ = fleet
|
|
523
|
+
board[fleet_pos][2] = index
|
|
524
|
+
board[fleet_pos][3] = ship_count
|
|
525
|
+
|
|
526
|
+
col_divider = "|"
|
|
527
|
+
row_divider = "+" + "+".join(["----"] * size) + "+\n"
|
|
528
|
+
|
|
529
|
+
out = row_divider
|
|
530
|
+
for row in range(size):
|
|
531
|
+
for col in range(size):
|
|
532
|
+
_, _, fleet, fleet_kore = board[col + row * size]
|
|
533
|
+
out += col_divider + (f"{min(int(fleet_kore), 99)}S{fleet}" if fleet > -1 else "").ljust(4)
|
|
534
|
+
out += col_divider + "\n"
|
|
535
|
+
for col in range(size):
|
|
536
|
+
kore, shipyard, _, _ = board[col + row * size]
|
|
537
|
+
if shipyard > -1:
|
|
538
|
+
out += col_divider + f"SY{shipyard}".ljust(4)
|
|
539
|
+
else:
|
|
540
|
+
out += col_divider + str(min(int(kore), 9999)).rjust(4)
|
|
541
|
+
out += col_divider + "\n" + row_divider
|
|
542
|
+
|
|
543
|
+
return out
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
dir_path = path.dirname(__file__)
|
|
547
|
+
json_path = path.abspath(path.join(dir_path, "kore_fleets.json"))
|
|
548
|
+
with open(json_path) as json_file:
|
|
549
|
+
specification = json.load(json_file)
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def html_renderer():
|
|
553
|
+
js_path = path.abspath(path.join(dir_path, "kore_fleets.js"))
|
|
554
|
+
with open(js_path, encoding="utf-8") as js_file:
|
|
555
|
+
return js_file.read()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import java.util.Scanner;
|
|
2
|
+
import java.util.Map.Entry;
|
|
3
|
+
|
|
4
|
+
import kore.*;
|
|
5
|
+
|
|
6
|
+
public class Bot {
|
|
7
|
+
private final static Scanner scanner = new Scanner(System.in);
|
|
8
|
+
public static void main(final String[] args) throws Exception {
|
|
9
|
+
while (true) {
|
|
10
|
+
/** Do not edit! **/
|
|
11
|
+
String rawObservation = scanner.nextLine();
|
|
12
|
+
String rawConfiguration = scanner.nextLine();
|
|
13
|
+
Board board = new Board(rawObservation, rawConfiguration);
|
|
14
|
+
/** end do not edit */
|
|
15
|
+
|
|
16
|
+
Player me = board.currentPlayer();
|
|
17
|
+
int turn = board.step;
|
|
18
|
+
int spawnCost = board.configuration.spawnCost;
|
|
19
|
+
double koreLeft = me.kore;
|
|
20
|
+
|
|
21
|
+
for (Shipyard shipyard : me.shipyards()) {
|
|
22
|
+
if (shipyard.shipCount > 10) {
|
|
23
|
+
Direction dir = Direction.fromIndex(turn % 4);
|
|
24
|
+
ShipyardAction action = ShipyardAction.launchFleetWithFlightPlan(2, dir.toChar());
|
|
25
|
+
shipyard.setNextAction(action);
|
|
26
|
+
} else if (koreLeft > spawnCost * shipyard.maxSpawn()) {
|
|
27
|
+
ShipyardAction action = ShipyardAction.spawnShips(shipyard.maxSpawn());
|
|
28
|
+
shipyard.setNextAction(action);
|
|
29
|
+
koreLeft -= spawnCost * shipyard.maxSpawn();
|
|
30
|
+
} else if (koreLeft > spawnCost) {
|
|
31
|
+
ShipyardAction action = ShipyardAction.spawnShips(1);
|
|
32
|
+
shipyard.setNextAction(action);
|
|
33
|
+
koreLeft -= spawnCost;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** AI Code Goes Above! **/
|
|
38
|
+
|
|
39
|
+
/** Do not edit! **/
|
|
40
|
+
StringBuilder commandBuilder = new StringBuilder("");
|
|
41
|
+
boolean first = true;
|
|
42
|
+
for (Entry<String, ShipyardAction> entry : board.currentPlayer().nextActions().entrySet()) {
|
|
43
|
+
if (first) {
|
|
44
|
+
first = false;
|
|
45
|
+
} else {
|
|
46
|
+
commandBuilder.append(",");
|
|
47
|
+
}
|
|
48
|
+
commandBuilder.append(String.format("%s:%s", entry.getKey(), entry.getValue().toString()));
|
|
49
|
+
}
|
|
50
|
+
System.out.println(commandBuilder.toString());
|
|
51
|
+
System.out.flush();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Kore Fleets Java Bot
|
|
2
|
+
|
|
3
|
+
## Running locally
|
|
4
|
+
|
|
5
|
+
1. compile your bot with `javac Bot.java`
|
|
6
|
+
2. run a match with `kaggle-environments run --environment kore_fleets --agents ./main.py ./main.py`
|
|
7
|
+
|
|
8
|
+
* where `./main.py` is the relative path from your current working directory to your bot's `main.py` file
|
|
9
|
+
* 1, 2, or 4 agents are supported
|
|
10
|
+
## Watching a replay locally
|
|
11
|
+
1. compile your bot with `javac Bot.java`
|
|
12
|
+
2. run a match with `kaggle-environments run --environment kore_fleets --agents ./main.py ./main.py --log out.log --out replay.html --render '{"mode": "html"}'`
|
|
13
|
+
3. open `replay.html` with your browser of choice!
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Creating a submission
|
|
17
|
+
|
|
18
|
+
1. compile your both with `javac Bot.java`
|
|
19
|
+
2. create a tar.gz with `tar --exclude='test' --exclude='jars' -czvf submission.tar.gz *`
|
|
20
|
+
|
|
21
|
+
note you must do this in the same directory as `main.py`!
|
|
22
|
+
|
|
23
|
+
## Running tests
|
|
24
|
+
|
|
25
|
+
1. Add the jars/ to visual studio as described [here](https://stackoverflow.com/questions/50232557/visual-studio-code-java-extension-howto-add-jar-to-classpath)
|
|
26
|
+
2. Run tests!
|