@@ -194,16 +194,30 @@ class GameMetadata:
194194 agent_info : list [AgentInfo ] | None = None
195195
196196
197- def process_round_results (round_results : dict [str , Any ] | None ) -> dict [str , Any ] | None :
197+ def process_round_results (
198+ round_results : dict [str , Any ] | None , agent_info : list [AgentInfo ] | None = None
199+ ) -> dict [str , Any ] | None :
198200 """Process round results to add computed fields and sort scores"""
199- if not round_results or not round_results . get ( "scores" ) :
201+ if not round_results :
200202 return round_results
201203
202204 # Create a copy to avoid modifying original data
203205 processed = round_results .copy ()
204206
207+ # Get scores, initialize empty dict if missing
208+ scores = round_results .get ("scores" , {}).copy ()
209+
210+ # Ensure all expected players are in scores, even with 0 wins
211+ if agent_info :
212+ expected_players = {agent .name for agent in agent_info }
213+ missing_players = expected_players - set (scores .keys ())
214+ if missing_players :
215+ print (f"WARNING: Players { sorted (missing_players )} not found in round results, adding with 0 wins" )
216+ for player in missing_players :
217+ scores [player ] = 0
218+
205219 # Sort scores alphabetically by key
206- scores = dict (sorted (round_results [ " scores" ] .items ()))
220+ scores = dict (sorted (scores .items ()))
207221 processed ["scores" ] = scores
208222 processed ["sorted_scores" ] = list (scores .items ())
209223
@@ -221,7 +235,9 @@ def process_round_results(round_results: dict[str, Any] | None) -> dict[str, Any
221235 processed ["winner_percentage" ] = None # No percentage for ties
222236
223237 # Calculate p-value for statistical significance
238+ print (f"Calculating p-value for scores: { dict (sorted (scores .items ()))} " )
224239 p_value = calculate_p_value (scores )
240+ print (f"P-value result: { p_value } (rounded: { round (p_value , 2 )} )" )
225241 processed ["p_value" ] = round (p_value , 2 )
226242 else :
227243 processed ["winner_percentage" ] = None
@@ -306,7 +322,9 @@ def parse_game_metadata(self) -> GameMetadata:
306322 round_results = None
307323 if results_file .exists ():
308324 round_results = json .loads (results_file .read_text ())
309- round_results = process_round_results (round_results )
325+ # Get agent info for this round (we'll need to get it from metadata)
326+ agent_info = get_agent_info_from_metadata (results ) if results else []
327+ round_results = process_round_results (round_results , agent_info )
310328
311329 rounds .append ({"round_num" : round_num , "sim_logs" : sim_logs , "results" : round_results })
312330
@@ -339,7 +357,7 @@ def parse_trajectory(self, player_name: str, round_num: int) -> TrajectoryInfo |
339357 info = data .get ("info" , {})
340358 model_stats = info .get ("model_stats" , {})
341359
342- # Get diff data from player metadata if available
360+ # Get diff data from player metadata and changes file
343361 diff = None
344362 incremental_diff = None
345363 modified_files = None
@@ -349,16 +367,35 @@ def parse_trajectory(self, player_name: str, round_num: int) -> TrajectoryInfo |
349367 if player_name in self ._player_metadata :
350368 player_meta = self ._player_metadata [player_name ]
351369 diff = player_meta .get ("diff" , {}).get (str (round_num ), "" )
352- incremental_diff = player_meta .get ("incremental_diff" , {}).get (str (round_num ), "" )
353- modified_files = player_meta .get ("modified_files" , {}).get (str (round_num ), {})
354-
355- # Filter and split diffs by files
356- filtered_diff = filter_git_diff (diff ) if diff else ""
357- filtered_incremental_diff = filter_git_diff (incremental_diff ) if incremental_diff else ""
358- diff_by_files = split_git_diff_by_files (filtered_diff ) if filtered_diff else {}
359- incremental_diff_by_files = (
360- split_git_diff_by_files (filtered_incremental_diff ) if filtered_incremental_diff else {}
361- )
370+
371+ # Try to read incremental changes from separate JSON file
372+ changes_file = player_dir / f"changes_r{ round_num } .json"
373+ if changes_file .exists ():
374+ try :
375+ changes_data = json .loads (changes_file .read_text ())
376+ incremental_diff = changes_data .get ("incremental_diff" , "" )
377+ modified_files = changes_data .get ("modified_files" , {})
378+ except (json .JSONDecodeError , KeyError ):
379+ # Fall back to metadata if changes file is corrupted
380+ if player_name in self ._player_metadata :
381+ player_meta = self ._player_metadata [player_name ]
382+ incremental_diff = player_meta .get ("incremental_diff" , {}).get (str (round_num ), "" )
383+ modified_files = player_meta .get ("modified_files" , {}).get (str (round_num ), {})
384+ else :
385+ # todo: Legacy: Remove this at some point after we have migrated
386+ # Fall back to metadata if changes file doesn't exist
387+ if player_name in self ._player_metadata :
388+ player_meta = self ._player_metadata [player_name ]
389+ incremental_diff = player_meta .get ("incremental_diff" , {}).get (str (round_num ), "" )
390+ modified_files = player_meta .get ("modified_files" , {}).get (str (round_num ), {})
391+
392+ # Filter and split diffs by files
393+ filtered_diff = filter_git_diff (diff ) if diff else ""
394+ filtered_incremental_diff = filter_git_diff (incremental_diff ) if incremental_diff else ""
395+ diff_by_files = split_git_diff_by_files (filtered_diff ) if filtered_diff else {}
396+ incremental_diff_by_files = (
397+ split_git_diff_by_files (filtered_incremental_diff ) if filtered_incremental_diff else {}
398+ )
362399
363400 return TrajectoryInfo (
364401 player_id = player_name , # Now stores player name instead of numeric ID
0 commit comments