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])
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)
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)
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)
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)
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)
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