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