def test_bad_move_function(team_to_test): """ Test that having a move function that returns a bad type appends a FatalException. """ def stopping(b, state): return b.position def move0(b, state): return None def move1(b, state): return 0 def move3(b, state): return 0, 0, 0 def move4( b ): # TypeError: move4() takes 1 positional argument but 2 were given return (0, 0), 0 layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) def test_run_game(move): # Flips the order of the teams depending on team_to_test if team_to_test == 0: teams = [move, stopping] elif team_to_test == 1: teams = [stopping, move] return run_game(teams, layout_dict=l, max_rounds=10) other = 1 - team_to_test res = test_run_game(move0) assert res['gameover'] assert res['whowins'] == other assert res['fatal_errors'][team_to_test][0]['type'] == 'FatalException' assert res['fatal_errors'][team_to_test][0][ 'description'] == 'Exception in client (ValueError): Function move did not return a valid position: got None instead.' res = test_run_game(move1) assert res['gameover'] assert res['whowins'] == other assert res['fatal_errors'][team_to_test][0]['type'] == 'FatalException' assert res['fatal_errors'][team_to_test][0][ 'description'] == 'Exception in client (ValueError): Function move did not return a valid position: got 0 instead.' res = test_run_game(move3) assert res['gameover'] assert res['whowins'] == other assert res['fatal_errors'][team_to_test][0]['type'] == 'FatalException' assert res['fatal_errors'][team_to_test][0][ 'description'] == 'Exception in client (ValueError): Function move did not return a valid position: got (0, 0, 0) instead.' res = test_run_game(move4) assert res['gameover'] assert res['whowins'] == other assert res['fatal_errors'][team_to_test][0]['type'] == 'FatalException' assert "takes 1 positional argument but 2 were given" in res[ 'fatal_errors'][team_to_test][0]['description']
def test_initial_position(_n_test): """ Test that out test team receives the correct initial positions.""" layout_name, layout_string = get_random_layout() l = parse_layout(layout_string) initial_pos = initial_positions(l['walls']) def move(bot, state): if bot.is_blue and bot.turn == 0: assert bot._initial_position == initial_pos[0] assert bot.other._initial_position == initial_pos[2] assert bot.enemy[0]._initial_position == initial_pos[1] assert bot.enemy[1]._initial_position == initial_pos[3] if bot.is_blue and bot.turn == 1: assert bot._initial_position == initial_pos[2] assert bot.other._initial_position == initial_pos[0] assert bot.enemy[0]._initial_position == initial_pos[1] assert bot.enemy[1]._initial_position == initial_pos[3] if not bot.is_blue and bot.turn == 0: assert bot._initial_position == initial_pos[1] assert bot.other._initial_position == initial_pos[3] assert bot.enemy[0]._initial_position == initial_pos[0] assert bot.enemy[1]._initial_position == initial_pos[2] if not bot.is_blue and bot.turn == 1: assert bot._initial_position == initial_pos[3] assert bot.other._initial_position == initial_pos[1] assert bot.enemy[0]._initial_position == initial_pos[0] assert bot.enemy[1]._initial_position == initial_pos[2] return randomBot(bot, state) state = run_game([move, move], max_rounds=3, layout_dict=l) # assertions might have been caught in run_game # check that all is good assert state['fatal_errors'] == [[], []]
def test_minimal_game(): def move(b, s): return b.position layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) final_state = run_game([move, move], max_rounds=20, layout_dict=l) assert final_state['gameover'] is True assert final_state['score'] == [0, 0] assert final_state['round'] == 20
def test_invalid_setup_game_closes_players(): layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) # setup a remote demo game with "0" and "1" but bad max rounds state = setup_game(["0", "1"], layout_dict=l, max_rounds=0, allow_exceptions=True) assert state["gameover"] # Check that both processes have exited assert state["teams"][0].proc[0].wait(timeout=3) == 0 assert state["teams"][1].proc[0].wait(timeout=3) == 0
def test_minimal_remote_game(): def move(b, s): return b.position layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) final_state = run_game(["test/demo01_stopping.py", move], max_rounds=20, layout_dict=l) final_state = run_game(["test/demo01_stopping.py", 'test/demo02_random.py'], max_rounds=20, layout_dict=l) assert final_state['gameover'] is True assert final_state['score'] == [0, 0] assert final_state['round'] == 20
def test_non_existing_file(): # TODO: Change error message to be more meaningful layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) res = run_game(["blah", "nothing"], max_rounds=1, layout_dict=l) assert res['fatal_errors'][0][0] == { 'description': '("Could not load blah: No module named \'blah\'", \'ModuleNotFoundError\')', 'round': None, 'turn': 0, 'type': 'PlayerDisconnected' }
def test_remote_errors(tmp_path): # TODO: Change error messages to be more meaningful # we change to the tmp dir, to make our paths simpler syntax_error = dedent(""" def move(b, state) return b.position """) import_error = dedent(""" import does_not_exist def move(b, state): return b.position """) layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) with temp_wd(tmp_path): s_py = Path("s.py") s_py.write_text(syntax_error) i_py = Path("i.py") i_py.write_text(import_error) res = run_game([str(s_py), str(i_py)], layout_dict=l, max_rounds=20) # Error messages have changed in Python 3.10. We can only do approximate maching assert "SyntaxError" in res['fatal_errors'][0][0].pop('description') assert res['fatal_errors'][0][0] == { 'round': None, 'turn': 0, 'type': 'PlayerDisconnected' } # Both teams fail during setup: DRAW assert res['whowins'] == 2 res = run_game(["0", str(i_py)], layout_dict=l, max_rounds=20) # Error messages have changed in Python 3.10. We can only do approximate maching assert "ModuleNotFoundError" in res['fatal_errors'][1][0].pop( 'description') assert res['fatal_errors'][1][0] == { 'round': None, 'turn': 1, 'type': 'PlayerDisconnected' } assert res['whowins'] == 0 res = run_game([str(i_py), "1"], layout_dict=l, max_rounds=20) # Error messages have changed in Python 3.10. We can only do approximate maching assert "ModuleNotFoundError" in res['fatal_errors'][0][0].pop( 'description') assert res['fatal_errors'][0][0] == { 'round': None, 'turn': 0, 'type': 'PlayerDisconnected' } assert res['whowins'] == 1
def test_remote_errors(tmp_path): # TODO: Change error messages to be more meaningful # we change to the tmp dir, to make our paths simpler syntax_error = dedent(""" def move(b, state) return b.position, state """) import_error = dedent(""" import does_not_exist def move(b, state): return b.position, state """) layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) with temp_wd(tmp_path): s_py = Path("s.py") s_py.write_text(syntax_error) i_py = Path("i.py") i_py.write_text(import_error) res = run_game([str(s_py), str(i_py)], layout_dict=l, max_rounds=20) assert res['fatal_errors'][0][0] == { 'description': "('Could not load s.py: invalid syntax (s.py, line 2)', 'SyntaxError')", 'round': None, 'turn': 0, 'type': 'PlayerDisconnected' } # Both teams fail during setup: DRAW assert res['whowins'] == 2 res = run_game(["0", str(i_py)], layout_dict=l, max_rounds=20) assert res['fatal_errors'][1][0] == { 'description': '("Could not load i.py: No module named \'does_not_exist\'", \'ModuleNotFoundError\')', 'round': None, 'turn': 1, 'type': 'PlayerDisconnected' } assert res['whowins'] == 0 res = run_game([str(i_py), "1"], layout_dict=l, max_rounds=20) assert res['fatal_errors'][0][0] == { 'description': '("Could not load i.py: No module named \'does_not_exist\'", \'ModuleNotFoundError\')', 'round': None, 'turn': 0, 'type': 'PlayerDisconnected' } assert res['whowins'] == 1
def test_manual_remote_game_closes_players(): layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) # run a remote demo game with "0" and "1" state = setup_game(["0", "1"], layout_dict=l, max_rounds=10, allow_exceptions=True) assert not state["gameover"] while not state["gameover"]: # still running # still running assert state["teams"][0].proc[0].poll() is None assert state["teams"][1].proc[0].poll() is None state = play_turn(state) # Check that both processes have exited assert state["teams"][0].proc[0].wait(timeout=3) == 0 assert state["teams"][1].proc[0].wait(timeout=3) == 0
def test_minimal_losing_game_has_one_error(): def move0(b, s): if b.round == 1 and b._bot_index == 0: # trigger a bad move in the first round return (0, 0) else: return b.position def move1(b, s): return b.position layout_name, layout_string = layout.get_random_layout() l = layout.parse_layout(layout_string) final_state = run_game([move0, move1], max_rounds=20, layout_dict=l) assert final_state['gameover'] is True assert final_state['score'] == [0, 0] assert len(final_state['errors'][0]) == 1 assert len(final_state['errors'][1]) == 0 assert final_state['round'] == 20
def run_simulation(self): for game in range(self.n_sim): print "Game %i" % game self.layout = get_random_layout(filter="normal_without_dead_ends")[1] self.gm = GameMaster(self.layout, number_bots=4, game_time=self.game_time, seed=self.seed) self.gm.register_team(self.team0) self.gm.register_team(self.team1) self.gm.play() import pdb pdb.set_trace() winner = self.gm.game_state["team_wins"] if winner is not None: self.score[winner] += 1 win = "Team %i wins" % winner else: win = "None wins" print "%s game %i. Score so far %i:%i" % (win, game, self.score[0], self.score[1])
def __init__(self, layout=None, layoutfile=None, players=4, rounds=3000, host="", port=50007, local=False): if layout is None: if layoutfile: with open(layoutfile) as file: self.layout = file.read() else: self.layout = get_random_layout() else: self.layout = layout self.players = players self.rounds = rounds if local: self.host = None self.port = None else: self.host = host self.port = port self.server = None self.remote = None
def run_simulation(self): # run the actual simulation for a defined amount of runs for game in range(self.n_sim): print "Game %i" %game self.layout = get_random_layout(filter="normal_without_dead_ends")[1] self.gm = GameMaster(self.layout, number_bots=4, game_time=self.game_time, seed=self.seed) for t in self.teams: self.gm.register_team(SimpleTeam(t, self.teams[t][0], self.teams[t][1])) self.gm.play() #import pdb; pdb.set_trace() #Append statistics of the last game self.stats["winning_team"].append(self.gm.game_state["team_wins"]) self.stats["food_eaten"]["t0"].append(self.gm.game_state["food_count"][0]) self.stats["food_eaten"]["t1"].append(self.gm.game_state["food_count"][1]) self.stats["rounds"].append(self.gm.game_state["round_index"]) self.stats["bots_destroyed"].append(self.gm.game_state["bot_destroyed"]) self.stats["timeout_teams"]["t0"].append(self.gm.game_state["timeout_teams"][0]) self.stats["timeout_teams"]["t1"].append(self.gm.game_state["timeout_teams"][1]) self.stats["team_time"]["t0"].append(self.gm.game_state["team_time"][0]) self.stats["team_time"]["t1"].append(self.gm.game_state["team_time"][1]) self.stats["times_killed"]["t0"].append(self.gm.game_state["times_killed"][0]) self.stats["times_killed"]["t1"].append(self.gm.game_state["times_killed"][1]) self.stats["score"]["t0"].append(self.gm.universe.teams[0].score) self.stats["score"]["t1"].append(self.gm.universe.teams[1].score) winner = self.stats["winning_team"][-1] if winner is not None: self.score[winner] += 1 win = "Team %r wins" %self.gm.universe.teams[winner].name else: win = "None wins" print "%s game %i. Score so far %i:%i" %(win, game, self.score[0], self.score[1])
######## #####x## ##ba y# ######## """, ]) def test_initial_positions(simple_layout): parsed = layout.parse_layout(simple_layout) i_pos = initial_positions(parsed['walls'], parsed['shape']) expected = parsed['bots'] assert len(i_pos) == 4 assert i_pos == expected @pytest.mark.parametrize('layout_t', [layout.get_random_layout() for _ in range(30)]) def test_initial_positions_same_in_layout_random(layout_t): """Check initial positions are the same as what the layout says for 30 random layouts""" layout_name, layout_string = layout_t # get_random_layout returns a tuple of name and string parsed_l = layout.parse_layout(layout_string) exp = parsed_l["bots"] walls = parsed_l["walls"] shape = parsed_l["shape"] out = initial_positions(walls, shape) assert out == exp @pytest.mark.parametrize('layout_name', layout.get_available_layouts()) def test_initial_positions_same_in_layout(layout_name): """Check initial positions are the same as what the layout says for all layouts""" l = layout.get_layout_by_name(layout_name=layout_name)
""", # TODO: Should this even be a valid layout? """ ######## ######## ######## ######## """, ]) def test_no_initial_positions_possible(bad_layout): parsed = layout.parse_layout(bad_layout) with pytest.raises(ValueError): # TODO should probably already raise in parse_layout initial_positions(parsed['walls']) @pytest.mark.parametrize('layout_t', [layout.get_random_layout() for _ in range(30)]) def test_initial_positions_same_in_layout_random(layout_t): """Check initial positions are the same as what the layout says for 30 random layouts""" layout_name, layout_string = layout_t # get_random_layout returns a tuple of name and string parsed_l = layout.parse_layout(layout_string) exp = parsed_l["bots"] walls = parsed_l["walls"] out = initial_positions(walls) assert out == exp @pytest.mark.parametrize('layout_name', layout.get_available_layouts()) def test_initial_positions_same_in_layout(layout_name): """Check initial positions are the same as what the layout says for all layouts""" l = layout.get_layout_by_name(layout_name=layout_name) parsed_l = layout.parse_layout(l) exp = parsed_l["bots"]
""" We start a server using the SimpleServer class and a layout given by the specified layout file. """ from pelita.simplesetup import SimpleServer from pelita.layout import get_random_layout layout_name, layout_string = get_random_layout() server = SimpleServer(layout_string=layout_string, layout_name=layout_name) # For more control, we could also define a game with 8 Bots, # run 10000 rounds and want to receive connections on port # # server = SimpleServer(layout_string=layout_string, players=8, rounds=10000, port=61009, layout_name=layout_name) server.run()
# -*- coding: utf-8 -*- """ We start a server using the SimpleServer class and a layout given by the specified layout file. """ from pelita.simplesetup import SimpleServer from pelita.layout import get_random_layout layout_name, layout_string = get_random_layout() server = SimpleServer(layout_string=layout_string, layout_name=layout_name) # For more control, we could also define a game with 8 Bots, # run 10000 rounds and want to receive connections on port # # server = SimpleServer(layout_string=layout_string, players=8, rounds=10000, port=61009, layout_name=layout_name) server.run()
#!/usr/bin/python from pelita.game_master import GameMaster from pelita.player import SimpleTeam, StoppingPlayer from pelita.viewer import AsciiViewer from pelita.layout import get_random_layout from players import BFSPlayer, BasicDefensePlayer if __name__ == '__main__': name, layout = get_random_layout() gm = GameMaster(layout, 4, 200) gm.register_team(SimpleTeam(BFSPlayer(), BFSPlayer())) gm.register_team(SimpleTeam(BasicDefensePlayer(), BasicDefensePlayer())) gm.register_viewer(AsciiViewer()) gm.play()