def run_bots(): seed: int = int(input("Choose a Seed: ")) random.seed(seed) runs = 10 bots: List[Tuple[str]] = find_bots() with open("scoreboard.txt", "w+") as scorefile: print("file opened") scoreboard: Dict[str, float] = dict() for run in range(runs): seed = random.randint(0, 9999) print("Run number: ", run) team = round( (run + 1) / runs) * 2 - 1 #-1 (orange): first half, 1 (blue): second half play = make_playlist(bots, team) results_generator = run_playlist(play, seed=seed) for bot_info, result in zip(bots, results_generator): if not bot_info[0] in scoreboard: scoreboard[bot_info[0]] = 0 scoreboard[bot_info[0]] += result.grade.score for bot_name, path in bots: entry = bot_name + " = " + str(scoreboard[bot_name] / (runs + 1)) print(bot_name + " got an average score of:", scoreboard[bot_name] / (runs + 1)) scorefile.write(entry + "\n")
def run_matches(working_dir: WorkingDir, replay_preference: ReplayPreference): """ Runs all matches as specified by working_dir/match_configs_todo """ match_paths = list(working_dir.match_configs_todo.iterdir()) if not len(match_paths): logger.warning( f'No matches found. Add some using `autoleague generate_matches`') return logger.info(f'Going to run {len(match_paths)} matches') match_configs = [parse_match_config(p) for p in match_paths] playlist = [ MatchExercise(name=get_match_name(match_config), match_config_file_name=match_path.name, match_config=match_config, grader=MatchGrader(replay_monitor=ReplayMonitor( replay_preference=replay_preference), )) for match_config, match_path in zip(match_configs, match_paths) ] set_additional_website_code(PackageFiles.additional_website_code, working_dir.history_dir) for result in run_playlist(playlist): store_result(result, working_dir.history_dir) match_config_file_name = result.exercise.match_config_file_name shutil.move( working_dir.match_configs_todo / match_config_file_name, working_dir.match_configs_done / match_config_file_name, ) log_result(result, logger)
def test_no_patience_required(self): result_iter = run_playlist( [StrikerPatience(name='no patience required', car_start_x=-1000)]) results = list(result_iter) self.assertEqual(len(results), 1) result = results[0] self.assertEqual(result.exercise.name, 'no patience required') self.assertIsInstance(result.grade, Pass)
def test_use_once(self): ex = TurnAndDriveToBall(name='Turn to ball', steering_coefficient=4.) results = list(run_playlist([ex, ex])) self.assertEqual(len(results), 2) self.assertIsInstance(results[0].grade, Pass) self.assertIsInstance(results[1].grade, FailDueToExerciseException) self.assertTrue('meant to be used once', str(results[1].grade.exception))
def test_patience_required(self): result_iter = run_playlist([StrikerPatience(name='patience required')]) results = list(result_iter) self.assertEqual(len(results), 1) result = results[0] self.assertEqual(result.exercise.name, 'patience required') self.assertIsInstance( result.grade, Fail ) # If you make the bot is smarter, update this assert that we pass.
def test_kickoff(self): from rlbottraining.common_exercises.kickoff_exercise import make_default_playlist self.assertGrades( run_playlist(make_default_playlist()), # There are five kickoffs, one for each position, in the default playlist. [ 'PassDueToMovedBall', 'PassDueToMovedBall', 'PassDueToMovedBall', 'PassDueToMovedBall', 'PassDueToMovedBall' ])
def test_bakkes_mod_import(self): from rlbottraining.common_exercises.bakkesmod_import.bakkesmod_importer import make_default_playlist playlist = make_default_playlist() assert len(playlist) > 2 playlist = playlist[:2] # for making tests run quicker results = list(run_playlist(playlist)) self.assertEqual(len(results), 2) for result in results: # All of these exercises are too advanced for SimpleBot. self.assertIsInstance(result.grade, Fail)
def run_match( ld: LeagueDir, match_details: MatchDetails, bots: Mapping[BotID, BotConfigBundle], replay_preference: ReplayPreference ) -> Tuple[MatchResult, Optional[ReplayData]]: """ Run a match, wait for it to finish, and return the result. """ with setup_manager_context() as setup_manager: # Expose data to overlay make_overlay(ld, match_details, bots) # Prepare the match exercise print( f"Starting match: {match_details.blue} vs {match_details.orange}. Waiting for match to finish..." ) match = MatchExercise(name=match_details.name, match_config=match_details.to_config(bots), grader=MatchGrader(replay_monitor=ReplayMonitor( replay_preference=replay_preference), )) # If any bots have signed up for early start, give them 10 seconds. # This is typically enough for Scratch. setup_manager.early_start_seconds = 10 # For loop, but should only run exactly once for exercise_result in run_playlist( [match], setup_manager=setup_manager, render_policy=RenderPolicy.DEFAULT): replay_data = None # Warn if no replay was found replay_data = exercise_result.exercise.grader.replay_monitor.replay_data( ) if isinstance(exercise_result.grade, Fail) and replay_data.replay_id is None: print( f"WARNING: No replay was found for the match '{match_details.name}'." ) else: if replay_preference != ReplayPreference.NONE and replay_data.replay_path is not None: try: dst = ld.replays / f"{replay_data.replay_id}.replay" shutil.copy(replay_data.replay_path, dst) print( "Replay successfully copied to replays directory") except: pass match_result = confirm_match_result( exercise_result.exercise.grader.match_result) return match_result, replay_data
def test_rl_graders(self): from tests.test_exercises.rl_grader_exercises import make_default_playlist self.assertGrades( run_playlist(make_default_playlist()), [ 'FailDueToGroundHit', 'FailDueToTimeout', # Cant yet detect this case, should be FailDueToGroundHit 'FailDueToGroundHit', 'FailDueToTimeout', #'FailDueToGroundHit', #'FailDueToTimeout', ])
def test_dribbling(self): exercise = Dribbling('Dribbling') exercise.match_config.player_configs = [ PlayerConfig.bot_config( Path(__file__).absolute().parent.parent.parent / 'Derevo.cfg', Team.BLUE) ] result_iter = run_playlist([exercise]) results = list(result_iter) result = results[0] self.assertEqual(len(results), 1) self.assertEqual(result.exercise.name, 'Dribbling') self.assertIsInstance(result.grade, Pass)
def time_to_goal(steering_coefficient: float) -> float: ex = TurnAndDriveToBall( name= f'Turn to ball (steering_coefficient={steering_coefficient:.2f})', steering_coefficient=steering_coefficient) result = list(run_playlist([ex], setup_manager=setup_manager))[0] grade = result.grade assert isinstance( grade, GameTickPacketWrapperGrader.WrappedPass) or isinstance( grade, GameTickPacketWrapperGrader.WrappedFail ), f'Unexpected grade: {grade}' duration_seconds = grade.last_tick.game_info.seconds_elapsed - grade.first_tick.game_info.seconds_elapsed logger.debug(f'intermediate result: {duration_seconds}') return duration_seconds
def run_test_match(participant_1: str, participant_2: str, match_config) -> Optional[Grade]: # Play the match print(f'Starting test match: {participant_1} vs {participant_2}...') match = MatchExercise(name=f'{participant_1} vs {participant_2}', match_config=match_config, grader=AliveGrader()) with setup_manager_context() as setup_manager: # If any bots have signed up for early start, give them 10 seconds. # This is typically enough for Scratch. setup_manager.early_start_seconds = 10 # For loop, but should only run exactly once for exercise_result in run_playlist([match], setup_manager=setup_manager): return exercise_result.grade
def start_training_helper(playlist_path, bot, seed=None): global in_training if in_training: return in_training = True playlist = import_pack(playlist_path) for el in playlist: if isinstance(el, JSONExercise): el.set_bot(bot["path"]) else: el.match_config.player_configs = [ PlayerConfig.bot_config(Path(bot["path"]), Team.BLUE), ] for result in run_playlist(playlist, seed=seed or random.randint(1, 1000)): try: print_result(result) except Exception: print("An error occurred trying to run training exercise:") traceback.print_exc() time.sleep(1) # Allow bot to finish its action so it doesnt f**k up in_training = False
def test_defend_ball_rolling_towards_goal(self): exercises = [ DefendBallRollingTowardsGoal('DefendBallRollingTowardsGoal'), LineSave('LineSave'), TryNotToOwnGoal('TryNotToOwnGoal'), ] for ex in exercises: # The length of players in the match_config needs to match the number or spawns. # Replace with path to your bot or bots. ex.match_config.player_configs = [ PlayerConfig.bot_config( Path(__file__).absolute().parent.parent.parent / 'Derevo.cfg', Team.BLUE) ] result_iter = run_playlist(exercises) results = list(result_iter) self.assertEqual(len(results), 3) for result in results: self.assertIsInstance(result.grade, Pass)
def run_match(participant_1: str, participant_2: str, match_config, replay_preference: ReplayPreference) -> MatchResult: with setup_manager_context() as setup_manager: # Prepare the match exercise print( f'Starting match: {participant_1} vs {participant_2}. Waiting for match to finish...' ) match = MatchExercise( name=f'{participant_1} vs {participant_2}', match_config=match_config, grader=MatchGrader( mercy_rule=MercyRule( game_interface=setup_manager.game_interface), replay_monitor=ReplayMonitor( replay_preference=replay_preference), )) # If any bots have signed up for early start, give them 10 seconds. # This is typically enough for Scratch. setup_manager.early_start_seconds = 10 # For loop, but should only run exactly once for exercise_result in run_playlist( [match], setup_manager=setup_manager, render_policy=RenderPolicy.NO_TRAINING_RENDER): # Warn users if no replay was found if isinstance( exercise_result.grade, Fail ) and exercise_result.exercise.grader.replay_monitor.replay_id == None: print( f'WARNING: No replay was found for the match \'{participant_1} vs {participant_2}\'. Is Bakkesmod injected and \'Automatically save all replays\' enabled?' ) return exercise_result.exercise.grader.match_result
def test_bronze_striker(self): from rlbottraining.common_exercises.bronze_striker import make_default_playlist result_iter = run_playlist(make_default_playlist()) result = next(result_iter) self.assertEqual(result.exercise.name, 'Facing ball') self.assertIsInstance(result.grade, Pass) result = next(result_iter) self.assertEqual(result.exercise.name, 'Rolling Shot') self.assertIsInstance(result.grade, Pass) result = next(result_iter) self.assertEqual(result.exercise.name, 'Facing directly away from ball') self.assertIsInstance(result.grade, Fail) # SimpleBot isn't smart enough. result = next(result_iter) self.assertEqual(result.exercise.name, 'Facing away from ball 1') self.assertIsInstance(result.grade, Pass) result = next(result_iter) self.assertEqual(result.exercise.name, 'Facing away from ball 2') self.assertIsInstance(result.grade, Pass) result = next(result_iter) self.assertEqual(result.exercise.name, 'Facing away from opponents goal') self.assertIsInstance(result.grade, FailOnTimeout.FailDueToTimeout) with self.assertRaises(StopIteration): next(result_iter) with self.assertRaises(StopIteration): next(result_iter)
def test_dribbling(self): from rlbottraining.common_exercises.dribbling import make_default_playlist self.assertGrades(run_playlist(make_default_playlist()), ['FailDueToTimeout'])
def test_silver_goalie(self): from rlbottraining.common_exercises.silver_goalie import make_default_playlist self.assertGrades(run_playlist(make_default_playlist()), ['WrongGoalFail', 'WrongGoalFail', 'WrongGoalFail'])
def run_league_play(working_dir: WorkingDir, odd_week: bool, replay_preference: ReplayPreference): """ Run a league play event by running round robins for half the divisions. When done, a new ladder file is created. """ bots = load_all_bots(working_dir) ladder = Ladder.read(working_dir.ladder) # We need the result of every match to create the next ladder. For each match in each round robin, if a result # exist already, it will be parsed, if it doesn't exist, it will be played. # When all results have been found, the new ladder can be completed and saved. new_ladder = Ladder(ladder.bots) event_results = [] # playing_division_indices contains either even or odd indices. # If there is only one division always play that division (division 0, quantum). playing_division_indices = range( ladder.division_count())[int(odd_week) % 2::2] if ladder.division_count() > 1 else [0] # The divisions play in reverse order, so quantum/overclocked division plays last for div_index in playing_division_indices[::-1]: print( f'Starting round robin for the {Ladder.DIVISION_NAMES[div_index]} division' ) rr_bots = ladder.round_robin_participants(div_index) rr_matches = generate_round_robin_matches(rr_bots) rr_results = [] for match_participants in rr_matches: # Check if match has already been play, i.e. the result file already exist result_path = working_dir.get_match_result(div_index, match_participants[0], match_participants[1]) if result_path.exists(): # Found existing result try: print(f'Found existing result {result_path.name}') result = MatchResult.read(result_path) rr_results.append(result) except Exception as e: print( f'Error loading result {result_path.name}. Fix/delete the result and run script again.' ) raise e else: assert match_participants[ 0] in bots, f'{match_participants[0]} was not found in \'{working_dir.bots}\'' assert match_participants[ 1] in bots, f'{match_participants[1]} was not found in \'{working_dir.bots}\'' # Play the match print( f'Starting match: {match_participants[0]} vs {match_participants[1]}. Waiting for match to finish...' ) match_config = make_match_config(working_dir, bots[match_participants[0]], bots[match_participants[1]]) match = MatchExercise( name=f'{match_participants[0]} vs {match_participants[1]}', match_config=match_config, grader=MatchGrader(replay_monitor=ReplayMonitor( replay_preference=replay_preference), )) # Let overlay know which match we are about to start overlay_data = OverlayData( div_index, bots[match_participants[0]].config_path, bots[match_participants[1]].config_path) overlay_data.write(working_dir.overlay_interface) with setup_manager_context() as setup_manager: # Disable rendering by replacing renderer with a renderer that does nothing setup_manager.game_interface.renderer = FakeRenderer() # For loop, but should only run exactly once for exercise_result in run_playlist( [match], setup_manager=setup_manager): # Warn users if no replay was found if isinstance( exercise_result.grade, Fail ) and exercise_result.exercise.grader.replay_monitor.replay_id == None: print( f'WARNING: No replay was found for the match \'{match_participants[0]} vs {match_participants[1]}\'. Is Bakkesmod injected and \'Automatically save all replays\' enabled?' ) # Save result in file result = exercise_result.exercise.grader.match_result result.write(result_path) print( f'Match finished {result.blue_goals}-{result.orange_goals}. Saved result as {result_path}' ) rr_results.append(result) # Let the winner celebrate and the scoreboard show for a few seconds. # This sleep not required. time.sleep(8) print(f'{Ladder.DIVISION_NAMES[div_index]} division done') event_results.append(rr_results) # Find bots' overall score for the round robin overall_scores = [ CombinedScore.calc_score(bot, rr_results) for bot in rr_bots ] sorted_overall_scores = sorted(overall_scores)[::-1] print( f'Bots\' overall performance in {Ladder.DIVISION_NAMES[div_index]} division:' ) for score in sorted_overall_scores: print( f'> {score.bot}: goal_diff={score.goal_diff}, goals={score.goals}, shots={score.shots}, saves={score.saves}, points={score.points}' ) # Rearrange bots in division on the new ladder first_bot_index = new_ladder.division_size * div_index bots_to_rearrange = len(rr_bots) for i in range(bots_to_rearrange): new_ladder.bots[first_bot_index + i] = sorted_overall_scores[i].bot # Save new ladder Ladder.write(new_ladder, working_dir.new_ladder) print(f'Done. Saved new ladder as {working_dir.new_ladder.name}') # Remove overlay interface file now that we are done if working_dir.overlay_interface.exists(): working_dir.overlay_interface.unlink() return new_ladder
def test_silver_striker(self): from rlbottraining.common_exercises.silver_striker import make_default_playlist self.assertGrades(run_playlist(make_default_playlist()), ['FailDueToTimeout'])
velocity = (rng.normalvariate(0, 1) for _ in range(3)) norm = sum(x**2 for x in velocity)**0.5 car_physics.angular_velocity = Vector3(*(x / norm * 5.5 for x in velocity)) ball_state = BallState(physics=Physics(velocity=Vector3(0, 0, 20), location=Vector3(500, 0, 800))) return GameState(cars={0: CarState(physics=car_physics)}, ball=ball_state) if __name__ == '__main__': current_path = Path(__file__).absolute().parent sys.path.insert(0, str( current_path.parent.parent)) # this is for first process imports from common_graders.matchcomms_grader import MatchcommsGrader match_config = make_match_config_with_bots( blue_bots=[current_path / 'simulation_agent.cfg']) exercises = [ RotationExercise(name='simulate rotation', grader=MatchcommsGrader(), match_config=match_config) for _ in range(100) ] print(list(exercise_runner.run_playlist(exercises)))
rng.uniform(-math.pi, math.pi), rng.uniform(-math.pi, math.pi)) car_physics.location = Vector3(rng.uniform(-1000, 1000), rng.uniform(-1000, 1000), rng.uniform(50, 1400)) car_physics.angular_velocity = Vector3(rng.uniform(-5, 5), rng.uniform(-5, 5), rng.uniform(-5, 5)) ball_state = BallState(physics=Physics(velocity=Vector3(0, 0, 20), location=Vector3(0, 0, 800))) return GameState(cars={0: CarState(physics=car_physics)}, ball=ball_state) if __name__ == '__main__': current_path = Path(__file__).absolute().parent sys.path.insert(0, str( current_path.parent.parent)) # this is for first process imports from common_graders.matchcomms_grader import MatchcommsGrader match_config = make_match_config_with_bots( blue_bots=[current_path / 'face_vector_agent.cfg']) exercise = RotationExercise(name='rotate to target', grader=MatchcommsGrader(), match_config=match_config) print(next(exercise_runner.run_playlist([exercise])))
def test_bronze_goalie(self): from rlbottraining.common_exercises.bronze_goalie import make_default_playlist self.assertGrades(run_playlist(make_default_playlist()), ['Pass'])