|
10 | 10 | from codeclash.constants import RESULT_TIE |
11 | 11 | from codeclash.games.game import CodeGame, RoundStats |
12 | 12 |
|
| 13 | +MAP_EXT_TO_HEADER = { |
| 14 | + "js": "function robot(state, unit) {", |
| 15 | + "py": "def robot(state, unit):", |
| 16 | +} |
| 17 | +ROBOTRUMBLE_HIDDEN_EXEC = ".codeclash_exec" |
| 18 | + |
13 | 19 |
|
14 | 20 | class RobotRumbleGame(CodeGame): |
15 | 21 | name: str = "RobotRumble" |
@@ -51,7 +57,10 @@ def _run_single_simulation(self, agents: list[Player], idx: int, cmd: str): |
51 | 57 |
|
52 | 58 | def execute_round(self, agents: list[Player]): |
53 | 59 | self.logger.info(f"Running game with players: {[agent.name for agent in agents]}") |
54 | | - args = [f"/{agent.name}/{self.submission}" for agent in agents] |
| 60 | + args = [] |
| 61 | + for agent in agents: |
| 62 | + executable = agent.environment.execute(f"cat {ROBOTRUMBLE_HIDDEN_EXEC}")["output"].strip() |
| 63 | + args.append(f"/{agent.name}/{executable}") |
55 | 64 | cmd = f"{self.run_cmd_round} {shlex.join(args)}" |
56 | 65 | self.logger.info(f"Running game: {cmd}") |
57 | 66 |
|
@@ -131,21 +140,33 @@ def get_results(self, agents: list[Player], round_num: int, stats: RoundStats): |
131 | 140 | stats.player_stats[player].score = score |
132 | 141 |
|
133 | 142 | def validate_code(self, agent: Player) -> tuple[bool, str | None]: |
134 | | - if self.submission not in agent.environment.execute("ls")["output"]: |
135 | | - return False, f"There should be a `{self.submission}` file" |
136 | | - if "function robot(state, unit) {" not in agent.environment.execute(f"cat {self.submission}")["output"]: |
| 143 | + # Determine if robot.js or robot.py exists |
| 144 | + ext, exists = None, False |
| 145 | + for possible_ext in MAP_EXT_TO_HEADER.keys(): |
| 146 | + exists_output = agent.environment.execute(f"test -f robot.{possible_ext} && echo 'exists'")["output"] |
| 147 | + if "exists" == exists_output.strip(): |
| 148 | + ext = possible_ext |
| 149 | + exists = True |
| 150 | + break |
| 151 | + if not exists: |
| 152 | + return False, "There should be a `robot.js` or `robot.py` file" |
| 153 | + agent.environment.execute(f'echo "robot.{ext}" > {ROBOTRUMBLE_HIDDEN_EXEC}') |
| 154 | + |
| 155 | + # Check that the robot function is defined |
| 156 | + header = MAP_EXT_TO_HEADER[ext] |
| 157 | + if header not in agent.environment.execute(f"cat robot.{ext}")["output"]: |
137 | 158 | return ( |
138 | 159 | False, |
139 | | - f"{self.submission} does not contain the required robot function. It should be defined as 'function robot(state, unit) {{ ... }}'.", |
| 160 | + f"robot.{ext} does not contain the required robot function. It should be defined as '{header}'.", |
140 | 161 | ) |
141 | | - test_run_cmd = f"{self.run_cmd_round} {self.submission} {self.submission} -t 1" |
| 162 | + test_run_cmd = f"{self.run_cmd_round} robot.{ext} robot.{ext} -t 1" |
142 | 163 | try: |
143 | | - test_run = agent.environment.execute(test_run_cmd, timeout=60)["output"] |
| 164 | + test_run = agent.environment.execute(test_run_cmd, timeout=10)["output"] |
144 | 165 | except subprocess.TimeoutExpired: |
145 | 166 | return ( |
146 | 167 | False, |
147 | | - f"Running {self.submission} (with `{test_run_cmd}`) timed out (60 seconds). Please ensure your code runs efficiently.", |
| 168 | + f"Running robot.{ext} (with `{test_run_cmd}`) timed out (10 seconds). Please ensure your code runs efficiently.", |
148 | 169 | ) |
149 | 170 | if "Some errors occurred:" in test_run: |
150 | | - return False, f"Running {self.submission} (with `{test_run_cmd}`) resulted in errors:\n{test_run}" |
| 171 | + return False, f"Running robot.{ext} (with `{test_run_cmd}`) resulted in errors:\n{test_run}" |
151 | 172 | return True, None |
0 commit comments