66from codeclash .utils .environment import create_file_in_container
77
88HB_LOG_ENGINE = "engine.log"
9+ HB_PORT = 8000
910HB_REGEX_SCORE = re .compile (r"Player\s(\d+)\sdelta\supdated\:[\d\s\-\+\=]+,\smoney\:\s\d+\s\-\>\s(\d+)" )
11+ HB_SCRIPT = "run_game.sh"
1012
1113
1214class HuskyBenchGame (CodeGame ):
@@ -16,7 +18,7 @@ def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
1618 super ().__init__ (config , tournament_id = tournament_id , local_output_dir = local_output_dir )
1719 self .num_players : int = len (config ["players" ])
1820 self .run_cmd_round : str = (
19- f"python engine/main.py --port 8000 --players { self .num_players } "
21+ f"python engine/main.py --port { HB_PORT } --players { self .num_players } "
2022 f"--sim --sim-rounds { self .game_config ['sims_per_round' ]} "
2123 )
2224 for arg , val in self .game_config .get ("args" , {}).items ():
@@ -26,24 +28,34 @@ def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
2628 else :
2729 self .run_cmd_round += f" --{ arg } { val } "
2830
29- def execute_round (self , agents : list [Player ]):
30- cmd = f"{ self .run_cmd_round } > { self .log_env / HB_LOG_ENGINE } 2>&1 &"
31- self .logger .debug (f"Starting game engine with command: { cmd } " )
32- # Remove previous outputs, kill previous game if any, start engine, start server
33- script = ["rm -rf /app/output/*" , "kill -9 $(lsof -ti :8000)" , cmd , "sleep 0.5" ]
31+ def _construct_game_script (self , agents : list [Player ], run_cmd_round : str , verbose : bool = False ) -> None :
32+ if verbose :
33+ self .logger .debug (f"Starting game engine with command: { run_cmd_round } " )
34+ script = [
35+ "!/bin/bash" ,
36+ "rm -rf /app/output/*" , # Remove previous outputs
37+ f"kill -9 $(lsof -ti :{ HB_PORT } )" , # Kill previous game if any
38+ run_cmd_round , # Start engine
39+ "sleep 0.5" , # Give engine a moment to start
40+ ]
3441 for agent in agents :
3542 # Start each agent in background, redirecting output to log file
36- cmd = f"cd /{ agent .name } && python client/main.py --port 8000 > { self .log_env / f'{ agent .name } .log' } 2>&1 &"
37- self .logger .info (f"Adding player { agent .name } with command: { cmd } " )
43+ cmd = (
44+ f"cd /{ agent .name } && python client/main.py --port { HB_PORT } "
45+ f"> { self .log_env / f'{ agent .name } .log' } 2>&1 &"
46+ )
47+ if verbose :
48+ self .logger .debug (f"Starting agent { agent .name } with command: { cmd } " )
3849 script .append (cmd )
3950 script .append ("wait" )
4051 script .append (f"mv /app/output/* { self .log_env } " ) # Move logs to log directory
41- create_file_in_container (
42- container = self .environment , content = "\n " .join (script ), dest_path = "/testbed/run_game.sh"
43- )
52+ return "\n " .join (script )
4453
45- # Run game
46- self .environment .execute ("chmod +x run_game.sh; ./run_game.sh" )
54+ def execute_round (self , agents : list [Player ]):
55+ cmd = f"{ self .run_cmd_round } > { self .log_env / HB_LOG_ENGINE } 2>&1 &"
56+ script = self ._construct_game_script (agents , cmd , verbose = True )
57+ create_file_in_container (container = self .environment , content = script , dest_path = f"/testbed/{ HB_SCRIPT } " )
58+ self .environment .execute (f"chmod +x { HB_SCRIPT } ; ./{ HB_SCRIPT } " )
4759
4860 def get_results (self , agents : list [Player ], round_num : int , stats : RoundStats ):
4961 map_id_to_agent = {}
@@ -69,5 +81,9 @@ def get_results(self, agents: list[Player], round_num: int, stats: RoundStats):
6981 stats .player_stats [player ].score = score
7082
7183 def validate_code (self , agent : Player ) -> tuple [bool , str | None ]:
72- # TODO: implement more checks
84+ assets = agent .environment .execute ("ls client" )["output" ]
85+ if "main.py" not in assets :
86+ return False , "There should be a `client/main.py` file"
87+ if "player.py" not in assets :
88+ return False , "There should be a `client/player.py` file"
7389 return True , None
0 commit comments