77from codeclash .games .game import CodeGame , RoundStats
88
99BC_LOG = "sim.log"
10+ BC_FOLDER = "mysubmission"
11+ BC_TIE = "Reason: The winning team won arbitrarily (coin flip)."
1012
1113
1214class BattleCodeGame (CodeGame ):
@@ -25,7 +27,7 @@ def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
2527
2628 def execute_round (self , agents : list [Player ]):
2729 for agent in agents :
28- src , dest = f"/{ agent .name } /src/mysubmission /" , str (DIR_WORK / "src" / agent .name )
30+ src , dest = f"/{ agent .name } /src/{ BC_FOLDER } /" , str (DIR_WORK / "src" / agent .name )
2931 self .environment .execute (f"cp -r { src } { dest } " )
3032 random .shuffle (agents ) # Start position matters in BattleCode! Shuffle to be fair.
3133 args = [f"--p{ idx + 1 } -dir src --p{ idx + 1 } { agent .name } " for idx , agent in enumerate (agents )]
@@ -36,27 +38,34 @@ def execute_round(self, agents: list[Player]):
3638 assert response ["returncode" ] == 0 , response
3739
3840 def get_results (self , agents : list [Player ], round_num : int , stats : RoundStats ):
39- winners = []
4041 with open (self .log_round (round_num ) / BC_LOG ) as f :
4142 lines = f .read ().strip ().split ("\n " )
4243 # Get the third-to-last line which contains the winner info
43- winner_line = lines [- 3 ] if len (lines ) >= 3 else ""
44+ assert len (lines ) >= 3 , "Log file does not contain enough lines to determine winner"
45+ winner_line = lines [- 3 ]
46+ reason_line = lines [- 2 ]
4447 self .logger .debug (f"Winner line: { winner_line } " )
48+ self .logger .debug (f"Reason line: { reason_line } " )
4549 match = re .search (r"\s\((.*)\)\swins\s\(" , winner_line )
46- if match :
50+ if match and reason_line != BC_TIE :
4751 winner_key = match .group (1 )
4852 self .logger .debug (f"Winner key from match: { winner_key } " )
4953 # Map A/B to actual agent names (much closer to original code)
5054 winner = {"A" : agents [0 ].name , "B" : agents [1 ].name }.get (winner_key , RESULT_TIE )
51- winners .append (winner )
5255 else :
53- winners . append ( RESULT_TIE )
56+ winner = RESULT_TIE
5457
55- stats .winner = max ( set ( winners ), key = winners . count )
56- stats .scores = {agent .name : winners . count ( agent .name ) for agent in agents }
58+ stats .winner = winner
59+ stats .scores = {agent .name : ( 1 if agent .name == winner else 0 ) for agent in agents }
5760 for player , score in stats .scores .items ():
5861 stats .player_stats [player ].score = score
5962
6063 def validate_code (self , agent : Player ) -> tuple [bool , str | None ]:
61- # TODO: implement more checks
64+ if BC_FOLDER not in agent .environment .execute ("ls src" )["output" ]:
65+ return False , f"`{ BC_FOLDER } ` directory not found in `src/`"
66+ if "bot.py" not in agent .environment .execute (f"ls src/{ BC_FOLDER } " )["output" ]:
67+ return False , "`bot.py` not found in `src/mysubmission/`"
68+ bot_content = agent .environment .execute (f"cat src/{ BC_FOLDER } /bot.py" )["output" ].splitlines ()
69+ if "def turn():" not in bot_content :
70+ return False , "`turn()` function not found in `bot.py`"
6271 return True , None
0 commit comments