def test_simple_movement_execution(self): board = Board() piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.south) board.get_tile(1, 2).place_piece(piece_two) assert board.execute_board_movements(PLAYER_1_ID) == 1 assert board.get_tile(1, 1).piece == piece_two
def test_move_to_perimeter(self): board = Board() piece_four = Piece(PLAYER_1_ID, PieceType.four) piece_four.set_movement_direction(Direction.south) board.get_tile(2, 1).place_piece(piece_four) assert board.execute_board_movements(PLAYER_1_ID) == 1 assert piece_four.tile is None assert board.get_tile(2, 1).piece is None assert board.get_tile(2, 0).piece is None
def test_one_not_pushable_if_piece_behind(self): board = Board() five = Piece(PLAYER_1_ID, PieceType.five) five.set_movement_direction(Direction.south) board.get_tile(2, 2).place_piece(five) one = Piece(PLAYER_1_ID, PieceType.one) one.set_movement_direction(Direction.north) board.get_tile(1, 1).place_piece(one) enemy_two = Piece(PLAYER_2_ID, PieceType.two) enemy_two.set_movement_direction(Direction.east) board.get_tile(0, 2).place_piece(enemy_two) board.execute_board_movements(PLAYER_2_ID) assert board.get_tile(2, 1).piece == five assert board.get_tile(1, 2).piece == one assert board.get_tile(0, 2).piece is None
def test_push_movements_execution(self): board = Board() piece_four = Piece(PLAYER_1_ID, PieceType.four) piece_four.set_movement_direction(Direction.north) board.get_tile(2, 1).place_piece(piece_four) piece_three = Piece(PLAYER_1_ID, PieceType.three) piece_three.set_movement_direction(Direction.east) board.get_tile(1, 2).place_piece(piece_three) piece_three_2 = Piece(PLAYER_2_ID, PieceType.three) piece_three_2.set_movement_direction(Direction.west) board.get_tile(2, 2).place_piece(piece_three_2) piece_five = Piece(PLAYER_2_ID, PieceType.five) piece_five.set_movement_direction(Direction.east) board.get_tile(2, 3).place_piece(piece_five) piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.south) board.get_tile(3, 3).place_piece(piece_two) piece_one = Piece(PLAYER_2_ID, PieceType.one) piece_one.set_movement_direction(Direction.west) board.get_tile(3, 2).place_piece(piece_one) assert board.execute_board_movements(PLAYER_1_ID) == 5 assert board.get_tile(1, 1).piece is None assert board.get_tile(2, 1).piece is None assert board.get_tile(3, 1).piece == piece_one assert board.get_tile(1, 2).piece == piece_three assert board.get_tile(2, 2).piece == piece_four assert board.get_tile(3, 2).piece == piece_two assert board.get_tile(1, 3).piece is None assert board.get_tile(2, 3).piece == piece_three_2 assert board.get_tile(3, 3).piece is None assert piece_five.tile is None
class Game(object): def __init__(self, on_player_moves_executed: Optional[Callable] = None): self.on_player_moves_executed = on_player_moves_executed self.board = Board() self.player_1 = Player(PLAYER_1_ID, self.board, self) self.player_2 = Player(PLAYER_2_ID, self.board, self) self.starting_player = self.player_1 self.first_move_executed = False self.player_moves = {PLAYER_1_ID: list(), PLAYER_2_ID: list()} self.turns = 0 self.result: GameResult = None def play_game(self, player_1_strategy_fn: StrategyFunction, player_2_strategy_fn: StrategyFunction) -> GameResult: logger.info(f"Game starting...") while self.result is None: self.first_move_executed = False self.execute_player_moves(player_1_strategy_fn, player_2_strategy_fn) if self.on_player_moves_executed is not None: self.on_player_moves_executed() self.board.execute_board_movements(self.starting_player.id) self.turns += 1 self.switch_starting_player() self.result = self.get_current_result() logger.info( f"Game finished in {self.turns} turns with result: {self.result}") return self.result def execute_player_moves(self, player_1_strategy_fn: StrategyFunction, player_2_strategy_fn: StrategyFunction): starting_strategy_fn = player_1_strategy_fn if self.starting_player.id == self.player_1.id else player_2_strategy_fn starting_move = starting_strategy_fn(self.starting_player, self.get_secondary_player(), True) if starting_move is not None: starting_move.execute() self.first_move_executed = True logger.debug( f"{self.starting_player!r} executed move {starting_move!r}") second_strategy_fn = player_1_strategy_fn if self.get_secondary_player( ).id == self.player_1.id else player_2_strategy_fn second_move = second_strategy_fn(self.get_secondary_player(), self.starting_player, False) if second_move is not None: second_move.execute() logger.debug( f"{self.get_secondary_player()!r} executed move {second_move!r}") self.player_moves[self.starting_player.id].append(starting_move) self.player_moves[self.get_secondary_player().id].append(second_move) def get_current_result(self) -> GameResult: return self.board.get_game_result(self.player_1.id, self.player_2.id) def get_player_by_id(self, player_id) -> Player: if player_id == PLAYER_1_ID: return self.player_1 elif player_id == PLAYER_2_ID: return self.player_2 else: raise ValueError(f"Unknown player ID specified: {player_id}.") # Returns the player that is next to play def get_active_player(self): return self.get_secondary_player( ) if self.first_move_executed else self.starting_player def switch_starting_player(self): self.starting_player = self.get_secondary_player() def get_secondary_player(self) -> Player: if self.starting_player is self.player_1: return self.player_2 return self.player_1 def clone(self) -> Game: clone_game = Game() clone_game.starting_player = clone_game.get_player_by_id( self.starting_player.id) clone_game.first_move_executed = self.first_move_executed board_pieces = self.board.get_board_pieces() for board_piece in board_pieces: owner = clone_game.get_player_by_id(board_piece.owner_id) target_piece = owner.get_piece_by_type(board_piece.type) target_piece.set_movement_direction(board_piece.direction) target_tile = clone_game.board.get_tile(board_piece.tile.x, board_piece.tile.y) target_tile.place_piece(target_piece) return clone_game