kaggle-environments 0.2.1__py3-none-any.whl → 1.20.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kaggle-environments might be problematic. Click here for more details.
- kaggle_environments/__init__.py +49 -13
- kaggle_environments/agent.py +177 -124
- kaggle_environments/api.py +31 -0
- kaggle_environments/core.py +295 -170
- kaggle_environments/envs/cabt/cabt.js +164 -0
- kaggle_environments/envs/cabt/cabt.json +28 -0
- kaggle_environments/envs/cabt/cabt.py +186 -0
- kaggle_environments/envs/cabt/cg/__init__.py +0 -0
- kaggle_environments/envs/cabt/cg/cg.dll +0 -0
- kaggle_environments/envs/cabt/cg/game.py +75 -0
- kaggle_environments/envs/cabt/cg/libcg.so +0 -0
- kaggle_environments/envs/cabt/cg/sim.py +48 -0
- kaggle_environments/envs/cabt/test_cabt.py +120 -0
- kaggle_environments/envs/chess/chess.js +4289 -0
- kaggle_environments/envs/chess/chess.json +60 -0
- kaggle_environments/envs/chess/chess.py +4241 -0
- kaggle_environments/envs/chess/test_chess.py +60 -0
- kaggle_environments/envs/connectx/connectx.ipynb +3186 -0
- kaggle_environments/envs/connectx/connectx.js +1 -1
- kaggle_environments/envs/connectx/connectx.json +15 -1
- kaggle_environments/envs/connectx/connectx.py +6 -23
- kaggle_environments/envs/connectx/test_connectx.py +70 -24
- kaggle_environments/envs/football/football.ipynb +75 -0
- kaggle_environments/envs/football/football.json +91 -0
- kaggle_environments/envs/football/football.py +277 -0
- kaggle_environments/envs/football/helpers.py +95 -0
- kaggle_environments/envs/football/test_football.py +360 -0
- kaggle_environments/envs/halite/__init__.py +0 -0
- kaggle_environments/envs/halite/halite.ipynb +44741 -0
- kaggle_environments/envs/halite/halite.js +199 -83
- kaggle_environments/envs/halite/halite.json +31 -18
- kaggle_environments/envs/halite/halite.py +164 -303
- kaggle_environments/envs/halite/helpers.py +720 -0
- kaggle_environments/envs/halite/test_halite.py +190 -0
- kaggle_environments/envs/hungry_geese/__init__.py +0 -0
- kaggle_environments/envs/{battlegeese/battlegeese.js → hungry_geese/hungry_geese.js} +38 -22
- kaggle_environments/envs/{battlegeese/battlegeese.json → hungry_geese/hungry_geese.json} +21 -14
- kaggle_environments/envs/hungry_geese/hungry_geese.py +316 -0
- kaggle_environments/envs/hungry_geese/test_hungry_geese.py +0 -0
- kaggle_environments/envs/identity/identity.json +6 -5
- kaggle_environments/envs/identity/identity.py +15 -2
- kaggle_environments/envs/kore_fleets/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/helpers.py +1005 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +114 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.js +658 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.json +164 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.py +555 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/Bot.java +54 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/README.md +26 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/hamcrest-core-1.3.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/junit-4.13.2.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Board.java +518 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Cell.java +61 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Configuration.java +24 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Direction.java +166 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Fleet.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/KoreJson.java +97 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Observation.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Pair.java +13 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Player.java +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Point.java +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Shipyard.java +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/ShipyardAction.java +59 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/BoardTest.java +567 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ConfigurationTest.java +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/KoreJsonTest.java +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ObservationTest.java +46 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/PointTest.java +21 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ShipyardTest.java +22 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/main.py +27 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/Bot.ts +34 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/DoNothingBot.ts +12 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/MinerBot.ts +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/README.md +55 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/interpreter.ts +402 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Board.ts +514 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Cell.ts +63 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Configuration.ts +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Direction.ts +169 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Fleet.ts +76 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/KoreIO.ts +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Observation.ts +45 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Pair.ts +11 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Player.ts +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Point.ts +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Shipyard.ts +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/ShipyardAction.ts +58 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/miner.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/package.json +23 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/BoardTest.ts +551 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ConfigurationTest.ts +16 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ObservationTest.ts +33 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/PointTest.ts +17 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ShipyardTest.ts +18 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/tsconfig.json +22 -0
- kaggle_environments/envs/kore_fleets/test_kore_fleets.py +331 -0
- kaggle_environments/envs/lux_ai_2021/README.md +3 -0
- kaggle_environments/envs/lux_ai_2021/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/agents.py +11 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js +2 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/main.js +1 -0
- kaggle_environments/envs/lux_ai_2021/index.html +43 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.json +100 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.py +231 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.js +6 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_objects.js +145 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/io.js +14 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/kit.js +209 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/map.js +107 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/parser.js +79 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.js +88 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.py +75 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/annotate.py +20 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/constants.py +25 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game.py +86 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.py +7 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_map.py +106 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_objects.py +154 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/random_agent.py +38 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/simple_agent.py +82 -0
- kaggle_environments/envs/lux_ai_2021/test_lux.py +19 -0
- kaggle_environments/envs/lux_ai_2021/testing.md +23 -0
- kaggle_environments/envs/lux_ai_2021/todo.md.og +18 -0
- kaggle_environments/envs/lux_ai_s3/README.md +21 -0
- kaggle_environments/envs/lux_ai_s3/agents.py +5 -0
- kaggle_environments/envs/lux_ai_s3/index.html +42 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.json +47 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.py +178 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +819 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +9 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +141 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +222 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +27 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +464 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +156 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +78 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/kit.py +31 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/utils.py +17 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/main.py +66 -0
- kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
- kaggle_environments/envs/mab/__init__.py +0 -0
- kaggle_environments/envs/mab/agents.py +12 -0
- kaggle_environments/envs/mab/mab.js +100 -0
- kaggle_environments/envs/mab/mab.json +74 -0
- kaggle_environments/envs/mab/mab.py +146 -0
- kaggle_environments/envs/open_spiel/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/chess/chess.js +441 -0
- kaggle_environments/envs/open_spiel/games/chess/image_config.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/chess/openings.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/connect_four/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js +284 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py +86 -0
- kaggle_environments/envs/open_spiel/games/go/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/go/go.js +481 -0
- kaggle_environments/envs/open_spiel/games/go/go_proxy.py +99 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe.js +345 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe_proxy.py +98 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker.js +431 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker_proxy.py +159 -0
- kaggle_environments/envs/open_spiel/html_playthrough_generator.py +31 -0
- kaggle_environments/envs/open_spiel/observation.py +128 -0
- kaggle_environments/envs/open_spiel/open_spiel.py +565 -0
- kaggle_environments/envs/open_spiel/proxy.py +138 -0
- kaggle_environments/envs/open_spiel/test_open_spiel.py +191 -0
- kaggle_environments/envs/rps/__init__.py +0 -0
- kaggle_environments/envs/rps/agents.py +84 -0
- kaggle_environments/envs/rps/helpers.py +25 -0
- kaggle_environments/envs/rps/rps.js +117 -0
- kaggle_environments/envs/rps/rps.json +63 -0
- kaggle_environments/envs/rps/rps.py +90 -0
- kaggle_environments/envs/rps/test_rps.py +110 -0
- kaggle_environments/envs/rps/utils.py +7 -0
- kaggle_environments/envs/tictactoe/test_tictactoe.py +43 -77
- kaggle_environments/envs/tictactoe/tictactoe.ipynb +1397 -0
- kaggle_environments/envs/tictactoe/tictactoe.json +10 -2
- kaggle_environments/envs/tictactoe/tictactoe.py +1 -1
- kaggle_environments/errors.py +2 -4
- kaggle_environments/helpers.py +377 -0
- kaggle_environments/main.py +340 -0
- kaggle_environments/schemas.json +23 -18
- kaggle_environments/static/player.html +206 -74
- kaggle_environments/utils.py +46 -73
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/METADATA +36 -114
- kaggle_environments-1.20.1.dist-info/RECORD +211 -0
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/WHEEL +1 -2
- kaggle_environments-1.20.1.dist-info/entry_points.txt +3 -0
- kaggle_environments/envs/battlegeese/battlegeese.py +0 -223
- kaggle_environments/temp.py +0 -14
- kaggle_environments-0.2.1.dist-info/RECORD +0 -32
- kaggle_environments-0.2.1.dist-info/entry_points.txt +0 -3
- kaggle_environments-0.2.1.dist-info/top_level.txt +0 -1
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import atexit
|
|
2
|
+
import json
|
|
3
|
+
import math
|
|
4
|
+
import random
|
|
5
|
+
import sys
|
|
6
|
+
from os import path
|
|
7
|
+
from queue import Empty, Queue
|
|
8
|
+
from subprocess import PIPE, Popen
|
|
9
|
+
from threading import Thread
|
|
10
|
+
|
|
11
|
+
from .agents import agents as all_agents
|
|
12
|
+
from .test_agents.python.lux.game import Game
|
|
13
|
+
|
|
14
|
+
t = None
|
|
15
|
+
q = None
|
|
16
|
+
dimension_process = None
|
|
17
|
+
game_state = Game()
|
|
18
|
+
prev_step = 0
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def cleanup_dimensions():
|
|
22
|
+
global dimension_process
|
|
23
|
+
if dimension_process is not None:
|
|
24
|
+
dimension_process.kill()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def enqueue_output(out, queue):
|
|
28
|
+
for line in iter(out.readline, b""):
|
|
29
|
+
queue.put(line)
|
|
30
|
+
out.close()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def interpreter(state, env):
|
|
34
|
+
global dimension_process, game_state, t, q, prev_step
|
|
35
|
+
player1 = state[0]
|
|
36
|
+
player2 = state[1]
|
|
37
|
+
|
|
38
|
+
### 1.1: Initialize dimensions in the background within the orchestrator if we haven't already ###
|
|
39
|
+
if dimension_process is None:
|
|
40
|
+
# dimension_process = Popen(["ts-node", "-P", path.abspath(path.join(dir_path, "dimensions/tsconfig.json")), path.abspath(path.join(dir_path, "dimensions/run.ts"))], stdin=PIPE, stdout=PIPE)
|
|
41
|
+
try:
|
|
42
|
+
dimension_process = Popen(
|
|
43
|
+
["node", path.abspath(path.join(dir_path, "dimensions/main.js"))], stdin=PIPE, stdout=PIPE, stderr=PIPE
|
|
44
|
+
)
|
|
45
|
+
except FileNotFoundError:
|
|
46
|
+
import warnings
|
|
47
|
+
|
|
48
|
+
warnings.warn("Node not installed")
|
|
49
|
+
return state
|
|
50
|
+
|
|
51
|
+
# following 4 lines from https://stackoverflow.com/questions/375427/a-non-blocking-read-on-a-subprocess-pipe-in-python
|
|
52
|
+
q = Queue()
|
|
53
|
+
t = Thread(target=enqueue_output, args=(dimension_process.stdout, q))
|
|
54
|
+
t.daemon = True # thread dies with the program
|
|
55
|
+
t.start()
|
|
56
|
+
atexit.register(cleanup_dimensions)
|
|
57
|
+
|
|
58
|
+
# filter out actions such as debug annotations so they aren't saved
|
|
59
|
+
filter_actions(state, env)
|
|
60
|
+
|
|
61
|
+
### 1.2: Initialize a blank state game if new episode is starting ###
|
|
62
|
+
if env.done:
|
|
63
|
+
# TODO: allow resetting to a specific state
|
|
64
|
+
# print("Initialize game", "steps", len(env.steps), "prev_step", prev_step)
|
|
65
|
+
# last_state = None
|
|
66
|
+
# if prev_step >= len(env.steps):
|
|
67
|
+
# last_state = env.steps[-1]
|
|
68
|
+
# prev_step = len(env.steps)
|
|
69
|
+
# print("prev_step now", prev_step)
|
|
70
|
+
if "seed" in env.configuration:
|
|
71
|
+
seed = env.configuration["seed"]
|
|
72
|
+
else:
|
|
73
|
+
seed = math.floor(random.random() * 1e9)
|
|
74
|
+
env.configuration["seed"] = seed
|
|
75
|
+
if "loglevel" in env.configuration:
|
|
76
|
+
loglevel = env.configuration["loglevel"]
|
|
77
|
+
else:
|
|
78
|
+
loglevel = 0 # warnings, 1: errors, 0: none
|
|
79
|
+
env.configuration["loglevel"] = loglevel
|
|
80
|
+
if "annotations" in env.configuration:
|
|
81
|
+
annotations = env.configuration["annotations"]
|
|
82
|
+
else:
|
|
83
|
+
annotations = False # warnings, 1: errors, 0: none
|
|
84
|
+
env.configuration["annotations"] = annotations
|
|
85
|
+
|
|
86
|
+
if "width" in env.configuration:
|
|
87
|
+
width = env.configuration["width"]
|
|
88
|
+
else:
|
|
89
|
+
width = -1 # -1 for randomly selected
|
|
90
|
+
env.configuration["width"] = width
|
|
91
|
+
if "height" in env.configuration:
|
|
92
|
+
height = env.configuration["height"]
|
|
93
|
+
else:
|
|
94
|
+
height = -1 # -1 for randomly selected
|
|
95
|
+
env.configuration["height"] = height
|
|
96
|
+
|
|
97
|
+
initiate = {
|
|
98
|
+
"type": "start",
|
|
99
|
+
"agent_names": [], # unsure if this is provided?
|
|
100
|
+
"config": env.configuration,
|
|
101
|
+
}
|
|
102
|
+
# if last_state is not None:
|
|
103
|
+
# initiate["state"] = last_state
|
|
104
|
+
dimension_process.stdin.write((json.dumps(initiate) + "\n").encode())
|
|
105
|
+
dimension_process.stdin.flush()
|
|
106
|
+
|
|
107
|
+
agent1res = get_message(dimension_process)
|
|
108
|
+
agent2res = get_message(dimension_process)
|
|
109
|
+
match_obs_meta = get_message(dimension_process)
|
|
110
|
+
|
|
111
|
+
player1.observation.player = 0
|
|
112
|
+
player2.observation.player = 1
|
|
113
|
+
player1.observation.updates = agent1res
|
|
114
|
+
|
|
115
|
+
# player2.observation.updates = agent2res # duplicated and not added
|
|
116
|
+
player1.observation.globalCityIDCount = match_obs_meta["globalCityIDCount"]
|
|
117
|
+
player1.observation.globalUnitIDCount = match_obs_meta["globalUnitIDCount"]
|
|
118
|
+
player1.observation.width = match_obs_meta["width"]
|
|
119
|
+
player1.observation.height = match_obs_meta["height"]
|
|
120
|
+
|
|
121
|
+
game_state = Game()
|
|
122
|
+
game_state._initialize(agent1res)
|
|
123
|
+
|
|
124
|
+
return state
|
|
125
|
+
# print("prev_step", prev_step, "stored steps", len(env.steps))
|
|
126
|
+
# prev_step += 1
|
|
127
|
+
|
|
128
|
+
### 2. : Pass in actions (json representation along with id of who made that action), agent information (id, status) to dimensions via stdin
|
|
129
|
+
dimension_process.stdin.write((json.dumps(state) + "\n").encode())
|
|
130
|
+
dimension_process.stdin.flush()
|
|
131
|
+
|
|
132
|
+
### 3.1 : Receive and parse the observations returned by dimensions via stdout
|
|
133
|
+
agent1res = json.loads(dimension_process.stderr.readline())
|
|
134
|
+
agent2res = json.loads(dimension_process.stderr.readline())
|
|
135
|
+
game_state._update(agent1res)
|
|
136
|
+
|
|
137
|
+
# receive meta info such as global ID and map sizes for purposes of being able to start from specific state
|
|
138
|
+
match_obs_meta = json.loads(dimension_process.stderr.readline())
|
|
139
|
+
match_status = json.loads(dimension_process.stderr.readline())
|
|
140
|
+
|
|
141
|
+
while True:
|
|
142
|
+
try:
|
|
143
|
+
line = q.get_nowait()
|
|
144
|
+
except Empty:
|
|
145
|
+
# no standard error received, break
|
|
146
|
+
break
|
|
147
|
+
else:
|
|
148
|
+
# standard error output received, print it out
|
|
149
|
+
print(line.decode(), file=sys.stderr, end="")
|
|
150
|
+
|
|
151
|
+
### 3.2 : Send observations to each agent through here. Like dimensions, first observation can include initialization stuff, then we do the looping
|
|
152
|
+
|
|
153
|
+
player1.observation.updates = agent1res
|
|
154
|
+
|
|
155
|
+
player1.observation.globalCityIDCount = match_obs_meta["globalCityIDCount"]
|
|
156
|
+
player1.observation.globalUnitIDCount = match_obs_meta["globalUnitIDCount"]
|
|
157
|
+
player1.observation.width = match_obs_meta["width"]
|
|
158
|
+
player1.observation.height = match_obs_meta["height"]
|
|
159
|
+
# player2.observation.updates = agent2res # duplicated and not added
|
|
160
|
+
|
|
161
|
+
player1.observation.player = 0
|
|
162
|
+
player2.observation.player = 1
|
|
163
|
+
|
|
164
|
+
### 3.3 : handle rewards
|
|
165
|
+
# reward here is defined as the sum of number of city tiles
|
|
166
|
+
player1.reward = compute_reward(game_state.players[0])
|
|
167
|
+
player2.reward = compute_reward(game_state.players[1])
|
|
168
|
+
player1.observation.reward = int(player1.reward)
|
|
169
|
+
player2.observation.reward = int(player2.reward)
|
|
170
|
+
|
|
171
|
+
### 3.4 Handle finished match status
|
|
172
|
+
if match_status["status"] == "finished":
|
|
173
|
+
if player1.status == "ACTIVE":
|
|
174
|
+
player1.status = "DONE"
|
|
175
|
+
if player2.status == "ACTIVE":
|
|
176
|
+
player2.status = "DONE"
|
|
177
|
+
return state
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def get_message(dimension_process):
|
|
181
|
+
raw = dimension_process.stderr.readline()
|
|
182
|
+
try:
|
|
183
|
+
res = json.loads(raw)
|
|
184
|
+
return res
|
|
185
|
+
except Exception:
|
|
186
|
+
print("Engine Exception")
|
|
187
|
+
err_stack = dimension_process.stderr.readlines(100)
|
|
188
|
+
# err_stack = [raw, *err_stack]
|
|
189
|
+
# print(err_stack)
|
|
190
|
+
for m in err_stack:
|
|
191
|
+
if len(m) < 1000:
|
|
192
|
+
print(m.decode(), file=sys.stderr)
|
|
193
|
+
else:
|
|
194
|
+
print("...", file=sys.stderr)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def filter_actions(state, env):
|
|
198
|
+
enable_annotations = env.configuration["annotations"]
|
|
199
|
+
if not enable_annotations:
|
|
200
|
+
for team in range(len(state)):
|
|
201
|
+
filtered = []
|
|
202
|
+
if state[team] is not None and state[team].action is not None:
|
|
203
|
+
for l in state[team].action:
|
|
204
|
+
if len(l) > 0 and l[0] != "d":
|
|
205
|
+
filtered.append(l)
|
|
206
|
+
state[team].action = filtered
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def compute_reward(player):
|
|
210
|
+
ct_count = sum([len(v.citytiles) for k, v in player.cities.items()])
|
|
211
|
+
unit_count = len(game_state.players[player.team].units)
|
|
212
|
+
# max board size is 32 x 32 => 1024 max city tiles and units, so this should keep it strictly so we break by city tiles then unit count
|
|
213
|
+
return ct_count * 10000 + unit_count
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def renderer(state, env):
|
|
217
|
+
raise NotImplementedError("To render the replay, please set the render mode to json or html")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
dir_path = path.dirname(__file__)
|
|
221
|
+
json_path = path.abspath(path.join(dir_path, "lux_ai_2021.json"))
|
|
222
|
+
with open(json_path) as json_file:
|
|
223
|
+
specification = json.load(json_file)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def html_renderer():
|
|
227
|
+
html_path = path.abspath(path.join(dir_path, "index.html"))
|
|
228
|
+
return ("html_path", html_path)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
agents = all_agents
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"UNIT_TYPES": {
|
|
3
|
+
"WORKER": 0,
|
|
4
|
+
"CART": 1
|
|
5
|
+
},
|
|
6
|
+
"RESOURCE_TYPES": {
|
|
7
|
+
"WOOD": "wood",
|
|
8
|
+
"COAL": "coal",
|
|
9
|
+
"URANIUM": "uranium"
|
|
10
|
+
},
|
|
11
|
+
"DIRECTIONS": {
|
|
12
|
+
"NORTH": "n",
|
|
13
|
+
"WEST": "w",
|
|
14
|
+
"EAST": "e",
|
|
15
|
+
"SOUTH": "s",
|
|
16
|
+
"CENTER": "c"
|
|
17
|
+
},
|
|
18
|
+
"PARAMETERS": {
|
|
19
|
+
"DAY_LENGTH": 30,
|
|
20
|
+
"NIGHT_LENGTH": 10,
|
|
21
|
+
"MAX_DAYS": 360,
|
|
22
|
+
"LIGHT_UPKEEP": {
|
|
23
|
+
"CITY": 30,
|
|
24
|
+
"WORKER": 4,
|
|
25
|
+
"CART": 10
|
|
26
|
+
},
|
|
27
|
+
"WOOD_GROWTH_RATE": 1.01,
|
|
28
|
+
"MAX_WOOD_AMOUNT": 500,
|
|
29
|
+
"CITY_BUILD_COST": 100,
|
|
30
|
+
"CITY_ADJACENCY_BONUS": 5,
|
|
31
|
+
"RESOURCE_CAPACITY": {
|
|
32
|
+
"WORKER": 100,
|
|
33
|
+
"CART": 2000
|
|
34
|
+
},
|
|
35
|
+
"WORKER_COLLECTION_RATE": {
|
|
36
|
+
"WOOD": 20,
|
|
37
|
+
"COAL": 5,
|
|
38
|
+
"URANIUM": 2
|
|
39
|
+
},
|
|
40
|
+
"RESOURCE_TO_FUEL_RATE": {
|
|
41
|
+
"WOOD": 1,
|
|
42
|
+
"COAL": 10,
|
|
43
|
+
"URANIUM": 40
|
|
44
|
+
},
|
|
45
|
+
"RESEARCH_REQUIREMENTS": {
|
|
46
|
+
"COAL": 50,
|
|
47
|
+
"URANIUM": 200
|
|
48
|
+
},
|
|
49
|
+
"CITY_ACTION_COOLDOWN": 10,
|
|
50
|
+
"UNIT_ACTION_COOLDOWN": {
|
|
51
|
+
"CART": 3,
|
|
52
|
+
"WORKER": 2
|
|
53
|
+
},
|
|
54
|
+
"MAX_ROAD": 6,
|
|
55
|
+
"MIN_ROAD": 0,
|
|
56
|
+
"CART_ROAD_DEVELOPMENT_RATE": 0.5,
|
|
57
|
+
"PILLAGE_RATE": 0.5
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All game objects for access by user
|
|
3
|
+
*/
|
|
4
|
+
const {
|
|
5
|
+
Position
|
|
6
|
+
} = require("./map");
|
|
7
|
+
const GAME_CONSTANTS = require("./game_constants");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* holds all data related to a player
|
|
11
|
+
*/
|
|
12
|
+
class Player {
|
|
13
|
+
constructor(teamid) {
|
|
14
|
+
this.team = teamid;
|
|
15
|
+
this.researchPoints = 0;
|
|
16
|
+
// map unit id to the unit
|
|
17
|
+
this.units = [];
|
|
18
|
+
this.cities = new Map();
|
|
19
|
+
this.cityTileCount = 0;
|
|
20
|
+
}
|
|
21
|
+
researchedCoal() {
|
|
22
|
+
return this.researchPoints >= GAME_CONSTANTS.PARAMETERS.RESEARCH_REQUIREMENTS.COAL;
|
|
23
|
+
}
|
|
24
|
+
researchedUranium() {
|
|
25
|
+
return this.researchPoints >= GAME_CONSTANTS.PARAMETERS.RESEARCH_REQUIREMENTS.URANIUM;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// all data related to a city
|
|
30
|
+
class City {
|
|
31
|
+
constructor(teamid, cityid, fuel, lightUpkeep) {
|
|
32
|
+
this.cityid = cityid;
|
|
33
|
+
this.team = teamid;
|
|
34
|
+
this.fuel = fuel;
|
|
35
|
+
this.citytiles = [];
|
|
36
|
+
this.lightUpkeep = lightUpkeep;
|
|
37
|
+
}
|
|
38
|
+
addCityTile(x, y, cooldown) {
|
|
39
|
+
const ct = new CityTile(this.team, this.cityid, x, y, cooldown)
|
|
40
|
+
this.citytiles.push(ct);
|
|
41
|
+
return ct;
|
|
42
|
+
}
|
|
43
|
+
getLightUpkeep() {
|
|
44
|
+
return this.lightUpkeep;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** CityTile and Unit are both actionable and can return action strings to send to engine */
|
|
49
|
+
class CityTile {
|
|
50
|
+
constructor(teamid, cityid, x, y, cooldown) {
|
|
51
|
+
this.cityid = cityid;
|
|
52
|
+
this.team = teamid;
|
|
53
|
+
this.pos = new Position(x, y);
|
|
54
|
+
this.cooldown = cooldown;
|
|
55
|
+
}
|
|
56
|
+
/** Whether or not this unit can research or build */
|
|
57
|
+
canAct() {
|
|
58
|
+
return this.cooldown < 1;
|
|
59
|
+
}
|
|
60
|
+
/** returns command to ask this tile to research this turn */
|
|
61
|
+
research() {
|
|
62
|
+
return `r ${this.pos.x} ${this.pos.y}`;
|
|
63
|
+
}
|
|
64
|
+
/** returns command to ask this tile to build a worker this turn */
|
|
65
|
+
buildWorker() {
|
|
66
|
+
return `bw ${this.pos.x} ${this.pos.y}`;
|
|
67
|
+
}
|
|
68
|
+
/** returns command to ask this tile to build a cart this turn */
|
|
69
|
+
buildCart() {
|
|
70
|
+
return `bc ${this.pos.x} ${this.pos.y}`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
class Unit {
|
|
75
|
+
constructor(teamid, type, unitid, x, y, cooldown, wood, coal, uranium) {
|
|
76
|
+
this.pos = new Position(x, y);
|
|
77
|
+
this.team = teamid;
|
|
78
|
+
this.id = unitid;
|
|
79
|
+
this.type = type;
|
|
80
|
+
this.cooldown = cooldown;
|
|
81
|
+
this.cargo = {
|
|
82
|
+
wood,
|
|
83
|
+
coal,
|
|
84
|
+
uranium
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
isWorker() {
|
|
88
|
+
return this.type === GAME_CONSTANTS.UNIT_TYPES.WORKER;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
isCart() {
|
|
92
|
+
return this.type === GAME_CONSTANTS.UNIT_TYPES.CART;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getCargoSpaceLeft() {
|
|
96
|
+
const spaceused = this.cargo.wood + this.cargo.coal + this.cargo.uranium;
|
|
97
|
+
if (this.type === GAME_CONSTANTS.UNIT_TYPES.WORKER) {
|
|
98
|
+
return GAME_CONSTANTS.PARAMETERS.RESOURCE_CAPACITY.WORKER - spaceused;
|
|
99
|
+
} else {
|
|
100
|
+
return GAME_CONSTANTS.PARAMETERS.RESOURCE_CAPACITY.CART - spaceused;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** whether or not the unit can build where it is right now */
|
|
105
|
+
canBuild(gameMap) {
|
|
106
|
+
let cell = gameMap.getCellByPos(this.pos);
|
|
107
|
+
if (!cell.hasResource() && this.canAct() && (this.cargo.wood + this.cargo.coal + this.cargo.uranium) >= GAME_CONSTANTS.PARAMETERS.CITY_BUILD_COST) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** whether or not the unit can act or not. This does not check for potential collisions into other units or enemy cities */
|
|
114
|
+
canAct() {
|
|
115
|
+
return this.cooldown < 1;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** return the command to move unit in the given direction */
|
|
119
|
+
move(dir) {
|
|
120
|
+
return `m ${this.id} ${dir}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** return the command to transfer a resource from a source unit to a destination unit as specified by their ids or the units themselves */
|
|
124
|
+
transfer(destUnit, resourceType, amount) {
|
|
125
|
+
let destID = typeof destUnit === "string" ? destUnit : destUnit.id;
|
|
126
|
+
return `t ${this.id} ${destID} ${resourceType} ${amount}`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** return the command to build a city right under the worker */
|
|
130
|
+
buildCity() {
|
|
131
|
+
return `bcity ${this.id}`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** return the command to pillage whatever is underneath the worker */
|
|
135
|
+
pillage() {
|
|
136
|
+
return `p ${this.id}`;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = {
|
|
141
|
+
Player,
|
|
142
|
+
City,
|
|
143
|
+
Unit,
|
|
144
|
+
CityTile,
|
|
145
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** all constants related to any input from match engine */
|
|
2
|
+
const INPUT_CONSTANTS = {
|
|
3
|
+
DONE: 'D_DONE',
|
|
4
|
+
RESEARCH_POINTS: 'rp',
|
|
5
|
+
RESOURCES: 'r',
|
|
6
|
+
UNITS: 'u',
|
|
7
|
+
CITY: 'c',
|
|
8
|
+
CITY_TILES: 'ct',
|
|
9
|
+
ROADS: 'ccd',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
INPUT_CONSTANTS,
|
|
14
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const readline = require('readline');
|
|
3
|
+
|
|
4
|
+
// Create parser and use ',' as the delimiter between commands being sent by the `Match` and `MatchEngine`
|
|
5
|
+
const Parser = require('./parser');
|
|
6
|
+
const {
|
|
7
|
+
GameMap
|
|
8
|
+
} = require('./map');
|
|
9
|
+
const {
|
|
10
|
+
INPUT_CONSTANTS
|
|
11
|
+
} = require('./io');
|
|
12
|
+
const {
|
|
13
|
+
Player,
|
|
14
|
+
City,
|
|
15
|
+
Unit,
|
|
16
|
+
} = require('./game_objects');
|
|
17
|
+
const GAME_CONSTANTS = require('./game_constants');
|
|
18
|
+
const parse = new Parser(' ');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Agent for sequential `Designs`
|
|
22
|
+
*/
|
|
23
|
+
class Agent {
|
|
24
|
+
_setup() {
|
|
25
|
+
|
|
26
|
+
// Prepare to read input
|
|
27
|
+
const rl = readline.createInterface({
|
|
28
|
+
input: process.stdin,
|
|
29
|
+
output: null,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
let buffer = [];
|
|
33
|
+
let currentResolve;
|
|
34
|
+
const makePromise = function () {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
currentResolve = resolve;
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
// on each line, push line to buffer
|
|
40
|
+
rl.on('line', (line) => {
|
|
41
|
+
buffer.push(line);
|
|
42
|
+
currentResolve();
|
|
43
|
+
currentPromise = makePromise();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// The current promise for retrieving the next line
|
|
47
|
+
let currentPromise = makePromise();
|
|
48
|
+
|
|
49
|
+
// with await, we pause process until there is input
|
|
50
|
+
const getLine = async () => {
|
|
51
|
+
return new Promise(async (resolve) => {
|
|
52
|
+
while (buffer.length === 0) {
|
|
53
|
+
// pause while buffer is empty, continue if new line read
|
|
54
|
+
await currentPromise;
|
|
55
|
+
}
|
|
56
|
+
// once buffer is not empty, resolve the most recent line in stdin, and remove it
|
|
57
|
+
resolve(parse(buffer.shift()));
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
this.getLine = getLine;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Constructor for a new agent
|
|
65
|
+
* User should edit this according to the `Design` this agent will compete under
|
|
66
|
+
*/
|
|
67
|
+
constructor() {
|
|
68
|
+
this._setup(); // DO NOT REMOVE
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Initialize Agent for the `Match`
|
|
73
|
+
* User should edit this according to their `Design`
|
|
74
|
+
*/
|
|
75
|
+
async initialize() {
|
|
76
|
+
|
|
77
|
+
// get agent ID
|
|
78
|
+
const id = (await this.getLine()).nextInt();
|
|
79
|
+
// get some other necessary initial input
|
|
80
|
+
let mapInfo = (await this.getLine());
|
|
81
|
+
let width = mapInfo.nextInt();
|
|
82
|
+
let height = mapInfo.nextInt();
|
|
83
|
+
const map = new GameMap(width, height);
|
|
84
|
+
const players = [new Player(0), new Player(1)];
|
|
85
|
+
|
|
86
|
+
this.gameState = {
|
|
87
|
+
id,
|
|
88
|
+
map,
|
|
89
|
+
players,
|
|
90
|
+
turn: -1,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Updates agent's own known state of `Match`
|
|
95
|
+
* User should edit this according to their `Design`.
|
|
96
|
+
*/
|
|
97
|
+
async update() {
|
|
98
|
+
this.gameState.turn++;
|
|
99
|
+
// wait for the engine to send any updates
|
|
100
|
+
await this.retrieveUpdates();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
resetPlayerStates() {
|
|
104
|
+
let players = this.gameState.players;
|
|
105
|
+
players[0].units = [];
|
|
106
|
+
players[0].cities = new Map();
|
|
107
|
+
players[0].cityTileCount = 0;
|
|
108
|
+
players[1].units = [];
|
|
109
|
+
players[1].cities = new Map();
|
|
110
|
+
players[1].cityTileCount = 0;
|
|
111
|
+
}
|
|
112
|
+
async retrieveUpdates() {
|
|
113
|
+
this.resetPlayerStates();
|
|
114
|
+
// TODO: this can be optimized. we only reset because some resources get removed
|
|
115
|
+
this.gameState.map = new GameMap(this.gameState.map.width, this.gameState.map.height);
|
|
116
|
+
while (true) {
|
|
117
|
+
let update = (await this.getLine());
|
|
118
|
+
if (update.str === INPUT_CONSTANTS.DONE) {
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
const inputIdentifier = update.nextStr();
|
|
122
|
+
switch (inputIdentifier) {
|
|
123
|
+
case INPUT_CONSTANTS.RESEARCH_POINTS: {
|
|
124
|
+
const team = update.nextInt();
|
|
125
|
+
this.gameState.players[team].researchPoints = update.nextInt();
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case INPUT_CONSTANTS.RESOURCES: {
|
|
129
|
+
const type = update.nextStr();
|
|
130
|
+
const x = update.nextInt();
|
|
131
|
+
const y = update.nextInt();
|
|
132
|
+
const amt = update.nextInt();
|
|
133
|
+
this.gameState.map._setResource(type, x, y, amt);
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case INPUT_CONSTANTS.UNITS: {
|
|
137
|
+
const unittype = update.nextInt();
|
|
138
|
+
const team = update.nextInt();
|
|
139
|
+
const unitid = update.nextStr();
|
|
140
|
+
const x = update.nextInt();
|
|
141
|
+
const y = update.nextInt();
|
|
142
|
+
const cooldown = update.nextFloat();
|
|
143
|
+
const wood = update.nextInt();
|
|
144
|
+
const coal = update.nextInt();
|
|
145
|
+
const uranium = update.nextInt();
|
|
146
|
+
this.gameState.players[team].units.push(new Unit(team, unittype, unitid, x, y, cooldown, wood, coal, uranium));
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case INPUT_CONSTANTS.CITY: {
|
|
150
|
+
const team = update.nextInt();
|
|
151
|
+
const cityid = update.nextStr();
|
|
152
|
+
const fuel = update.nextFloat();
|
|
153
|
+
const lightUpkeep = update.nextFloat();
|
|
154
|
+
this.gameState.players[team].cities.set(cityid, new City(team, cityid, fuel, lightUpkeep));
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case INPUT_CONSTANTS.CITY_TILES: {
|
|
158
|
+
const team = update.nextInt();
|
|
159
|
+
const cityid = update.nextStr();
|
|
160
|
+
const x = update.nextInt();
|
|
161
|
+
const y = update.nextInt();
|
|
162
|
+
const cooldown = update.nextFloat();
|
|
163
|
+
const city = this.gameState.players[team].cities.get(cityid);
|
|
164
|
+
const citytile = city.addCityTile(x, y, cooldown);
|
|
165
|
+
this.gameState.map.getCell(x, y).citytile = citytile;
|
|
166
|
+
this.gameState.players[team].cityTileCount += 1;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case INPUT_CONSTANTS.ROADS: {
|
|
170
|
+
const x = update.nextInt();
|
|
171
|
+
const y = update.nextInt();
|
|
172
|
+
const road = update.nextFloat();
|
|
173
|
+
this.gameState.map.getCell(x, y).road = road;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* End a turn
|
|
182
|
+
*/
|
|
183
|
+
endTurn() {
|
|
184
|
+
console.log('D_FINISH');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const annotate = {
|
|
189
|
+
circle: (x, y) => {
|
|
190
|
+
return `dc ${x} ${y}`
|
|
191
|
+
},
|
|
192
|
+
x: (x, y) => {
|
|
193
|
+
return `dx ${x} ${y}`
|
|
194
|
+
},
|
|
195
|
+
line: (x1, y1, x2, y2) => {
|
|
196
|
+
return `dl ${x1} ${y1} ${x2} ${y2}`
|
|
197
|
+
},
|
|
198
|
+
text: (x1, y1, message, fontsize = 16) => {
|
|
199
|
+
return `dt ${x1} ${y1} ${fontsize} '${message}'`
|
|
200
|
+
},
|
|
201
|
+
sidetext: (message) => {
|
|
202
|
+
return `dst '${message}'`
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
module.exports = {
|
|
207
|
+
Agent,
|
|
208
|
+
annotate
|
|
209
|
+
};
|