33import json
44import shlex
55import subprocess
6- from collections import Counter
76from concurrent .futures import ThreadPoolExecutor , as_completed
87
98from tqdm .auto import tqdm
@@ -53,10 +52,7 @@ def validate_code(self, agent: Player) -> tuple[bool, str | None]:
5352 content = agent .environment .execute (f"cat { self .submission } " )["output" ]
5453
5554 # Check for required function definitions
56- required_functions = [
57- "def get_bid(" ,
58- "def play_card("
59- ]
55+ required_functions = ["def get_bid(" , "def play_card(" ]
6056
6157 missing = []
6258 for func in required_functions :
@@ -86,7 +82,7 @@ def _run_single_simulation(self, agents: list[Player], idx: int, cmd: str):
8682
8783 def execute_round (self , agents : list [Player ]):
8884 """Execute a round of Bridge games."""
89- sims = self .game_config .get (' sims_per_round' , 10 )
85+ sims = self .game_config .get (" sims_per_round" , 10 )
9086 self .logger .info (f"Running { sims } Bridge simulations with 4 players" )
9187
9288 # Build agent paths for the command
@@ -100,12 +96,7 @@ def execute_round(self, agents: list[Player]):
10096 # Run simulations in parallel
10197 with ThreadPoolExecutor (max_workers = 8 ) as executor :
10298 futures = [
103- executor .submit (
104- self ._run_single_simulation ,
105- agents ,
106- idx ,
107- f"{ cmd } --seed { idx } --dealer { idx % 4 } "
108- )
99+ executor .submit (self ._run_single_simulation , agents , idx , f"{ cmd } --seed { idx } --dealer { idx % 4 } " )
109100 for idx in range (sims )
110101 ]
111102 for future in tqdm (as_completed (futures ), total = len (futures ), desc = "Bridge simulations" ):
@@ -114,11 +105,11 @@ def execute_round(self, agents: list[Player]):
114105 def get_results (self , agents : list [Player ], round_num : int , stats : RoundStats ):
115106 """Parse results and determine winners."""
116107 # Initialize team scores
117- team_scores = {'NS' : 0.0 , 'EW' : 0.0 }
108+ team_scores = {"NS" : 0.0 , "EW" : 0.0 }
118109 games_played = 0
119110
120111 # Parse all simulation logs
121- for idx in range (self .game_config .get (' sims_per_round' , 10 )):
112+ for idx in range (self .game_config .get (" sims_per_round" , 10 )):
122113 log_file = self .log_round (round_num ) / f"sim_{ idx } .json"
123114
124115 if not log_file .exists ():
@@ -130,15 +121,15 @@ def get_results(self, agents: list[Player], round_num: int, stats: RoundStats):
130121 result = json .load (f )
131122
132123 # Check for error
133- if ' error' in result :
124+ if " error" in result :
134125 self .logger .warning (f"Simulation { idx } had error: { result ['error' ]} " )
135126 continue
136127
137128 # Extract VP scores for each team
138- vp_scores = result .get (' normalized_score' , {})
129+ vp_scores = result .get (" normalized_score" , {})
139130 if vp_scores :
140- team_scores ['NS' ] += vp_scores .get ('NS' , 0.0 )
141- team_scores ['EW' ] += vp_scores .get ('EW' , 0.0 )
131+ team_scores ["NS" ] += vp_scores .get ("NS" , 0.0 )
132+ team_scores ["EW" ] += vp_scores .get ("EW" , 0.0 )
142133 games_played += 1
143134 except (json .JSONDecodeError , KeyError ) as e :
144135 self .logger .warning (f"Error parsing { log_file } : { e } " )
@@ -153,20 +144,20 @@ def get_results(self, agents: list[Player], round_num: int, stats: RoundStats):
153144 return
154145
155146 # Average the scores
156- team_scores ['NS' ] /= games_played
157- team_scores ['EW' ] /= games_played
147+ team_scores ["NS" ] /= games_played
148+ team_scores ["EW" ] /= games_played
158149
159150 # Determine winning team
160- if abs (team_scores ['NS' ] - team_scores ['EW' ]) < 0.01 : # Tie threshold
151+ if abs (team_scores ["NS" ] - team_scores ["EW" ]) < 0.01 : # Tie threshold
161152 stats .winner = RESULT_TIE
162- elif team_scores ['NS' ] > team_scores ['EW' ]:
153+ elif team_scores ["NS" ] > team_scores ["EW" ]:
163154 stats .winner = f"{ agents [0 ].name } /{ agents [2 ].name } "
164155 else :
165156 stats .winner = f"{ agents [1 ].name } /{ agents [3 ].name } "
166157
167158 # Assign scores to individual players based on their team
168159 for position , agent in enumerate (agents ):
169- team = 'NS' if position % 2 == 0 else 'EW'
160+ team = "NS" if position % 2 == 0 else "EW"
170161 score = team_scores [team ]
171162 stats .scores [agent .name ] = score
172163 stats .player_stats [agent .name ].score = score
0 commit comments