Example #1
0
    def test_normal_run_n_games(self):
        """test a normal game series between two good players
        """

        player1 = LegitPlayer()
        player1.end_of_game = mock.MagicMock()
        player1.get_name = mock.MagicMock(return_value="p1")

        player2 = LegitPlayer()
        player2.end_of_game = mock.MagicMock()
        player2.get_name = mock.MagicMock(return_value="p2")

        player1guard = PlayerGuard(player1)
        player2guard = PlayerGuard(player2)

        uuids_to_player = {
            self.uuidp1: player1guard,
            self.uuidp2: player2guard
        }
        ref = Referee(uuids_to_player, self.uuids_to_name, self.obs_man)
        bad_players, game_results = ref.run_n_games(3)

        self.assertEqual(player1.end_of_game.call_count, 3)
        self.assertEqual(player2.end_of_game.call_count, 3)
        player1.end_of_game.assert_called_with("p1")
        player2.end_of_game.assert_called_with("p1")
        self.assertEqual(bad_players, [])
        self.assertEqual(game_results, [self.uuidp1, self.uuidp2, self.uuidp1])
Example #2
0
    def test_game_invalid_placements(self):
        """test that a player who gives invalid placements loses
        test that end_of_game is called on both players
        """

        player1 = LegitPlayer()
        player1.end_of_game = mock.MagicMock()

        player2 = BadPlacementPlayer()
        player2.end_of_game = mock.MagicMock()

        player1guard = PlayerGuard(player1)
        player2guard = PlayerGuard(player2)
        uuids_to_player = {
            self.uuidp1: player1guard,
            self.uuidp2: player2guard
        }
        ref = Referee(uuids_to_player, self.uuids_to_name, self.obs_man)

        result = ref.run_game()

        player1.end_of_game.assert_called_once_with("p1")
        player2.end_of_game.assert_not_called()

        bad_players, game_results = result
        expected_bad_players = [self.uuidp2]
        for actual, expected in zip(bad_players, expected_bad_players):
            self.assertEqual(actual, expected)
        expected_game_results = [self.uuidp1]
        for actual, expected in zip(game_results, expected_game_results):
            self.assertEqual(actual, expected)
Example #3
0
    def setUp(self):
        self.p1name = "p1"
        self.uuidp1 = uuid.UUID('00000000000000000000000000000000')
        self.player1 = LegitPlayer()
        self.player1.end_of_game = mock.MagicMock()
        self.player1.get_name = mock.MagicMock(return_value=self.p1name)

        self.p2name = "p2"
        self.uuidp2 = uuid.UUID('11111111111111111111111111111111')
        self.player2 = LegitPlayer()
        self.player2.end_of_game = mock.MagicMock()
        self.player2.get_name = mock.MagicMock(return_value=self.p2name)

        self.obs_man = ObserverManager()
        self.uuids_to_name = {
            self.uuidp1: self.p1name,
            self.uuidp2: self.p2name
        }
        self.player1guard = PlayerGuard(self.player1)
        self.player2guard = PlayerGuard(self.player2)
        self.uuids_to_player = {
            self.uuidp1: self.player1guard,
            self.uuidp2: self.player2guard
        }
        self.ref = Referee(self.uuids_to_player, self.uuids_to_name,
                           self.obs_man)
Example #4
0
    def test_n_games_malformed_turn(self):
        """tests that a player who gives a malformed turn
        loses and end_of_games is not called on it in n games
        """
        player1 = LegitPlayer()
        player1.end_of_game = mock.MagicMock()
        player1.get_name = mock.MagicMock(return_value="p1")

        player2 = LegitPlayer()
        player2.end_of_game = mock.MagicMock()
        player2.get_name = mock.MagicMock(return_value="p2")
        player2.play_turn = mock.MagicMock(return_value="lolol")

        player1guard = PlayerGuard(player1)
        player2guard = PlayerGuard(player2)
        uuids_to_player = {
            self.uuidp1: player1guard,
            self.uuidp2: player2guard
        }
        ref = Referee(uuids_to_player, self.uuids_to_name, self.obs_man)

        result = ref.run_n_games(3)

        player1.end_of_game.assert_called_once_with("p1")
        player2.end_of_game.assert_not_called()
        bad_players, game_results = result
        expected_bad_players = [self.uuidp2]
        for actual, expected in zip(bad_players, expected_bad_players):
            self.assertEqual(actual, expected)
        expected_game_results = [self.uuidp1]
        for actual, expected in zip(game_results, expected_game_results):
            self.assertEqual(actual, expected)
