Skip to content

Commit 5c4724c

Browse files
authored
Merge pull request #217 from Lux-AI-Challenge/v2.1.8
V2.1.8
2 parents 87cd543 + 42e1185 commit 5c4724c

File tree

10 files changed

+71
-14
lines changed

10 files changed

+71
-14
lines changed

ChangeLog.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# ChangeLog
22

3+
### v2.1.8
4+
5+
fix bug on mac where non python kits assumed a windows platform
6+
7+
store replay seed and player paths on CLI tool.
8+
9+
visualizer shows the player paths as well as seed on kaggle and local replays
10+
11+
12+
### v2.1.7
13+
removed omegaconf as dependency
14+
15+
16+
### v2.1.6
17+
18+
some bug fixes
19+
20+
### v2.1.5
21+
22+
verbosity is nicer and more bug fixes
23+
324
### v2.1.4
425

526
Fix bug with action formatter not handling lists

lux-eye-s2/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lux-ai/lux-eye-s2",
3-
"version": "2.1.7",
3+
"version": "2.1.9",
44
"type": "module",
55
"scripts": {
66
"dev": "vite",

lux-eye-s2/src/episode/kaggle-environments.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { parseLuxAIS2Episode } from './luxai-s2';
2-
import { Episode } from './model';
2+
import { Episode, EpisodeMetadata } from './model';
33

44
export function isKaggleEnvironmentsEpisode(data: any): boolean {
55
return typeof data === 'object' && data.steps !== undefined;
@@ -9,9 +9,12 @@ export function parseKaggleEnvironmentsEpisode(data: any): Episode {
99
const observations = [];
1010
const actions = [];
1111

12-
let teamNames: [string, string] | undefined = undefined;
12+
const extra: Partial<EpisodeMetadata> = {};
1313
if (typeof data.info === 'object' && data.info.TeamNames !== undefined) {
14-
teamNames = data.info.TeamNames;
14+
extra.teamNames = data.info.TeamNames;
15+
}
16+
if (typeof data.configuration == 'object' && data.configuration.seed !== undefined) {
17+
extra.seed = data.configuration.seed;
1518
}
1619

1720
for (const step of data.steps) {
@@ -26,5 +29,5 @@ export function parseKaggleEnvironmentsEpisode(data: any): Episode {
2629
});
2730
}
2831

29-
return parseLuxAIS2Episode({ observations, actions }, teamNames);
32+
return parseLuxAIS2Episode({ observations, actions }, extra);
3033
}

lux-eye-s2/src/episode/luxai-s2.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
Board,
33
Episode,
4+
EpisodeMetadata,
45
Faction,
56
Factory,
67
FactoryAction,
@@ -128,11 +129,27 @@ export function isLuxAIS2Episode(data: any): boolean {
128129
return typeof data === 'object' && data.observations !== undefined && data.actions !== undefined;
129130
}
130131

131-
export function parseLuxAIS2Episode(data: any, teamNames: [string, string] = ['Player A', 'Player B']): Episode {
132+
export function parseLuxAIS2Episode(data: any, extra: Partial<EpisodeMetadata> = {}): Episode {
132133
if (data.observations[0].board.valid_spawns_mask === undefined) {
133134
throw new Error('Only Lux AI v1.1.0+ episodes are supported');
134135
}
135136

137+
let metadata: EpisodeMetadata = { teamNames: ['Player A', 'Player B'], seed: undefined };
138+
metadata = {
139+
...metadata,
140+
...extra,
141+
};
142+
if (data.metadata) {
143+
if (data.metadata['players']) {
144+
for (let i = 0; i < 2; i++) {
145+
metadata.teamNames[i] = data.metadata['players'][`player_${i}`];
146+
}
147+
}
148+
if (data.metadata['seed']) {
149+
metadata.seed = data.metadata['seed'];
150+
}
151+
}
152+
136153
const steps: Step[] = [];
137154

138155
for (let i = 0; i < data.observations.length; i++) {
@@ -195,7 +212,7 @@ export function parseLuxAIS2Episode(data: any, teamNames: [string, string] = ['P
195212
data.observations[1].teams[playerId] !== undefined ? data.observations[1].teams[playerId] : null;
196213

197214
teams.push({
198-
name: teamNames[j],
215+
name: metadata.teamNames[j],
199216
faction: rawPlayer !== null ? rawPlayer.faction : Faction.None,
200217

201218
water: 0,
@@ -285,7 +302,7 @@ export function parseLuxAIS2Episode(data: any, teamNames: [string, string] = ['P
285302

286303
const rawTeam = obs.teams[playerId];
287304
teams.push({
288-
name: teamNames[j],
305+
name: metadata.teamNames[j],
289306
faction: rawTeam.faction,
290307

291308
water: rawTeam.water,
@@ -311,5 +328,5 @@ export function parseLuxAIS2Episode(data: any, teamNames: [string, string] = ['P
311328
});
312329
}
313330

314-
return { steps };
331+
return { steps, metadata };
315332
}

lux-eye-s2/src/episode/model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,9 @@ export interface Step {
166166

167167
export interface Episode {
168168
steps: Step[];
169+
metadata: EpisodeMetadata;
170+
}
171+
export interface EpisodeMetadata {
172+
teamNames: [string, string];
173+
seed?: number;
169174
}

lux-eye-s2/src/pages/visualizer/TurnControl.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ export function TurnControl({ showHotkeysButton, showOpenButton }: TurnControlPr
287287

288288
<Group position="apart">
289289
<Text>{isDay ? 'Day' : 'Night'}</Text>
290+
{episode.metadata.seed && <Text>Seed: {episode.metadata.seed}</Text>}
290291
{selectedTile !== null && (
291292
<Text>
292293
Tile: ({selectedTile.x}, {selectedTile.y})

luxai_s2/luxai_runner/bot.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ async def step(self, obs, step: int, reward: float = 0, info=dict()):
8282
)
8383
except asyncio.TimeoutError:
8484
action, stderr = None, None
85+
except:
86+
action, stderr = None, None
8587
time_used = time.time() - stime
8688

8789
if stderr != "" and stderr is not None:

luxai_s2/luxai_runner/episode.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ def __init__(self, cfg: EpisodeConfig) -> None:
3939
self.seed = cfg.seed if cfg.seed is not None else np.random.randint(9999999)
4040
self.players = cfg.players
4141

42-
def save_replay(self, replay):
42+
def save_replay(self, replay, metadata):
4343
save_format = self.cfg.replay_options.save_format
4444
if save_format not in ["json", "html"]:
4545
raise ValueError(f"{save_format} is not a valid save format")
46-
46+
replay["metadata"] = metadata
4747
replay["observations"] = [to_json(x) for x in replay["observations"]]
4848
replay["actions"] = [to_json(x) for x in replay["actions"]]
49+
replay["default_seed"] = self.cfg.seed
4950
del replay["dones"]
5051
del replay["rewards"]
5152

@@ -102,11 +103,18 @@ async def run(self):
102103
start_tasks += [player.proc.start()]
103104
await asyncio.wait(start_tasks, return_when=asyncio.ALL_COMPLETED)
104105

106+
metadata = dict()
107+
105108
obs = self.env.reset(seed=self.seed)
106109
env_cfg = self.env.state.env_cfg
107110
state_obs = self.env.state.get_compressed_obs()
108111
obs = to_json(state_obs)
109112

113+
metadata["seed"] = self.env.seed_val
114+
metadata["players"] = dict()
115+
for player_id, bot in players.items():
116+
metadata["players"][player_id] = bot.main_file_path
117+
110118
if self.cfg.render:
111119
self.env.render()
112120
time.sleep(0.2)
@@ -181,7 +189,7 @@ async def run(self):
181189
game_done = True
182190
self.log.info(f"Final Scores: {rewards}")
183191
if save_replay:
184-
self.save_replay(replay)
192+
self.save_replay(replay, metadata)
185193

186194
for player in players.values():
187195
await player.proc.cleanup()

luxai_s2/luxai_runner/process.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ async def start(self):
5454
base_file_path = os.path.basename(self.file_path)
5555
if self.is_binary:
5656
self._agent_process = await asyncio.create_subprocess_exec(
57-
f"{cwd}\{base_file_path}" if "win" in sys.platform else f"./{base_file_path}",
57+
f"{cwd}\{base_file_path}" if sys.platform.startswith('win') else f"./{base_file_path}",
5858
stdin=asyncio.subprocess.PIPE,
5959
stdout=asyncio.subprocess.PIPE,
6060
stderr=asyncio.subprocess.PIPE,

luxai_s2/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def read(fname):
1717
long_description="Code for the Lux AI Challenge Season 2",
1818
packages=find_packages(exclude="kits"),
1919
entry_points={"console_scripts": ["luxai-s2 = luxai_runner.cli:main"]},
20-
version="2.1.7",
20+
version="2.1.8",
2121
python_requires=">=3.7",
2222
install_requires=[
2323
"numpy",

0 commit comments

Comments
 (0)