def setUp(self): players = [ PlayerAI(0), PlayerAI(1), PlayerAI(2), ] self.referee = Referee(players)
def test_handle_player_timeout() -> None: ref = Referee() assert ref._handle_player_timeout("white", lambda: fast_function_test()) == 3 assert ref._handle_player_timeout("black", lambda: slow_function_test()) == None assert ref._cheaters == {"black"}
def __match_against_rest(self, player, opponents): """ Match given player to the given opponents, updating the meet ups. :param player: Player, player :param opponents: [Player, ...], opponents of player """ for opponent in opponents: if player.get_id() in self.__misbehaved_players: break if opponent.get_id() in self.__misbehaved_players: continue referee = Referee(player, opponent, time_limit=5, observers=self.__observers) self.__notify_of_opponents(player, opponent) series_result = referee.run_games(3) # Penalize loser if game ended unfairly if series_result.condition is not GameOverCondition.FairGame: self.__handle_misbehaving_player(series_result.loser.player) self.__meet_ups.append(series_result)
def start_game(self): player_colors = [] for color, player_info in self.connections.items(): player_proxy = PlayerProxy(player_info[0], color, player_info[1], player_info[2]) self.player_proxies.append(player_proxy) player_colors.append(color) self.referee = Referee(self.player_proxies, self.board, self.rule_checker, self.deck) self.send_all_players(json.dumps(["setup", player_colors])) logging.info("Running game . . . ") return self.referee.run_game()
def run_game(players, output_index, winner_list, cheater_list, failed_list): ref = Referee(players) game_output = ref.run_game() try: winner_list[output_index] = game_output["winners"] cheater_list[output_index] = game_output["cheaters"] failed_list[output_index] = game_output["failed"] return True except IndexError: return False
def test_notify_player_placement(self): state = self.setup() player_1_component = PlayerComponent() player_2_component = PlayerComponent() ref = Referee(players=[player_1_component, player_2_component], num_rows=4, num_cols=3) ref.notify_player_placement() expected_state = state.add_penguin(0, 0, 'red') self.assertTrue(ref.state.is_equal(expected_state))
def run_game(self): """ prompt players for moves in order of their position in the players array -their move is determined by their strategies -run the game on each player's move until the game ends need to have a ref set up """ log.info("running game") referee = Referee(self.players) while referee.run_turn(): pass
def test_notify_player_kicked(self): player_1_component = PlayerComponent() player_2_component = PlayerComponent() player_1_component.notify_kicked = MagicMock() ref = Referee(players=[player_1_component, player_2_component], num_rows=4, num_cols=3) ref.notify_player_kicked(player=player_1_component) player_1_component.notify_kicked.assert_called_once_with()
def render_results(inputs): """ Performs placements and returns their results. """ placements = [PlacementFactory.create(x) for x in inputs] players = [] for i, placement in enumerate(placements): p = Player(name=str(i)) p.color = placement.color players.append(p) ref = Referee(players) ref.add_placements(placements) return observer.render_board(ref.board, ref.players)
def test_notify_player_placement_invalid_movement(self): state = self.setup() state = state.add_penguin(row=0, col=0, color="red") state = state.add_penguin(row=1, col=1, color="white") state = state.finalize() expected_action = Action(start=Coordinate(row=0, col=0), end=Coordinate(row=3, col=2), player_color="red") not_expected_action = Action(start=Coordinate(row=1, col=1), end=Coordinate(row=2, col=2), player_color="white") mocked_strategy_player1 = GenericStrategyComponent() mocked_strategy_player1.choose_action_from_state = MagicMock( return_value=expected_action) mocked_strategy_player2 = GenericStrategyComponent() mocked_strategy_player2.choose_action_from_state = MagicMock( return_value=not_expected_action) player_1_component = PlayerComponent(strategy=mocked_strategy_player1) player_2_component = PlayerComponent(strategy=mocked_strategy_player2) ref = Referee(players=[player_1_component, player_2_component], num_rows=4, num_cols=3) expected = state.kick_player(player_to_kick=state.current_player) ref.state = state ref.end_penguin_placement() ref.notify_players_movement() actual = ref.state self.assertTrue(actual.is_equal(expected))
def test_player_error(self): players = [ ErrorPlayer(), PlayerAI(1), PlayerAI(2), ] ref = Referee(players) ref.run_placement() self.assertEqual(ref.state.get_game_phase(), Game_Phase.PLAYING) self.assertEqual(ref.state.players[0].toDict(), { 'color': 'g', 'score': 0, 'places': [(0, 0), (0, 2), (0, 4), (1, 1)] }) self.assertEqual(ref.state.players[1].toDict(), { 'color': 'b', 'score': 0, 'places': [(0, 1), (0, 3), (1, 0), (1, 2)] })
def test_notify_player_placement_invalid(self): state = self.setup() expected_placement = Coordinate(row=5, col=5) mocked_strategy_player1 = GenericStrategyComponent() mocked_strategy_player1.place_penguin = MagicMock( return_value=expected_placement) player_1_component = PlayerComponent(strategy=mocked_strategy_player1) player_2_component = PlayerComponent() ref = Referee(players=[player_1_component, player_2_component], num_rows=4, num_cols=3) expected = state.kick_player(player_to_kick=state.current_player) ref.notify_player_placement() self.assertTrue(ref.state.is_equal(expected))
def run_game(names): players = [Player(name=name, age=i) for i, name in enumerate(names)] ref = Referee(players=players) while ref.run_turn(): pass overall_losers, overall_winners = [], [] for round_number in reversed(sorted(ref.dead.keys())): results = ref.dead[round_number] winners = [] for player, reason in results: (overall_losers if reason is PlayerState.EJECTED else winners).append(player.name) if winners: overall_winners.append(winners) return {"losers": overall_losers, "winners": overall_winners}
def test_end_game(self): state = self.setup() state = state.finalize() state.end_game() player_1_component = PlayerComponent() player_2_component = PlayerComponent() player_1_component.notify_game_over = MagicMock() player_2_component.notify_game_over = MagicMock() ref = Referee(players=[player_1_component, player_2_component], num_rows=4, num_cols=3) ref.end_game() player_1_component.notify_game_over.assert_called_once_with() player_2_component.notify_game_over.assert_called_once_with() self.assertTrue(state.is_equal(ref.state))
def render_intermediate(inputs, requested): placements = [PlacementFactory.create(x) for x in inputs + [requested[0]]] players = [] for i, placement in enumerate(placements): p = Player(name=str(i)) p.color = placement.color players.append(p) ref = Referee(players) ref.add_placements(placements[:-1]) next_move = placements[-1] ref.players_by_color[next_move.color].tile_hand = [ Tile.Builder.build(i).readonly() for i in requested[1:] ] ref.players_by_color[next_move.color].strategy = Predetermined(next_move) ref.turn_index = ref.turn_order.index( ref.players_by_color[next_move.color]) return observer.render_board(ref.board, ref.players, ref.turn)
def _initialize_ref(self) -> Referee: """ Sets up a ref to run a game. """ ref = Referee() ref.set_rule_checker(RuleChecker()) ref.set_tile_iterator(deterministic_tile_iterator()) return ref
def test_get_tiles() -> None: ref = Referee() ref.set_tile_iterator(deterministic_tile_iterator()) assert ref._get_tiles(3) == [ index_to_tile(0), index_to_tile(1), index_to_tile(2) ] assert [tile_to_index(t) for t in ref._get_tiles(35)] == list(range(3, 35)) + [ 0, 1, 2, ] assert len(ref._get_tiles(123)) == 123
class TestReferee(unittest.TestCase): def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) self.state = None def setUp(self): players = [ PlayerAI(0), PlayerAI(1), PlayerAI(2), ] self.referee = Referee(players) def test_constructor(self): self.assertEqual(len(self.referee.state.get_board_tiles()), 5) self.assertEqual(len(self.referee.state.get_board_tiles()[0]), 5) self.assertEqual(self.referee.state.players[0].toDict(), { 'color': 'r', 'score': 0, 'places': [] }) self.assertEqual(self.referee.state.players[1].toDict(), { 'color': 'g', 'score': 0, 'places': [] }) self.assertEqual(self.referee.state.players[2].toDict(), { 'color': 'b', 'score': 0, 'places': [] }) def test_run_placement(self): self.referee.run_placement() self.assertEqual(self.referee.state.get_game_phase(), Game_Phase.PLAYING) self.assertEqual(self.referee.state.players[0].toDict(), { 'color': 'r', 'score': 0, 'places': [(0, 0), (0, 3), (1, 1)] }) self.assertEqual(self.referee.state.players[1].toDict(), { 'color': 'g', 'score': 0, 'places': [(0, 1), (0, 4), (1, 2)] }) self.assertEqual(self.referee.state.players[2].toDict(), { 'color': 'b', 'score': 0, 'places': [(0, 2), (1, 0), (1, 3)] }) def test_run(self): self.referee.run_game() self.assertEqual(self.referee.state.get_game_phase(), Game_Phase.GAME_OVER) def test_remove_player(self): self.referee.remove_player(0) self.assertEqual(self.referee.state.players[0].toDict(), { 'color': 'g', 'score': 0, 'places': [] }) self.assertEqual(self.referee.state.players[1].toDict(), { 'color': 'b', 'score': 0, 'places': [] }) self.assertEqual(self.referee.players[0].turn_idx, 0) def test_remove_cheater(self): self.referee.update_game_state([[-1, 0]], 0) self.assertEqual(self.referee.state.players[0].toDict(), { 'color': 'g', 'score': 0, 'places': [] }) self.assertEqual(self.referee.state.players[1].toDict(), { 'color': 'b', 'score': 0, 'places': [] }) self.assertEqual(self.referee.players[0].turn_idx, 0) def test_player_error(self): players = [ ErrorPlayer(), PlayerAI(1), PlayerAI(2), ] ref = Referee(players) ref.run_placement() self.assertEqual(ref.state.get_game_phase(), Game_Phase.PLAYING) self.assertEqual(ref.state.players[0].toDict(), { 'color': 'g', 'score': 0, 'places': [(0, 0), (0, 2), (0, 4), (1, 1)] }) self.assertEqual(ref.state.players[1].toDict(), { 'color': 'b', 'score': 0, 'places': [(0, 1), (0, 3), (1, 0), (1, 2)] }) def test_update_game_state(self): self.referee.update_game_state([[0, 0]], 0) self.assertEqual(self.referee.state.players[0].toDict(), { 'color': 'r', 'score': 0, 'places': [(0, 0)] }) self.assertEqual(self.referee.state.players[1].toDict(), { 'color': 'g', 'score': 0, 'places': [] }) self.assertEqual(self.referee.state.players[2].toDict(), { 'color': 'b', 'score': 0, 'places': [] }) self.assertEqual(self.referee.players[0].state.players[0].toDict(), { 'color': 'r', 'score': 0, 'places': [(0, 0)] })
def make_ref() -> Referee: ref = Referee() ref.set_rule_checker(RuleChecker()) return ref
def test_run_game_without_init() -> None: ref = Referee() r = ref.run_game() assert r.is_error() assert r.error() == "must add players to this referee" assert ref.set_players(make_players(3)).is_ok() r = ref.run_game() assert r.is_error() assert r.error() == "must add a rule checker to this referee" ref.set_rule_checker(RuleChecker()) r = ref.run_game() assert r.is_error() assert r.error() == "must add a tile iterator to this referee" ref.set_tile_iterator(deterministic_tile_iterator()) r = ref.run_game() assert r.is_ok()
import sys import inspect current_dir = os.path.dirname( os.path.abspath(inspect.getfile(inspect.currentframe()))) parent_dir = os.path.dirname(current_dir) sys.path.insert(0, parent_dir) import json from Admin.referee import Referee from Common.board import Board import Common.tile from Common.tile_conversion import Converter from Player.player import DumbPlayer from Common.rules import RuleChecker color = ["white", "black", "red", "green", "blue"] if __name__ == "__main__": input_content = sys.stdin.readline() json_array = json.loads(input_content) if len(json_array) > 5 or len(json_array) < 3: raise Exception("Must have 3 to 5 players.") # Construct players player_list = [] for i in range(len(json_array)): player_list.append(DumbPlayer(json_array[i], color[i])) game_board = Board() rule_checker = RuleChecker() deck = Converter().generate_tile_dictionary() manager = Referee(player_list, game_board, rule_checker, deck) win_order, elimination = manager.run_game() print(json.dumps({"winners": win_order, "losers": elimination}))
def random_crashing_referee(random_player_one, crashing_player_one): return Referee(random_player_one, crashing_player_one, observers=[])
def misbehaving_random_referee(random_player_one, misbehaving_player_one): return Referee(misbehaving_player_one, random_player_one, observers=[])
def random_misbehaving_referee(random_player_one, misbehaving_player_one): return Referee(random_player_one, misbehaving_player_one, time_limit=1, observers=[])
def infinite_random_referee(random_player_one, infinite_player_one): return Referee(infinite_player_one, random_player_one, time_limit=1, observers=[])
def random_random_referee(random_player_one, random_player_two): return Referee(random_player_one, random_player_two, time_limit=1, observers=[])
def test_get_tiles_error() -> None: ref = Referee() with pytest.raises(ValueError): ref._get_tiles(5)
def init_ref(instrs): placements = [PlacementFactory.create(x) for x in instrs] ref = Referee() ref.add_placements(placements) return ref
class TsuroServer: EOF = "\x04" def __init__(self, ip, port): self.ip = ip self.port = port self.player_proxies = [] self.connections = {} self.board = Board() self.rule_checker = RuleChecker() self.referee = None self.colors = ["white", "black", "red", "green", "blue"] self.deck = Converter().generate_tile_dictionary() try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.bind((ip, int(port))) except Exception as e: print("Failed Connection, shutting down.", e) return enough_players = self.wait_for_players() if enough_players: result = self.start_game() self.send_all_players(json.dumps(["game over", result])) print(result) # wait until there are 3 players then 30 seconds until max 5 players def wait_for_players(self): start_time = time.time() end_time = start_time + 5*60 self.socket.settimeout(0.2) self.socket.listen() # Wait for at most 5 minutes while len(self.connections) < 3 and time.time() < end_time: self.accept_player() logging.info("First round of waiting for players has finished") # If not enough players joined after 5 minutes, stop server if len(self.connections) < 3: logging.info("Did not get enough players for a game of Tsuro, shutting down server") return False logging.info("Connected with three players, waiting 30 seconds for more") # Wait for 30 more seconds for more players to join before starting the game start_time = time.time() end_time = start_time + 30 while len(self.connections) < 5 and time.time() < end_time: self.accept_player() logging.info("Second round of waiting for players has finished") return True # Accept tcp connection and verify correct player connection message def accept_player(self): try: conn, addr = self.socket.accept() received_msg = self.recv_connect_message(conn) conn_msg = json.loads(received_msg) name = self.process_connect_message(conn_msg) logging.info("Player " + name + " has connected") except socket.timeout: return False except Exception as e: logging.exception("Failed to connect player after receiving connect message") return False color = self.colors[len(self.connections)] self.connections[color] = [name, conn, addr] conn.sendall(json.dumps(["setup", color]).encode("ascii")) logging.info("Player " + name + " has been given color " + color) return True # Receive and return player's connection message def recv_connect_message(self, conn): total_data = [] while True: data = conn.recv(1024).decode("ascii") if '\n' in data: total_data.append(data[:data.find('\n')]) break else: total_data.append(data) return ''.join(total_data) # Process player's connection message and return player's name def process_connect_message(self, message): if len(message) == 2 and message[0] == "tsuro-connect" and isinstance(message[1], str): return message[1] else: logging.exception("Received bad connection message") raise Exception("Bad connect message") # Starts the game after players join the game def start_game(self): player_colors = [] for color, player_info in self.connections.items(): player_proxy = PlayerProxy(player_info[0], color, player_info[1], player_info[2]) self.player_proxies.append(player_proxy) player_colors.append(color) self.referee = Referee(self.player_proxies, self.board, self.rule_checker, self.deck) self.send_all_players(json.dumps(["setup", player_colors])) logging.info("Running game . . . ") return self.referee.run_game() # Sends the message to all connected players def send_all_players(self, msg): for color, player_info in self.connections.items(): try: player_info[1].sendall(msg.encode("ascii")) logging.info("Player " + color + " (" + player_info[0] + ") " + "was sent " + msg) except Exception as e: logging.info("send all players: " + e) logging.info("Failed to send message to player " + player_info[0])