Example #5
0
    def test_n_games_invalid_turns(self):
        """tests that a player who gives invalid turns
        always loses in a series of n games but all games are played
        """
        player1 = LegitPlayer()
        player1.end_of_game = mock.MagicMock()

        player2 = BadTurnPlayer()
        player2.end_of_game = mock.MagicMock()

        player1guard = PlayerGuard(player1)
        player2guard = PlayerGuard(player2)
        uuids_to_player = {
            self.uuidp1: player1guard,
            self.uuidp2: player2guard
        }
        ref = Referee(uuids_to_player, self.uuids_to_name, self.obs_man)
        result = ref.run_n_games(3)

        self.assertEqual(player1.end_of_game.call_count, 1)
        self.assertEqual(player2.end_of_game.call_count, 0)
        player1.end_of_game.assert_called_with("p1")
        bad_players, game_results = result
        expected_bad_players = [self.uuidp2]
        for actual, expected in zip(bad_players, expected_bad_players):
            self.assertEqual(actual, expected)
        expected_game_results = [self.uuidp1]
        for actual, expected in zip(game_results, expected_game_results):
            self.assertEqual(actual, expected)
Example #6
0
 def __init__(self, hostname, port, player, player_name):
     """ Create a connection to the server and setup PlayerGuard.
     :param String hostname: the name of the host
     :param nat port: port number to connect to
     :param Player player: the player that's playing over this
                           connection
     :param String playername: name of the player
     """
     self._player = PlayerGuard(player)
     self._player_name = player_name
     self._client_msger = ClientMessager(hostname, port)
     self._relay_state = RelayState.REGISTRATION
     self._our_uuid = uuid.uuid4()
     self._opp_uuid = uuid.uuid4()
     self._uuid_to_name = {self._our_uuid: player_name}
     self._player.set_id(self._our_uuid)
