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,518 @@
|
|
|
1
|
+
package kore;
|
|
2
|
+
|
|
3
|
+
import java.util.ArrayList;
|
|
4
|
+
import java.util.Arrays;
|
|
5
|
+
import java.util.HashMap;
|
|
6
|
+
import java.util.List;
|
|
7
|
+
import java.util.Optional;
|
|
8
|
+
import java.util.Map.Entry;
|
|
9
|
+
|
|
10
|
+
public class Board {
|
|
11
|
+
|
|
12
|
+
public final HashMap<String, Shipyard> shipyards;
|
|
13
|
+
public final HashMap<String, Fleet> fleets;
|
|
14
|
+
public final Player[] players;
|
|
15
|
+
public final int currentPlayerId;
|
|
16
|
+
public final Configuration configuration;
|
|
17
|
+
public int step;
|
|
18
|
+
public final double remainingOverageTime;
|
|
19
|
+
public final Cell[] cells;
|
|
20
|
+
public final int size;
|
|
21
|
+
|
|
22
|
+
private int uidCounter;
|
|
23
|
+
|
|
24
|
+
public Board(HashMap<String, Shipyard> shipyards, HashMap<String, Fleet> fleets, Player[] players, int currentPlayerId, Configuration configuration, int step, double remainingOverageTime, Cell[] cells, int size) {
|
|
25
|
+
this.shipyards = new HashMap<>();
|
|
26
|
+
shipyards.entrySet().stream().forEach(entry -> this.shipyards.put(entry.getKey(), entry.getValue().cloneToBoard(this)));
|
|
27
|
+
this.fleets = new HashMap<>();
|
|
28
|
+
fleets.entrySet().stream().forEach(entry -> this.fleets.put(entry.getKey(), entry.getValue().cloneToBoard(this)));
|
|
29
|
+
this.players = Arrays.stream(players).map(player -> player.cloneToBoard(this)).toArray(Player[]::new);
|
|
30
|
+
this.currentPlayerId = currentPlayerId;
|
|
31
|
+
this.configuration = configuration;
|
|
32
|
+
this.step = step;
|
|
33
|
+
this.remainingOverageTime = remainingOverageTime;
|
|
34
|
+
this.cells = Arrays.stream(cells).map(cell -> cell.cloneToBoard(this)).toArray(Cell[]::new);
|
|
35
|
+
this.size = size;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public Board cloneBoard() {
|
|
39
|
+
return new Board(this.shipyards, this.fleets, this.players, this.currentPlayerId, this.configuration, this.step, this.remainingOverageTime, this.cells, this.size);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a board from the provided observation, configuration, and nextActions as specified by
|
|
44
|
+
* https://github.com/Kaggle/kaggle-environments/blob/master/kaggle_environments/envs/kore/kore.json
|
|
45
|
+
* Board tracks players (by id), fleets (by id), shipyards (by id), and cells (by position).
|
|
46
|
+
* Each entity contains both key values (e.g. fleet.player_id) as well as entity references (e.g. fleet.player).
|
|
47
|
+
* References are deep and chainable e.g.
|
|
48
|
+
* [fleet.kore for player in board.players for fleet in player.fleets]
|
|
49
|
+
* fleet.player.shipyards()[0].cell.north.east.fleet
|
|
50
|
+
* Consumers should not set or modify any attributes except and Shipyard.nextAction
|
|
51
|
+
*/
|
|
52
|
+
public Board(
|
|
53
|
+
String rawObservation,
|
|
54
|
+
String rawConfiguration
|
|
55
|
+
) {
|
|
56
|
+
Observation observation = new Observation(rawObservation);
|
|
57
|
+
|
|
58
|
+
this.step = observation.step;
|
|
59
|
+
this.remainingOverageTime = observation.remainingOverageTime;
|
|
60
|
+
this.configuration = new Configuration(rawConfiguration);
|
|
61
|
+
this.currentPlayerId = observation.player;
|
|
62
|
+
this.players = new Player[observation.playerHlt.length];
|
|
63
|
+
this.fleets = new HashMap<String, Fleet>();
|
|
64
|
+
this.shipyards = new HashMap<String, Shipyard>();
|
|
65
|
+
this.cells = new Cell[observation.kore.length];
|
|
66
|
+
this.size = this.configuration.size;
|
|
67
|
+
|
|
68
|
+
// Create a cell for every point in a size x size grid
|
|
69
|
+
for (int x = 0; x < size; x++) {
|
|
70
|
+
for (int y = 0; y < size; y++) {
|
|
71
|
+
Point position = new Point(x, y);
|
|
72
|
+
double kore = observation.kore[position.toIndex(size)];
|
|
73
|
+
// We'll populate the cell's fleets and shipyards in _add_fleet and addShipyard
|
|
74
|
+
this.cells[position.toIndex(size)] = new Cell(position, kore, "", "", this);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (int playerId = 0; playerId < observation.playerHlt.length; playerId++) {
|
|
80
|
+
double playerKore = observation.playerHlt[playerId];
|
|
81
|
+
HashMap<String, int[]> playerShipyards = observation.playerShipyards.get(playerId);
|
|
82
|
+
HashMap<String, String[]> playerFleets = observation.playerFleets.get(playerId);
|
|
83
|
+
this.players[playerId] = new Player(playerId, playerKore, new ArrayList<String>(), new ArrayList<String>(), this);
|
|
84
|
+
//player_actions = nextActions[player_id] or {}
|
|
85
|
+
|
|
86
|
+
for (Entry<String, String[]> entry : playerFleets.entrySet()) {
|
|
87
|
+
String fleetId = entry.getKey();
|
|
88
|
+
String[] fleetStrs = entry.getValue();
|
|
89
|
+
|
|
90
|
+
int fleetPosIdx = Integer.parseInt(fleetStrs[0]);
|
|
91
|
+
float fleetKore = Float.parseFloat(fleetStrs[1]);
|
|
92
|
+
int shipCount = Integer.parseInt(fleetStrs[2]);
|
|
93
|
+
int directionIdx = Integer.parseInt(fleetStrs[3]);
|
|
94
|
+
String flightPlan = fleetStrs[4];
|
|
95
|
+
|
|
96
|
+
Point fleetPosition = Point.fromIndex(fleetPosIdx, this.size);
|
|
97
|
+
Direction fleetDirection = Direction.fromIndex(directionIdx);
|
|
98
|
+
this.addFleet(new Fleet(fleetId, shipCount, fleetDirection, fleetPosition, fleetKore, flightPlan, playerId, this));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (Entry<String, int[]> entry : playerShipyards.entrySet()) {
|
|
102
|
+
String shipyardId = entry.getKey();
|
|
103
|
+
int[] shipyardInts = entry.getValue();
|
|
104
|
+
int shipyardPosIdx = shipyardInts[0];
|
|
105
|
+
int shipCount = shipyardInts[1];
|
|
106
|
+
int turnsControlled = shipyardInts[2];
|
|
107
|
+
Point shipyardPosition = Point.fromIndex(shipyardPosIdx, this.size);
|
|
108
|
+
Optional<ShipyardAction> action = Optional.empty();
|
|
109
|
+
this.addShipyard(new Shipyard(shipyardId, shipCount, shipyardPosition, playerId, turnsControlled, this, action));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public Cell getCellAtPosition(Point position) {
|
|
115
|
+
return this.cells[position.toIndex(this.size)];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public void addFleet(Fleet fleet) {
|
|
119
|
+
fleet.player().fleetIds.add(fleet.id);
|
|
120
|
+
fleet.cell().fleetId = fleet.id;
|
|
121
|
+
this.fleets.put(fleet.id, fleet);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public void addShipyard(Shipyard shipyard) {
|
|
125
|
+
shipyard.player().shipyardIds.add(shipyard.id);
|
|
126
|
+
shipyard.cell().shipyardId = shipyard.id;
|
|
127
|
+
shipyard.cell().kore = 0;
|
|
128
|
+
this.shipyards.put(shipyard.id, shipyard);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public void deleteFleet(Fleet fleet) {
|
|
132
|
+
fleet.player().fleetIds.remove(fleet.id);
|
|
133
|
+
if (fleet.cell().fleetId == fleet.id) {
|
|
134
|
+
fleet.cell().fleetId = "";
|
|
135
|
+
}
|
|
136
|
+
this.fleets.remove(fleet.id);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public void deleteShipyard(Shipyard shipyard) {
|
|
140
|
+
shipyard.player().shipyardIds.remove(shipyard.id);
|
|
141
|
+
if (shipyard.cell().shipyardId == shipyard.id) {
|
|
142
|
+
shipyard.cell().shipyardId = "";
|
|
143
|
+
}
|
|
144
|
+
this.shipyards.remove(shipyard.id);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public Optional<Fleet> getFleetAtPoint(Point position) {
|
|
148
|
+
return this.fleets.values().stream().filter(fleet -> fleet.position.equals(position)).findAny();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public Optional<Shipyard> getShipyardAtPoint(Point position) {
|
|
152
|
+
return this.shipyards.values().stream().filter(shipyard -> shipyard.position.equals(position)).findAny();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Returns the current player (generally this is you).
|
|
157
|
+
* @return
|
|
158
|
+
*/
|
|
159
|
+
public Player currentPlayer() {
|
|
160
|
+
return this.players[this.currentPlayerId];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Returns all players that aren't the current player.
|
|
165
|
+
* You can get all opponent fleets with [fleet for fleet in player.fleets for player in board.opponents]
|
|
166
|
+
*/
|
|
167
|
+
public Player[] opponents() {
|
|
168
|
+
return Arrays.stream(this.players).filter(player -> player.id != this.currentPlayerId).toArray(Player[]::new);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private String createUid() {
|
|
172
|
+
String uid = String.format("%d-%d", this.step + 1, this.uidCounter);
|
|
173
|
+
this.uidCounter += 1;
|
|
174
|
+
return uid;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private boolean isValidFlightPlan(String flightPlan) {
|
|
178
|
+
String allowed = "NESWC0123456789";
|
|
179
|
+
for (int i = 0; i < allowed.length(); i++) {
|
|
180
|
+
String c = allowed.substring(i, i +1);
|
|
181
|
+
if (allowed.indexOf(c) == -1) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private int findFirstNonDigit(String candidateStr) {
|
|
189
|
+
if (candidateStr.length() == 0) return 0;
|
|
190
|
+
for (int i = 0; i < candidateStr.length(); i++) {
|
|
191
|
+
if (!Character.isDigit(candidateStr.charAt(i))) {
|
|
192
|
+
return i;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return candidateStr.length() + 1;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private String combineFleets(Board board, String fid1, String fid2) {
|
|
199
|
+
Fleet f1 = board.fleets.get(fid1);
|
|
200
|
+
Fleet f2 = board.fleets.get(fid2);
|
|
201
|
+
if (f1.lessThanOtherAlliedFleet(f2)) {
|
|
202
|
+
Fleet temp = f1;
|
|
203
|
+
f1 = f2;
|
|
204
|
+
f2 = temp;
|
|
205
|
+
String tempS = fid1;
|
|
206
|
+
fid1 = fid2;
|
|
207
|
+
fid2 = tempS;
|
|
208
|
+
}
|
|
209
|
+
f1.kore += f2.kore;
|
|
210
|
+
f1.shipCount += f2.shipCount;
|
|
211
|
+
board.deleteFleet(f2);
|
|
212
|
+
return fid1;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Accepts the list of fleets at a particular position (must not be empty).
|
|
217
|
+
* Returns the fleet with the most ships or None in the case of a tie along with all other fleets.
|
|
218
|
+
*/
|
|
219
|
+
public Pair<Optional<Fleet>, Fleet[]> resolveCollision(List<Fleet> fleets) {
|
|
220
|
+
if (fleets.size() == 1) {
|
|
221
|
+
return new Pair<Optional<Fleet>, Fleet[]>(Optional.of(fleets.get(0)), new Fleet[0]);
|
|
222
|
+
}
|
|
223
|
+
HashMap<Integer, List<Fleet>> fleetsByShips = new HashMap<Integer, List<Fleet>>();
|
|
224
|
+
for (Fleet fleet : fleets) {
|
|
225
|
+
int ships = fleet.shipCount;
|
|
226
|
+
if (!fleetsByShips.containsKey(ships)) {
|
|
227
|
+
fleetsByShips.put(ships, new ArrayList<Fleet>());
|
|
228
|
+
}
|
|
229
|
+
fleetsByShips.get(ships).add(fleet);
|
|
230
|
+
}
|
|
231
|
+
int mostShips = fleetsByShips.keySet().stream().max((a, b) -> a > b ? 1 : -1).get();
|
|
232
|
+
List<Fleet> largestFleets = fleetsByShips.get(mostShips);
|
|
233
|
+
if (largestFleets.size() == 1) {
|
|
234
|
+
// There was a winner, return it
|
|
235
|
+
Fleet winner = largestFleets.get(0);
|
|
236
|
+
return new Pair<Optional<Fleet>, Fleet[]>(Optional.of(winner), fleets.stream().filter(f -> !f.id.equals(winner.id)).toArray(Fleet[]::new));
|
|
237
|
+
}
|
|
238
|
+
// There was a tie for most ships, all are deleted
|
|
239
|
+
return new Pair<Optional<Fleet>, Fleet[]>(Optional.empty(), fleets.stream().toArray(Fleet[]::new));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Returns a new board with the current board's next actions applied.
|
|
245
|
+
* The current board is unmodified.
|
|
246
|
+
* This can form a kore interpreter, e.g.
|
|
247
|
+
* next_observation = Board(current_observation, configuration, actions).next().observation
|
|
248
|
+
*/
|
|
249
|
+
public Board next() {
|
|
250
|
+
// Create a copy of the board to modify so we don't affect the current board
|
|
251
|
+
Board board = this.cloneBoard();
|
|
252
|
+
Configuration configuration = board.configuration;
|
|
253
|
+
int converstCost = configuration.convertCost;
|
|
254
|
+
int spawnCost = configuration.spawnCost;
|
|
255
|
+
this.uidCounter = 0;
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
// Process actions and store the results in the fleets and shipyards lists for collision checking
|
|
259
|
+
for (Player player : board.players) {
|
|
260
|
+
for (Shipyard shipyard : player.shipyards()) {
|
|
261
|
+
if (shipyard.nextAction.isEmpty()) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
ShipyardAction nextAction = shipyard.nextAction.get();
|
|
265
|
+
|
|
266
|
+
if (nextAction.shipCount == 0) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (nextAction.actionType.equals(ShipyardAction.SPAWN) && player.kore >= spawnCost * nextAction.shipCount && nextAction.shipCount <= shipyard.maxSpawn()) {
|
|
271
|
+
player.kore -= spawnCost * nextAction.shipCount;
|
|
272
|
+
shipyard.shipCount += nextAction.shipCount;
|
|
273
|
+
} else if (nextAction.actionType.equals(ShipyardAction.LAUNCH) && shipyard.shipCount >= nextAction.shipCount) {
|
|
274
|
+
String flightPlan = nextAction.flightPlan;
|
|
275
|
+
if (flightPlan.length() == 0 || !isValidFlightPlan(flightPlan)) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
shipyard.shipCount -= nextAction.shipCount;
|
|
279
|
+
Direction direction = Direction.fromChar(flightPlan.charAt(0));
|
|
280
|
+
int maxFlightPlanLen = Fleet.maxFlightPlanLenForShipCount(nextAction.shipCount);
|
|
281
|
+
if (flightPlan.length() > maxFlightPlanLen) {
|
|
282
|
+
flightPlan = flightPlan.substring(0, maxFlightPlanLen);
|
|
283
|
+
}
|
|
284
|
+
board.addFleet(new Fleet(this.createUid(), nextAction.shipCount, direction, shipyard.position, 0, flightPlan, player.id, board));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
shipyard.nextAction = Optional.empty();
|
|
288
|
+
}
|
|
289
|
+
for (Shipyard shipyard : player.shipyards()) {
|
|
290
|
+
shipyard.nextAction = Optional.empty();
|
|
291
|
+
shipyard.turnsControlled += 1;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
for (Fleet fleet : player.fleets()) {
|
|
296
|
+
// remove any errant 0s
|
|
297
|
+
while (fleet.flightPlan.length() > 0 && fleet.flightPlan.startsWith("0") ) {
|
|
298
|
+
fleet.flightPlan = fleet.flightPlan.substring(1);
|
|
299
|
+
}
|
|
300
|
+
if (fleet.flightPlan.length() > 0 && fleet.flightPlan.startsWith("C") && fleet.shipCount >= converstCost && fleet.cell().shipyardId.length() == 0) {
|
|
301
|
+
player.kore += fleet.kore;
|
|
302
|
+
fleet.cell().kore = 0;
|
|
303
|
+
board.addShipyard(new Shipyard(this.createUid(), fleet.shipCount - converstCost, fleet.position, player.id, 0, board, Optional.empty()));
|
|
304
|
+
board.deleteFleet(fleet);
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
while (fleet.flightPlan.length() > 0 && fleet.flightPlan.startsWith("C")) {
|
|
308
|
+
// couldn't build, remove the Convert and continue with flight plan
|
|
309
|
+
fleet.flightPlan = fleet.flightPlan.substring(1);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (fleet.flightPlan.length() > 0 && Character.isLetter(fleet.flightPlan.charAt(0))) {
|
|
313
|
+
fleet.direction = Direction.fromChar(fleet.flightPlan.charAt(0));
|
|
314
|
+
fleet.flightPlan = fleet.flightPlan.substring(1);
|
|
315
|
+
} else if (fleet.flightPlan.length() > 0) {
|
|
316
|
+
int idx = this.findFirstNonDigit(fleet.flightPlan);
|
|
317
|
+
int digits = Integer.parseInt(fleet.flightPlan.substring(0, idx));
|
|
318
|
+
String rest = fleet.flightPlan.substring(idx);
|
|
319
|
+
digits -= 1;
|
|
320
|
+
if (digits > 0) {
|
|
321
|
+
fleet.flightPlan = String.valueOf(digits) + rest;
|
|
322
|
+
} else {
|
|
323
|
+
fleet.flightPlan = rest;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// continue moving in the fleet's direction
|
|
328
|
+
fleet.cell().fleetId = "";
|
|
329
|
+
fleet.position = fleet.position.translate(fleet.direction, configuration.size);
|
|
330
|
+
// We don't set the new cell's fleet_id here as it would be overwritten by another fleet in the case of collision.
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
HashMap<Integer, List<Fleet>> fleetsByLoc = new HashMap<Integer, List<Fleet>>();
|
|
334
|
+
for (Fleet fleet : player.fleets()) {
|
|
335
|
+
int locIdx = fleet.position.toIndex(configuration.size);
|
|
336
|
+
if (!fleetsByLoc.containsKey(locIdx)) {
|
|
337
|
+
fleetsByLoc.put(locIdx, new ArrayList<Fleet>());
|
|
338
|
+
}
|
|
339
|
+
fleetsByLoc.get(locIdx).add(fleet);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
for (List<Fleet> fleets : fleetsByLoc.values()) {
|
|
343
|
+
fleets.sort((a, b) -> {
|
|
344
|
+
if (a.shipCount != b.shipCount) {
|
|
345
|
+
return a.shipCount > b.shipCount ? -1 : 1;
|
|
346
|
+
}
|
|
347
|
+
if (a.kore != b.kore) {
|
|
348
|
+
return a.kore > b.kore ? -1 : 1;
|
|
349
|
+
}
|
|
350
|
+
return a.direction.toIndex() > a.direction.toIndex() ? 1 : -1;
|
|
351
|
+
});
|
|
352
|
+
String fid = fleets.get(0).id;
|
|
353
|
+
for (int i = 1; i < fleets.size(); i++) {
|
|
354
|
+
fid = this.combineFleets(board, fid, fleets.get(i).id);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Lets just check and make sure.
|
|
360
|
+
assert player.kore >= 0 : "Player should have non-negative kore";
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
// Check for fleet to fleet collisions
|
|
365
|
+
HashMap<Integer, List<Fleet>> fleetCollisionGroups = new HashMap<Integer, List<Fleet>>();
|
|
366
|
+
for (Fleet fleet : board.fleets.values()) {
|
|
367
|
+
int posIdx = fleet.position.toIndex(board.size);
|
|
368
|
+
if (!fleetCollisionGroups.containsKey(posIdx)) {
|
|
369
|
+
fleetCollisionGroups.put((Integer)posIdx, (List<Fleet>)new ArrayList<Fleet>());
|
|
370
|
+
}
|
|
371
|
+
fleetCollisionGroups.get(posIdx).add(fleet);
|
|
372
|
+
}
|
|
373
|
+
for (Entry<Integer, List<Fleet>> entry : fleetCollisionGroups.entrySet()) {
|
|
374
|
+
Point position = Point.fromIndex(entry.getKey(), configuration.size);
|
|
375
|
+
List<Fleet> collidedFleets = entry.getValue();
|
|
376
|
+
Pair<Optional<Fleet>, Fleet[]> pair = this.resolveCollision(collidedFleets);
|
|
377
|
+
Optional<Fleet> winnerOptional = pair.first;
|
|
378
|
+
Fleet[] deleted = pair.second;
|
|
379
|
+
Optional<Shipyard> shipyardOpt = board.getShipyardAtPoint(position);
|
|
380
|
+
if (winnerOptional.isPresent()) {
|
|
381
|
+
Fleet winner = winnerOptional.get();
|
|
382
|
+
winner.cell().fleetId = winner.id;
|
|
383
|
+
int maxEnemySize = deleted.length > 0 ? Arrays.stream(deleted).map(f -> f.shipCount).max((a, b) -> a > b ? 1: -1).get() : 0;
|
|
384
|
+
winner.shipCount -= maxEnemySize;
|
|
385
|
+
}
|
|
386
|
+
for (Fleet fleet : deleted) {
|
|
387
|
+
board.deleteFleet(fleet);
|
|
388
|
+
if (winnerOptional.isPresent()) {
|
|
389
|
+
// Winner takes deleted fleets' kore
|
|
390
|
+
winnerOptional.get().kore += fleet.kore;
|
|
391
|
+
} else if (winnerOptional.isEmpty() && shipyardOpt.isPresent()) {
|
|
392
|
+
// Desposit the kore into the shipyard
|
|
393
|
+
shipyardOpt.get().player().kore += fleet.kore;
|
|
394
|
+
} else if (winnerOptional.isEmpty()) {
|
|
395
|
+
// Desposit the kore on the square
|
|
396
|
+
board.getCellAtPosition(position).kore += fleet.kore;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
// Check for fleet to shipyard collisions
|
|
403
|
+
for (Shipyard shipyard : board.shipyards.values()) {
|
|
404
|
+
Optional<Fleet> optFleet = shipyard.cell().fleet();
|
|
405
|
+
if (!optFleet.isEmpty() && optFleet.get().playerId != shipyard.playerId) {
|
|
406
|
+
Fleet fleet = optFleet.get();
|
|
407
|
+
if (fleet.shipCount > shipyard.shipCount) {
|
|
408
|
+
int count = fleet.shipCount - shipyard.shipCount;
|
|
409
|
+
board.deleteShipyard(shipyard);
|
|
410
|
+
board.addShipyard(new Shipyard(this.createUid(), count, shipyard.position, fleet.player().id, 1, board, Optional.empty()));
|
|
411
|
+
fleet.player().kore += fleet.kore;
|
|
412
|
+
board.deleteFleet(fleet);
|
|
413
|
+
} else {
|
|
414
|
+
shipyard.shipCount -= fleet.shipCount;
|
|
415
|
+
shipyard.player().kore += fleet.kore;
|
|
416
|
+
board.deleteFleet(fleet);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Deposit kore from fleets into shipyards
|
|
422
|
+
for (Shipyard shipyard : board.shipyards.values()) {
|
|
423
|
+
Optional<Fleet> optFleet = shipyard.cell().fleet();
|
|
424
|
+
if (!optFleet.isEmpty() && optFleet.get().playerId == shipyard.playerId) {
|
|
425
|
+
Fleet fleet = optFleet.get();
|
|
426
|
+
shipyard.player().kore += fleet.kore;
|
|
427
|
+
shipyard.shipCount += fleet.shipCount;
|
|
428
|
+
board.deleteFleet(fleet);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// apply fleet to fleet damage on all orthagonally adjacent cells
|
|
433
|
+
HashMap<String, ArrayList<Pair<String, Integer>>> incomingFleetDmg = new HashMap<String, ArrayList<Pair<String, Integer>>>();
|
|
434
|
+
for (Fleet fleet : board.fleets.values()) {
|
|
435
|
+
for (Direction direction : Direction.listDirections()) {
|
|
436
|
+
Point currPos = fleet.position.translate(direction, board.configuration.size);
|
|
437
|
+
Optional<Fleet> optFleet = board.getFleetAtPoint(currPos);
|
|
438
|
+
if (optFleet.isPresent() && optFleet.get().playerId != fleet.playerId) {
|
|
439
|
+
Fleet f = optFleet.get();
|
|
440
|
+
if (!incomingFleetDmg.containsKey(f.id)) {
|
|
441
|
+
incomingFleetDmg.put(f.id, new ArrayList<Pair<String, Integer>>());
|
|
442
|
+
}
|
|
443
|
+
incomingFleetDmg.get(f.id).add(new Pair<String, Integer>(fleet.id, fleet.shipCount));
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// dump 1/2 kore to the cell of killed fleets
|
|
449
|
+
// mark the other 1/2 kore to go to surrounding fleets proportionally
|
|
450
|
+
HashMap<String, ArrayList<Pair<Integer, Double>>> toDistribute = new HashMap<String, ArrayList<Pair<Integer, Double>>>();
|
|
451
|
+
for(Entry<String, ArrayList<Pair<String, Integer>>> entry : incomingFleetDmg.entrySet()) {
|
|
452
|
+
String fleetId = entry.getKey();
|
|
453
|
+
ArrayList<Pair<String, Integer>> attackers = entry.getValue();
|
|
454
|
+
int totalDamage = attackers.stream().map(p -> p.second).reduce(0, Integer::sum);
|
|
455
|
+
Fleet fleet = board.fleets.get(fleetId);
|
|
456
|
+
if (totalDamage >= fleet.shipCount) {
|
|
457
|
+
fleet.cell().kore += fleet.kore / 2;
|
|
458
|
+
attackers.forEach(p -> {
|
|
459
|
+
String attackerId = p.first;
|
|
460
|
+
int attackerDmg = p.second;
|
|
461
|
+
if (!toDistribute.containsKey(attackerId)) {
|
|
462
|
+
toDistribute.put(attackerId, new ArrayList<Pair<Integer, Double>>());
|
|
463
|
+
}
|
|
464
|
+
double toGet = fleet.kore / 2 * (double)attackerDmg / (double)totalDamage;
|
|
465
|
+
toDistribute.get(attackerId).add(new Pair<Integer, Double>(fleet.cell().position.toIndex(board.configuration.size), toGet));
|
|
466
|
+
});
|
|
467
|
+
board.deleteFleet(fleet);
|
|
468
|
+
} else {
|
|
469
|
+
fleet.shipCount -= totalDamage;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// give kore claimed above to surviving fleets, otherwise add it to the kore of the tile where the fleet died
|
|
474
|
+
for(Entry<String, ArrayList<Pair<Integer, Double>>> entry : toDistribute.entrySet()) {
|
|
475
|
+
String fleetId = entry.getKey();
|
|
476
|
+
ArrayList<Pair<Integer, Double>> resoureFromLocs = entry.getValue();
|
|
477
|
+
resoureFromLocs.forEach(p -> {
|
|
478
|
+
int cellIdx = p.first;
|
|
479
|
+
double kore = p.second;
|
|
480
|
+
if (!board.fleets.containsKey(fleetId)) {
|
|
481
|
+
board.cells[cellIdx].kore += kore;
|
|
482
|
+
} else {
|
|
483
|
+
Fleet fleet = board.fleets.get(fleetId);
|
|
484
|
+
fleet.kore += kore;
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Collect kore from cells into fleets
|
|
490
|
+
for (Fleet fleet : board.fleets.values() ) {
|
|
491
|
+
Cell cell = fleet.cell();
|
|
492
|
+
double deltaKore = roundToThreePlaces(cell.kore * Math.min(fleet.collectionRate(), .99));
|
|
493
|
+
if (deltaKore > 0) {
|
|
494
|
+
fleet.kore += deltaKore;
|
|
495
|
+
cell.kore -= deltaKore;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Regenerate kore in cells
|
|
500
|
+
for (Cell cell : board.cells) {
|
|
501
|
+
if (cell.fleetId.equals("") && cell.shipyardId.equals("")) {
|
|
502
|
+
if (cell.kore < configuration.maxRegenCellKore) {
|
|
503
|
+
double nextKore = roundToThreePlaces(cell.kore * (1 + configuration.regenRate));
|
|
504
|
+
cell.kore = nextKore;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
board.step += 1;
|
|
510
|
+
|
|
511
|
+
return board;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
private static double roundToThreePlaces(double num) {
|
|
515
|
+
return Math.round(num * 1000.0) / 1000.0;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package kore;
|
|
2
|
+
|
|
3
|
+
import java.util.Optional;
|
|
4
|
+
|
|
5
|
+
public class Cell {
|
|
6
|
+
|
|
7
|
+
public final Point position;
|
|
8
|
+
public double kore;
|
|
9
|
+
public String shipyardId;
|
|
10
|
+
public String fleetId;
|
|
11
|
+
public final Board board;
|
|
12
|
+
|
|
13
|
+
public Cell(Point position, double kore, String shipyardId, String fleetId, Board board) {
|
|
14
|
+
this.position = position;
|
|
15
|
+
this.kore = kore;
|
|
16
|
+
this.shipyardId = shipyardId;
|
|
17
|
+
this.fleetId = fleetId;
|
|
18
|
+
this.board = board;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public Cell cloneToBoard(Board board) {
|
|
22
|
+
return new Cell(this.position, this.kore, this.shipyardId, this.fleetId, board);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public Optional<Fleet> fleet() {
|
|
26
|
+
if (this.board.fleets.containsKey(this.fleetId)) {
|
|
27
|
+
return Optional.of(this.board.fleets.get(this.fleetId));
|
|
28
|
+
}
|
|
29
|
+
return Optional.empty();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
public Optional<Shipyard> shipyard() {
|
|
34
|
+
if (this.board.shipyards.containsKey(this.shipyardId)) {
|
|
35
|
+
return Optional.of(this.board.shipyards.get(this.shipyardId));
|
|
36
|
+
}
|
|
37
|
+
return Optional.empty();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public Cell neighbor(Point offset) {
|
|
41
|
+
Point next = this.position.translate(offset, this.board.size);
|
|
42
|
+
return this.board.getCellAtPosition(next);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
public Cell north() {
|
|
47
|
+
return this.neighbor(Direction.NORTH);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public Cell south() {
|
|
51
|
+
return this.neighbor(((Point)Direction.SOUTH));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public Cell east() {
|
|
55
|
+
return this.neighbor(Direction.EAST);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public Cell west() {
|
|
59
|
+
return this.neighbor(Direction.WEST);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
package kore;
|
|
2
|
+
|
|
3
|
+
public class Configuration {
|
|
4
|
+
|
|
5
|
+
public final int agentTimeout;
|
|
6
|
+
public final int startingKore;
|
|
7
|
+
public final int size;
|
|
8
|
+
public final double spawnCost;
|
|
9
|
+
public final int convertCost;
|
|
10
|
+
public final double regenRate;
|
|
11
|
+
public final int maxRegenCellKore;
|
|
12
|
+
public final int randomSeed;
|
|
13
|
+
|
|
14
|
+
public Configuration(String rawConfiguration) {
|
|
15
|
+
this.agentTimeout = KoreJson.getIntFromJson(rawConfiguration, "agentTimeout");
|
|
16
|
+
this.startingKore = KoreJson.getIntFromJson(rawConfiguration, "startingKore");
|
|
17
|
+
this.size = KoreJson.getIntFromJson(rawConfiguration, "size");
|
|
18
|
+
this.spawnCost = KoreJson.getDoubleFromJson(rawConfiguration, "spawnCost");
|
|
19
|
+
this.convertCost = KoreJson.getIntFromJson(rawConfiguration, "convertCost");
|
|
20
|
+
this.regenRate = KoreJson.getDoubleFromJson(rawConfiguration, "regenRate");
|
|
21
|
+
this.maxRegenCellKore = KoreJson.getIntFromJson(rawConfiguration, "maxRegenCellKore");
|
|
22
|
+
this.randomSeed = KoreJson.getIntFromJson(rawConfiguration, "randomSeed");
|
|
23
|
+
}
|
|
24
|
+
}
|