Source code in codeclash/arenas/battlecode/battlecode.py
26272829303132333435
def__init__(self,config,**kwargs):super().__init__(config,**kwargs)assertlen(config["players"])==2,"BattleCode is a two-player game"self.run_cmd_round:str="python run.py run"forarg,valinself.game_config.get("args",self.default_args).items():ifisinstance(val,bool):ifval:self.run_cmd_round+=f" --{arg}"else:self.run_cmd_round+=f" --{arg}{val}"
nameclass-attributeinstance-attribute
name:str='BattleCode'
descriptionclass-attributeinstance-attribute
description:str='Battlecode 25 throws you into a real-time strategy showdown where your Python bot pilots a team of specialized robots—Soldiers, Moppers, Splashers—alongside towers that spawn units or generate resources.\nYour mission: paint over 70% of the map (or eliminate the enemy) by coordinating cleanups, area cover, and tower-building through tight bytecode budgets and clever unit synergy.'
Source code in codeclash/arenas/battlecode/battlecode.py
4950515253545556575859606162636465
defexecute_round(self,agents:list[Player]):foragentinagents:src,dest=f"/{agent.name}/src/{BC_FOLDER}/",str(DIR_WORK/"src"/agent.name)self.environment.execute(f"cp -r {src}{dest}")args=[f"--p{idx+1}-dir src --p{idx+1}{agent.name}"foridx,agentinenumerate(agents)]cmd=f"{self.run_cmd_round}{' '.join(args)}"self.logger.info(f"Running game: {cmd}")withThreadPoolExecutor(5)asexecutor:# Submit all simulations to the thread poolfutures=[executor.submit(self._run_single_simulation,agents,idx,cmd)foridxinrange(self.game_config["sims_per_round"])]# Collect results as they completeforfutureintqdm(as_completed(futures),total=len(futures),desc="Simulations"):future.result()
Source code in codeclash/arenas/battlecode/battlecode.py
67686970717273747576777879808182838485868788
defget_results(self,agents:list[Player],round_num:int,stats:RoundStats):scores=defaultdict(int)foridxinrange(self.game_config["sims_per_round"]):withopen(self.log_round(round_num)/BC_LOG.format(idx=idx))asf:lines=f.read().strip().split("\n")# Get the third-to-last line which contains the winner infoassertlen(lines)>=3,"Log file does not contain enough lines to determine winner"winner_line=lines[-3]reason_line=lines[-2]match=re.search(r"\s\((.*)\)\swins\s\(",winner_line)ifmatchandreason_line!=BC_TIE:winner_key=match.group(1)# Map A/B to actual agent names (much closer to original code)winner={"A":agents[0].name,"B":agents[1].name}.get(winner_key,RESULT_TIE)scores[winner]+=1else:winner=RESULT_TIEstats.winner=max(scores,key=scores.get)stats.scores=scoresforplayer,scoreinstats.scores.items():stats.player_stats[player].score=score
Source code in codeclash/arenas/battlecode/battlecode.py
909192939495969798
defvalidate_code(self,agent:Player)->tuple[bool,str|None]:ifBC_FOLDERnotinagent.environment.execute("ls src")["output"]:returnFalse,f"There should be a `src/{BC_FOLDER}/` directory"if"bot.py"notinagent.environment.execute(f"ls src/{BC_FOLDER}")["output"]:returnFalse,f"There should be a `src/{BC_FOLDER}/bot.py` file"bot_content=agent.environment.execute(f"cat src/{BC_FOLDER}/bot.py")["output"].splitlines()if"def turn():"notinbot_content:returnFalse,f"There should be a `turn()` function implemented in `src/{BC_FOLDER}/bot.py`"returnTrue,None