22import time
33from pathlib import Path
44
5+ from tqdm .auto import tqdm
6+
57from codeclash .agents .abstract import Player
6- from codeclash .constants import OUTPUTS_LOGS , OUTPUTS_RESULTS
7- from codeclash .games .abstract import CodeGame
8+ from codeclash .constants import RESULT_TIE
9+ from codeclash .games .abstract import CodeGame , RoundData , RoundStats
810from codeclash .utils .environment import assert_zero_exit_code
911
1012
@@ -23,21 +25,25 @@ def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
2325 else :
2426 self .run_cmd_round += f" --{ arg } { val } "
2527
26- def determine_winner (
27- self , result_outputs : list [str ], agents : list [Player ]
28- ) -> dict [str , str ]:
28+ def get_stats (self , result_outputs : list [str ], agents : list [Player ]) -> RoundStats :
2929 winners = []
3030 for ro in result_outputs :
3131 lines = ro .strip ().split ("\n " )
32- # Get the last line which contains the game result
33- last_line = lines [- 1 ] if lines else ""
34- self . logger . debug ( f"Last line: { last_line } " )
32+ last_line = (
33+ lines [- 1 ] if lines else ""
34+ ) # Get the last line which contains the game result
3535 winner = json .loads (last_line )["winnerName" ]
3636 winners .append (winner )
37- winner = max (set (winners ), key = winners .count )
38- return {"winner" : winner }
3937
40- def execute_round (self , agents : list [Player ]) -> dict [str , list [str ]]:
38+ win_counts = {agent .name : winners .count (agent .name ) for agent in agents }
39+ max_wins = max (win_counts .values ())
40+ winners = [name for name , wins in win_counts .items () if wins == max_wins ]
41+ return RoundStats (
42+ winner = RESULT_TIE if len (winners ) > 1 else winners [0 ],
43+ scores = win_counts ,
44+ )
45+
46+ def execute_round (self , agents : list [Player ]) -> RoundData :
4147 cmd = []
4248 for idx , agent in enumerate (agents ):
4349 port = 8001 + idx
@@ -51,15 +57,16 @@ def execute_round(self, agents: list[Player]) -> dict[str, list[str]]:
5157
5258 try :
5359 log_outputs , result_outputs = [], []
54- for idx in range (self .game_config ["sims_per_round" ]):
60+ cmd = self .run_cmd_round + " " + " " .join (cmd )
61+ self .logger .info (f"Running game: { cmd } " )
62+ for idx in tqdm (range (self .game_config ["sims_per_round" ])):
5563 # Create temporary output file for results
5664 output_file = f"battlesnake_output_{ idx } _{ int (time .time ())} .json"
57- cmd_str = " " .join (cmd ) + f" -o { output_file } "
58- self .logger .info (f"Running command: { self .run_cmd_round } { cmd_str } " )
5965
66+ # Run game
6067 response = assert_zero_exit_code (
6168 self .environment .execute (
62- f" { self . run_cmd_round } { cmd_str } " ,
69+ cmd + f" -o { output_file } " ,
6370 cwd = f"{ self .environment .config .cwd } /game" ,
6471 )
6572 )
@@ -72,10 +79,9 @@ def execute_round(self, agents: list[Player]) -> dict[str, list[str]]:
7279
7380 # Clean up the output file
7481 self .environment .execute (f"rm -f game/{ output_file } " )
82+ time .sleep (0.05 )
7583
76- time .sleep (0.1 )
77-
78- return {OUTPUTS_LOGS : log_outputs , OUTPUTS_RESULTS : result_outputs }
84+ return RoundData (log_outputs , result_outputs )
7985 finally :
8086 # Kill all python servers when done
8187 self .environment .execute ("pkill -f 'python main.py' || true" )
0 commit comments