Example #7
0
class RemoteProxyServer:
    def __init__(self, hostname, port, player, player_name):
        """ Create a connection to the server and setup PlayerGuard.
        :param String hostname: the name of the host
        :param nat port: port number to connect to
        :param Player player: the player that's playing over this
                              connection
        :param String playername: name of the player
        """
        self._player = PlayerGuard(player)
        self._player_name = player_name
        self._client_msger = ClientMessager(hostname, port)
        self._relay_state = RelayState.REGISTRATION
        self._our_uuid = uuid.uuid4()
        self._opp_uuid = uuid.uuid4()
        self._uuid_to_name = {self._our_uuid: player_name}
        self._player.set_id(self._our_uuid)

    def start(self):
        """
        Begin protocol.
        """
        # set relay state
        self._relay_state = RelayState.REGISTRATION
        # send name
        self._client_msger.send_register_message(self._player_name)

        while self._relay_state != RelayState.FINISHED:
            self.handle_message()

    def handle_message(self):
        """
        Receives a message from the server and handles it
        """
        message = self._client_msger.receive_message()

        if self._relay_state == RelayState.REGISTRATION and \
                validate_json(PLAYING_AS, message):
            _, new_name = message
            self.set_new_name(new_name)

        elif validate_json(OTHER, message):
            self.set_opp()
            self._relay_state = RelayState.PLACEMENT1

        elif validate_json(RESULTS, message):
            self._relay_state = RelayState.FINISHED

        elif (self._relay_state == RelayState.PLACEMENT1 or \
                self._relay_state == RelayState.TAKE_TURNS) and \
                validate_json(PLACEMENT, message):
            self._player.start_of_game()
            self.handle_placement(message)
            self._relay_state = RelayState.PLACEMENT2

        elif self._relay_state == RelayState.PLACEMENT2 and \
                validate_json(PLACEMENT, message):
            self.handle_placement(message)
            self._relay_state = RelayState.TAKE_TURNS

        elif self._relay_state == RelayState.TAKE_TURNS and \
                validate_json(BOARD, message):
            self.handle_take_turn(message)

        else:
            raise ValueError("got message: " + str(message) +
                             "in RelayState " + self._relay_state.name)

    def set_new_name(self, new_name):
        """
        set's a new name for this player
        :param String new_name: the player's new name
        """
        self._player_name = new_name
        self._uuid_to_name[self._our_uuid] = new_name

    def handle_placement(self, placement):
        """
        handles a placement request
        :param Json Placement placement: the placement request
        """
        workers = self.placement_to_workers(placement)
        self.enact_placement(workers)

    def handle_take_turn(self, board):
        """
        handles a take_turn request
        :param Json Board board: the board of the take_turn request
        """
        santorini_board = self.board_to_board(board)
        self.enact_turn(santorini_board)

    def set_opp(self):
        """
        Generate two uuids to represent this player and the opponent.
        This will be kept consistent for calls on this side of the
        connection and will be translated to player names when
        sending messages.
        Uuids will be kept track of in self._our_uuid and
        self._opp_uuid.
        The actual names of the players will be kept track of
        in self._uuid_to_name.
        """
        self._opp_uuid = uuid.uuid4()

    def enact_placement(self, workers):
        """
        Gets a placement from the player and sends it to the server.
        :param list(Worker) workers: the list of Workers already placed.
        """
        current_board = Board(workers=workers)
        placement = self._player.place_worker(current_board)
        self._client_msger.respond_placement_message(placement)

    def placement_to_workers(self, placement):
        """
        Converts Placement message to list of Workers.
        :param PlacementMsg placement: A list of [Worker, Coordinate, Coordinate]
        :rtype list(Workers): a list of Workers
        """
        workers = {}
        for workerplace in placement:
            worker, row, col = workerplace
            workers[self.worker_to_worker(worker)] = (row, col)
        return workers

    def worker_to_worker(self, worker):
        """
        Converts a string representation of a Worker to a worker.
        e.g. "potato2" would be a Worker of player "potato" and number 2
        :param WorkerMsg worker: a series of lowercase letters followed by either 1 or 2
        :rtype Worker worker: the Worker
        """
        player, number = worker[:-1], int(worker[-1:])
        player_uuid = self.name_to_uuid(player)
        return Worker(player_uuid, number)

    def name_to_uuid(self, name):
        """
        Get's a player's id from their name
        :param String name: name of convert to a Uuid
        """
        return self._our_uuid if self._player_name == name else self._opp_uuid

    def enact_turn(self, board):
        """
        Gets the player to play a turn and then sends it.
        :param Board board: the current board
        """
        turn = self._player.play_turn(board)
        self._client_msger.respond_turn_message(turn, self._our_uuid,
                                                self._uuid_to_name)

    def board_to_board(self, board_arr):
        """
        Converts a 2d Board cell array to a Board object
        :param [[Cell, ...], ...] board_arr: where Cell is either a Height (0, 1, 2, 3, 4)
                                             or a BuildingWorker, a Height followed by a Worker
        :rtype Board: a suitable board
        """
        new_board = [[0 for col in range(Board.BOARD_SIZE)]
                     for row in range(Board.BOARD_SIZE)]
        workers = {}
        for (row, rows) in enumerate(board_arr):
            for col in range(len(rows)):
                cur_cell = board_arr[row][col]
                if isinstance(cur_cell, int):
                    new_board[row][col] = cur_cell
                elif cur_cell:
                    new_board[row][col] = int(cur_cell[0])
                    worker_str = cur_cell[1:]
                    worker_num = int(worker_str[-1:])
                    player_name = worker_str[:-1]
                    cur_worker = Worker(self.name_to_uuid(player_name),
                                        worker_num)
                    if cur_worker:
                        workers[cur_worker] = (row, col)

        cur_board = Board(new_board, workers)
        return cur_board