Skip to content

Commit 1c343ad

Browse files
committed
WIP HuskyBench
1 parent 0cb4d62 commit 1c343ad

4 files changed

Lines changed: 48 additions & 17 deletions

File tree

codeclash/games/huskybench/huskybench.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1+
import re
12
from pathlib import Path
23

34
from codeclash.agents.player import Player
45
from codeclash.games.game import CodeGame, RoundStats
56
from codeclash.utils.environment import copy_from_container
67

78
HB_LOG_DIR = Path("/testbed/engine/logs/")
9+
HB_REGEX_SCORE = re.compile(r"Player\s(\d+)\sdelta\supdated\:[\d\s\-\+\=]+,\smoney\:\s\d+\s\-\>\s(\d+)")
810

911

1012
class HuskyBenchGame(CodeGame):
1113
name: str = "HuskyBench"
1214

1315
def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
1416
super().__init__(config, tournament_id=tournament_id, local_output_dir=local_output_dir)
17+
self.num_players: int = len(config["players"])
1518
self.run_cmd_round: str = (
16-
f"python engine/main.py --port 8000 --sim --sim-rounds {self.game_config['sims_per_round']}"
19+
f"python engine/main.py --port 8000 --players {self.num_players} "
20+
f"--sim --sim-rounds {self.game_config['sims_per_round']}"
1721
)
1822
for arg, val in self.game_config.get("args", {}).items():
1923
if isinstance(val, bool):
@@ -32,17 +36,34 @@ def copy_logs_from_env(self, round_num):
3236
)
3337

3438
def get_stats(self, agents: list[Player], round_num: int) -> RoundStats:
35-
return RoundStats(winner="N/A", scores={})
39+
map_id_to_agent = {}
40+
for agent in agents:
41+
with open(self.log_round(round_num) / f"logs/{agent.name}.log") as f:
42+
for line in f:
43+
if line.startswith("My id:"):
44+
agent_id = line.strip().split()[-1]
45+
map_id_to_agent[agent_id] = agent.name
46+
self.logger.info("Agent IDs: " + str(map_id_to_agent))
47+
48+
with open(self.log_round(round_num) / "logs/engine.log") as f:
49+
score_updates = [
50+
(match.group(1), int(match.group(2))) for l in f.readlines() if (match := HB_REGEX_SCORE.search(l))
51+
]
52+
map_id_to_score = {k: v for k, v in score_updates[-self.num_players :]}
53+
self.logger.info("Final Scores: " + str(map_id_to_score))
54+
agent_to_score = {map_id_to_agent[agent_id]: score for agent_id, score in map_id_to_score.items()}
55+
return RoundStats(winner=max(agent_to_score, key=agent_to_score.get), scores=agent_to_score)
3656

3757
def execute_round(self, agents: list[Player]):
3858
self.environment.execute(f"rm -rf {HB_LOG_DIR}; mkdir -p {HB_LOG_DIR}")
3959
try:
40-
self.logger.debug("Starting game servers")
41-
self.environment.execute(f"{self.run_cmd_round} > {HB_LOG_DIR / 'engine.log'} &")
60+
cmd = f"{self.run_cmd_round} > {HB_LOG_DIR / 'engine.log'} &"
61+
self.logger.debug(f"Starting game engine with command: {cmd}")
62+
self.environment.execute(cmd)
4263
for agent in agents:
43-
self.environment.execute(
44-
f"python client/main.py --port 8000 > {HB_LOG_DIR / f'{agent.name}.log'} &", cwd=f"/{agent.name}"
45-
)
64+
cmd = f"python client/main.py --port 8000 > {HB_LOG_DIR / f'{agent.name}.log'} &"
65+
self.logger.debug(f"Adding agent with command: {cmd}")
66+
self.environment.execute(cmd, cwd=f"/{agent.name}")
4667
finally:
4768
# Kill all python servers when done
4869
self.environment.execute("pkill -f 'python client/main.py' || true")

codeclash/ratings/elo.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from dataclasses import dataclass
44
from pathlib import Path
55

6+
from tqdm import tqdm
7+
68
from codeclash.constants import DIR_LOGS, FILE_RESULTS
79

810
K_FACTOR = 32 # ELO constant, changeable
@@ -29,10 +31,10 @@ def main(log_dir: Path):
2931
# - metadata.json
3032
player_profiles = {}
3133
for user_folder in log_dir.iterdir():
32-
for game_log_folder in user_folder.iterdir():
33-
if game_log_folder.is_dir():
34-
print(f"Processing game log folder: {game_log_folder}")
35-
34+
print(f"Processing games under user `{user_folder.name}`")
35+
for game_log_folder in tqdm(list(user_folder.iterdir())):
36+
if not game_log_folder.is_dir():
37+
continue
3638
game_id = game_log_folder.name.split(".")[1]
3739
player_ids = [x.name for x in (game_log_folder / "players").iterdir() if x.is_dir()]
3840
# Initialize profiles
@@ -42,6 +44,9 @@ def main(log_dir: Path):
4244
player_profiles[key] = PlayerEloProfile(player_id=player, game_id=game_id)
4345

4446
for round_folder in (game_log_folder / "rounds").iterdir():
47+
if round_folder.name == "0":
48+
# Skip initial round
49+
continue
4550
if not (round_folder / FILE_RESULTS).exists():
4651
continue
4752
round_results = json.load(open(round_folder / FILE_RESULTS))

codeclash/ratings/win_rate.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from dataclasses import dataclass
44
from pathlib import Path
55

6+
from tqdm import tqdm
7+
68
from codeclash.constants import DIR_LOGS, FILE_RESULTS, RESULT_TIE
79

810

@@ -27,10 +29,10 @@ def main(log_dir: Path):
2729
# - metadata.json
2830
player_profiles = {}
2931
for user_folder in log_dir.iterdir():
30-
for game_log_folder in user_folder.iterdir():
31-
if game_log_folder.is_dir():
32-
print(f"Processing game log folder: {game_log_folder}")
33-
32+
print(f"Processing games under user `{user_folder.name}`")
33+
for game_log_folder in tqdm(list(user_folder.iterdir())):
34+
if not game_log_folder.is_dir():
35+
continue
3436
game_id = game_log_folder.name.split(".")[1]
3537
player_ids = [x.name for x in (game_log_folder / "players").iterdir() if x.is_dir()]
3638
num_rounds = len(list((game_log_folder / "rounds").iterdir()))
@@ -44,6 +46,9 @@ def main(log_dir: Path):
4446
)
4547

4648
for round_folder in (game_log_folder / "rounds").iterdir():
49+
if round_folder.name == "0":
50+
# Skip initial round
51+
continue
4752
if not (round_folder / FILE_RESULTS).exists():
4853
continue
4954
round_results = json.load(open(round_folder / FILE_RESULTS))

configs/test/dummy_huskybench.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
tournament:
2-
rounds: 3
2+
rounds: 25
33
game:
44
name: HuskyBench
5-
sims_per_round: 1
5+
sims_per_round: 30
66
players:
77
- agent: dummy
88
name: p1

0 commit comments

Comments
 (0)