Source code in codeclash/arenas/robotrumble/robotrumble.py
26272829303132333435363738
def__init__(self,config,**kwargs):super().__init__(config,**kwargs)assertlen(config["players"])==2,"RobotRumble is a two-player game"self.run_cmd_round:str="./rumblebot run term"self.sim_ext="txt"forarg,valinself.game_config.get("args",self.default_args).items():ifisinstance(val,bool):ifval:self.run_cmd_round+=f" --{arg}"ifarg=="raw":self.sim_ext="json"else:self.run_cmd_round+=f" --{arg}{val}"
nameclass-attributeinstance-attribute
name:str='RobotRumble'
descriptionclass-attributeinstance-attribute
description:str='RobotRumble is a turn-based coding battle where you program a team of robots in Python or JavaScript to move, attack, and outmaneuver your opponent on a grid.\nEvery decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match.\nNOTE: Please ensure that your code runs efficiently (under 60 seconds). Code that exceeds this run time will automatically forfeit the round.'
Source code in codeclash/arenas/robotrumble/robotrumble.py
56575859606162636465666768697071727374757677
defexecute_round(self,agents:list[Player]):self.logger.info(f"Running game with players: {[agent.nameforagentinagents]}")args=[]foragentinagents:executable=agent.environment.execute(f"cat {ROBOTRUMBLE_HIDDEN_EXEC}")["output"].strip()args.append(f"/{agent.name}/{executable}")cmd=f"{self.run_cmd_round}{shlex.join(args)}"self.logger.info(f"Running game: {cmd}")withThreadPoolExecutor(8)asexecutor:# Submit all simulations to the thread poolfutures=[executor.submit(self._run_single_simulation,agents,idx,cmd)foridxinrange(self.game_config.get("sims_per_round",100))]# Collect results as they completei_completed=0forfutureinas_completed(futures):future.result()i_completed+=1self.logger.info(f"Completed {i_completed} of {len(futures)} simulations")
defget_results(self,agents:list[Player],round_num:int,stats:RoundStats):winners=[]foridxinrange(self.game_config.get("sims_per_round",100)):output_file=self.log_round(round_num)/f"sim_{idx}.{self.sim_ext}"ifnotoutput_file.exists():self.logger.warning(f"Simulation {idx} not found, skipping")continuewinners.append(self._get_winner_txt(output_file,agents)ifself.sim_ext=="txt"elseself._get_winner_json(output_file,agents))# Count winswin_counts=Counter(winners)# Find all winners with the maximum countmax_wins=max(win_counts.values())overall_winners=[nameforname,countinwin_counts.items()ifcount==max_wins]# Update statsstats.winner=RESULT_TIEiflen(overall_winners)>1elseoverall_winners[0]stats.details.append(f"In this round, {agents[0].name} was Blue and {agents[1].name} was Red.")stats.scores=dict(win_counts)forplayer,scoreinwin_counts.items():ifplayer!=RESULT_TIE:stats.player_stats[player].score=score
defvalidate_code(self,agent:Player)->tuple[bool,str|None]:# Determine if robot.js or robot.py existsext,exists=None,Falseforpossible_extinMAP_EXT_TO_HEADER.keys():exists_output=agent.environment.execute(f"test -f robot.{possible_ext} && echo 'exists'")["output"]if"exists"==exists_output.strip():ext=possible_extexists=Truebreakifnotexists:returnFalse,"There should be a `robot.js` or `robot.py` file"agent.environment.execute(f'echo "robot.{ext}" > {ROBOTRUMBLE_HIDDEN_EXEC}')# Check that the robot function is definedheader=MAP_EXT_TO_HEADER[ext]ifheadernotinagent.environment.execute(f"cat robot.{ext}")["output"]:return(False,f"robot.{ext} does not contain the required robot function. It should be defined as '{header}'.",)test_run_cmd=f"{self.run_cmd_round} robot.{ext} robot.{ext} -t 1"try:test_run=agent.environment.execute(test_run_cmd,timeout=10)["output"]exceptsubprocess.TimeoutExpired:return(False,f"Running robot.{ext} (with `{test_run_cmd}`) timed out (10 seconds). Please ensure your code runs efficiently.",)if"Some errors occurred:"intest_run:returnFalse,f"Running robot.{ext} (with `{test_run_cmd}`) resulted in errors:\n{test_run}"returnTrue,None