Пример #1
0
    def beta_play(self, board_history):
        # work in progress
        current_board = board_history[0]
        opponent_point = MaybeStone.flip_stone(self.stone)
        all_opponent_connections = []
        for point in Board.get_points(current_board, opponent_point):
            all_opponent_connections.append(get_blob(current_board, point))

        all_opponent_liberties = []
        for connection in all_opponent_connections:
            all_opponent_liberties.append(
                get_blob_liberties(current_board, connection))

        connections_with_one_liberty = set()
        for liberties_set in all_opponent_liberties:
            if len(liberties_set) == 1:
                connections_with_one_liberty.union(liberties_set)

        for row, maybe_stones in enumerate(current_board):
            for column, maybe_stone in enumerate(current_board):
                if (column, row) in connections_with_one_liberty:
                    try:
                        RuleChecker.check_move(self.stone, (column, row),
                                               board_history)
                        return Point.point_to_string((column, row))
                    except IllegalMoveError:
                        pass
                    except ImproperHistoryError as e:
                        # raise PlayerCommandError('Invalid history') from e
                        return 'This history makes no sense!'

        return 'pass'
    def test_check_player_color(self):
        rule_checker = RuleChecker()
        valid_colors = ['white', 'black', 'red', 'green', 'blue']

        for color in valid_colors:
            self.assertAlmostEqual(rule_checker.check_player_color(color),
                                   True)

        self.assertAlmostEqual(rule_checker.check_player_color("orange"),
                               False)
Пример #3
0
 def initial_setUp(self):
     self.T = TP.extract_transcript('transcriptparser/test.pdf')
     with mock.patch.object(attendanceparser.parser,
                            'get_attendance',
                            return_value=mock_attendance):
         self.A: List[Attendance] = AP.parse_attendance(self.T.student_id)
     self.C: RuleChecker = RuleChecker(self.T, self.A)
Пример #4
0
    def execute_turn(self, action):
        # Check for double pass
        if action == "pass":
            if not self.last_turn_was_pass:
                self.last_turn_was_pass = True
                self._update_history(self.board_hist[0])
                return deepcopy(self.board_hist)

            elif self.last_turn_was_pass:
                return self.end_game()

        elif action == "GO has gone crazy!" or action == "This history makes no sense!":
            if self.current_turn == "B":
                return self.end_game(self.black_player)
            else:
                return self.end_game(self.white_player)

        else:
            self.last_turn_was_pass = False
            action = Point.string_to_point(action)
            try:
                new_board = RuleChecker.check_move(self.current_turn, action,
                                                   self.board_hist)

                self._update_history(new_board)

                return deepcopy(self.board_hist)

            except RuleCheckerError as e:
                if self.current_turn == "B":
                    return self.end_game(self.black_player)
                else:
                    return self.end_game(self.white_player)
    def test_check_player_dead(self):
        rule_checker = RuleChecker()
        board = Board()
        player = Avatar('green')
        tile_1 = HandTile([('n1', 's2'), ('n2', 'e2'), ('e1', 'w2'),
                           ('s1', 'w1')])
        tile_2 = HandTile([('n1', 'e2'), ('n2', 'w2'), ('e1', 's1'),
                           ('s2', 'w1')])

        board.first_turn(player, tile_1, 'a1', 'n1')
        self.assertAlmostEqual(player.current_port, 's2')
        self.assertAlmostEqual(player.current_tile, 'a1')

        self.assertAlmostEqual(
            rule_checker.check_player_dead(board, tile_2, "a2", player), True)
        self.assertAlmostEqual(
            rule_checker.check_player_dead(board, tile_1, "a2", player), False)
    def test_check_turn(self):
        rc = RuleChecker()
        empty_board = Board()
        player = Avatar("white")
        tile = HandTile([('s1', 'e2'), ('s2', 'w1'), ('e1', 'n2'),
                         ('n1', 'w2')])
        tile_2 = HandTile([('n1', 's2'), ('n2', 'e2'), ('e1', 'w2'),
                           ('s1', 'w1')])
        suicide_tile = HandTile([('n1', 'w1'), ('n2', 'e1'), ('s2', 'e2'),
                                 ('s1', 'w2')])

        empty_board.first_turn(player, tile, "a1", "n2")
        self.assertAlmostEqual(player.current_port, "e1")
        self.assertAlmostEqual(player.current_tile, "a1")

        player.tiles = [tile_2, suicide_tile]

        # Tile has to be at the correct coordinate
        self.assertAlmostEqual(
            rc.check_turn(empty_board, tile_2, "a1", player)["legal"], False)
        self.assertAlmostEqual(
            rc.check_turn(empty_board, tile_2, "a2", player)["legal"], False)
        self.assertAlmostEqual(
            rc.check_turn(empty_board, tile_2, "b1", player)["legal"], True)

        # Tile cannot cause a suicide if there are other options
        self.assertAlmostEqual(
            rc.check_turn(empty_board, suicide_tile, "b1", player)["legal"],
            False)

        player.tiles = [suicide_tile]

        self.assertAlmostEqual(
            rc.check_turn(empty_board, suicide_tile, "b1", player)["legal"],
            True)
Пример #7
0
    def dumb_play(self, board_history):
        if self.stone == None:
            raise PlayerCommandError(
                'You need to set the stone before you can play.')

        current_board = board_history[0]
        for column, maybe_stones in enumerate(current_board):
            for row, maybe_stone in enumerate(current_board):
                try:
                    RuleChecker.check_move(self.stone, (column, row),
                                           board_history)
                    return Point.point_to_string((column, row))
                except IllegalMoveError:
                    pass
                except ImproperHistoryError as e:
                    # raise PlayerCommandError('Invalid history') from e
                    return 'This history makes no sense!'

        return 'pass'
    def test_valid_starting_port(self):
        rc = RuleChecker()

        coordinate = "a1"
        port_valid_north = 'n1'
        port_valid_west = 'w1'
        port_invalid = 's2'
        port_invalid_side = 'x2'
        port_invalid_space = 'n5'

        self.assertAlmostEqual(
            rc.valid_starting_port(coordinate, port_valid_north), True)
        self.assertAlmostEqual(
            rc.valid_starting_port(coordinate, port_valid_west), True)
        self.assertAlmostEqual(
            rc.valid_starting_port(coordinate, port_invalid), False)
        self.assertAlmostEqual(
            rc.valid_starting_port(coordinate, port_invalid_side), False)
        self.assertAlmostEqual(
            rc.valid_starting_port(coordinate, port_invalid_space), False)
Пример #9
0
    def end_game(self, committed_illegal=""):
        # Checks the score using RuleChecker and returns the name(s) of the winner(s)

        score = RuleChecker.get_score(self.board_hist[0])
        black_score = score["B"]
        white_score = score["W"]

        # Cheating players: winning player, cheating player, cheating flag
        if committed_illegal == self.black_player:
            return [self.white_player, self.black_player, 2]
        elif committed_illegal == self.white_player:
            return [self.black_player, self.white_player, 2]

        if black_score > white_score:
            return [self.black_player]

        elif white_score > black_score:
            return [self.white_player]

        elif black_score == white_score:
            winners = [self.black_player, self.white_player]
            return winners
Пример #10
0
    def n1play(self, board_history):
        if self.stone == None:
            raise PlayerCommandError(
                'You need to set the stone before you can play.')

        current_board = copy.deepcopy(board_history[0])
        opponent_point = MaybeStone.flip_stone(self.stone)

        for column_index in range(MAX_COLUMN):
            for row_index in range(MAX_ROW):
                if self.check_for_adjacent_stones(opponent_point,
                                                  (column_index, row_index),
                                                  current_board):
                    try:
                        # Try putting a stone in the current position
                        new_board = RuleChecker.check_move(
                            self.stone, (column_index, row_index),
                            board_history)
                        try:
                            Board.place(current_board, self.stone,
                                        (column_index, row_index))
                            # See if capture occurred by comparing with just placing
                            if current_board != new_board:
                                return Point.point_to_string(
                                    (column_index, row_index))
                            else:
                                Board.remove(current_board, self.stone,
                                             (column_index, row_index))
                        except BoardStateError as e:
                            pass
                    except IllegalMoveError as e:
                        pass
                    except ImproperHistoryError as e:
                        # raise PlayerCommandError('Invalid history') from e
                        return 'This history makes no sense!'

        return self.dumb_play(board_history)
Пример #11
0
 def __init__(self):
     self.tiles = {}
     self.rule_checker = RuleChecker()
Пример #12
0
class Board:

    # Constructor
    def __init__(self):
        self.tiles = {}
        self.rule_checker = RuleChecker()

    # returns true if the given board coordinate has a tile on it
    def is_coordinate_occupied(self, board_coordinate):
        return board_coordinate in self.tiles.keys()

    # returns dictionary of north, south, east, west neighbors of the given square
    def get_board_coordinate_neighbors(self, board_coordinate):
        neighbors = {NORTH: None, SOUTH: None, WEST: None, EAST: None}
        for side in neighbors.keys():
            neighbor = get_coordinate_neighbor(board_coordinate, side)
            if self.is_coordinate_occupied(neighbor):
                neighbor = self.tiles[neighbor]
            elif neighbor != EDGE:
                neighbor = None
            neighbors[side] = neighbor

        return neighbors

    # Converts hand_tile to a BoardTile and initializes its neighbors
    def convert_to_board_tile(self, hand_tile, board_coordinate):
        tile_neighbors = self.get_board_coordinate_neighbors(board_coordinate)
        board_tile = BoardTile(hand_tile.paths, tile_neighbors)
        return board_tile

    # hand_tile is a HandTile , board_coordinate is a string of 2 characters
    # in battleship coordiates -> 10x10 board is A-J 1-10
    # returns the generated board tile
    def place_tile(self, hand_tile, board_coordinate):
        board_tile = self.convert_to_board_tile(hand_tile, board_coordinate)
        self.tiles[board_coordinate] = board_tile

        # Link the newly created board tile to any of its neighbors currently on the board
        sides = [NORTH, SOUTH, EAST, WEST]
        for side in sides:
            new_neighbor_coordinate = get_coordinate_neighbor(
                board_coordinate, side)
            if self.is_coordinate_occupied(new_neighbor_coordinate):
                new_neighbor = self.tiles[new_neighbor_coordinate]
                new_neighbor.set_neighbor(get_opposite_side(side), board_tile)

        return board_tile

    # given a board coordinate and a starting port on the tile at that location
    # return the end board coordinate and port of that path on this board
    # or EDGE if they fall off the board
    # board_coordinate must have a tile on it (be in board.tiles)
    def end_of_path(self, board_coordinate, starting_port):
        board_tile = self.tiles[board_coordinate]
        end_port = board_tile.end_of_path(starting_port)
        neighboring_side = port_to_side(end_port)
        neighbor_to_move_to = board_tile.neighbors[neighboring_side]

        if neighbor_to_move_to == EDGE:
            return {TILE: EDGE, PORT: EDGE}
        elif neighbor_to_move_to == None:
            return {TILE: board_coordinate, PORT: end_port}
        else:
            new_tile_location = get_coordinate_neighbor(
                board_coordinate, neighboring_side)
            starting_port_on_new_tile = get_connecting_port(end_port)
            return self.end_of_path(new_tile_location,
                                    starting_port_on_new_tile)

    # moves given player to given board_coordinate and moves them along the path
    # throws exception if player cannot be moved (if there is no tile at the connecting side)
    def move_player(self, player):
        starting_port = player.current_port
        new_coordiate = get_connecting_coordinate(player.current_tile,
                                                  starting_port)

        if self.is_coordinate_occupied(new_coordiate):
            port_on_new_tile = get_connecting_port(starting_port)
            ending_location = self.end_of_path(new_coordiate, port_on_new_tile)
            player.current_tile = ending_location[TILE]
            player.current_port = ending_location[PORT]
        else:
            logging.info("Player cannot be moved, no tile at: %s",
                         new_coordiate)
            sys.exit(1)

    # places a player and a handtile on the board at the given coordinate and port
    # this is part of the players intial turn
    def first_turn(self, player, hand_tile, board_coordinate, starting_port):
        # Rule Checker : sees if tile location is valid
        first_turn_check = self.rule_checker.check_first_turn(
            self, hand_tile, board_coordinate, starting_port)[LEGAL]
        if first_turn_check:
            board_tile = self.place_tile(hand_tile, board_coordinate)
            end_port = board_tile.end_of_path(starting_port)
            player.place_avatar(board_coordinate, end_port)
        else:
            logging.info("Invalid initial tile placement: %s",
                         board_coordinate)
            sys.exit(1)

    def take_turn(self, hand_tile, board_coordinate, player):
        # Rule Checker : sees if turn is valid
        turn_check = self.rule_checker.check_turn(self, hand_tile,
                                                  board_coordinate,
                                                  player)[LEGAL]
        if turn_check:
            self.place_tile(hand_tile, board_coordinate)
            self.move_player(player)
        else:
            logging.info("Invalid turn: %s", board_coordinate)
            sys.exit(1)

    def get_port_coordinate(self, port):
        return (0, 0)
Пример #13
0
 def __init__(self):
     self.deck = Deck()
     self.board = Board()
     self.player_dictionary = {}
     self.rule_checker = RuleChecker()
     self.dead_players = []
Пример #14
0
class GameState:
    def __init__(self):
        self.deck = Deck()
        self.board = Board()
        self.player_dictionary = {}
        self.rule_checker = RuleChecker()
        self.dead_players = []

    #################### Public methods ###################################

    # checks if an initial tile placement is legal
    # tile_index -> int : 0 - 34 (represents the index in all_tiles)
    # rotation -> int : 0, 90, 180, 270 (represents the number of roations for the given tile)
    # boar_coordinate -> string : valid_cooridinate() (coordinate the tile is placed at)
    # starting_port -> string : valid_port() (port on the edge of the board the player starts at)
    def initial_placement_check(self, tile_index, rotation, board_coordinate,
                                starting_port):
        tile = self.deck.get_tile(tile_index)
        number_of_rotations = get_number_of_rotations(rotation)
        tile.rotate(number_of_rotations)
        return self.rule_checker.check_first_turn(self.board, tile,
                                                  board_coordinate,
                                                  starting_port)

    # performs a players first turn, returns the validity of that turn (if not valid kills player)
    # player_color -> string : valid_color() (the color of the player making the turn)
    # tile_index -> int : 0 - 34 (represents the index in all_tiles)
    # rotation -> int : 0, 90, 180, 270 (represents the number of roations for the given tile)
    # boar_coordinate -> string : valid_cooridinate() (coordinate the tile is placed at)
    # starting_port -> string : valid_port() (port on the edge of the board the player starts at)
    def player_first_turn(self, player_color, tile_index, rotation,
                          board_coordinate, starting_port):
        new_player = Avatar(player_color)
        self.player_dictionary[player_color] = new_player

        first_turn_rule_check = self.initial_placement_check(
            tile_index, rotation, board_coordinate, starting_port)
        if first_turn_rule_check[LEGAL]:
            tile = self.deck.get_tile(tile_index)
            number_of_rotations = get_number_of_rotations(rotation)
            tile.rotate(number_of_rotations)
            self.board.first_turn(new_player, tile, board_coordinate,
                                  starting_port)
        else:
            self.dead_players.append(player_color)

        return first_turn_rule_check

    # checks if an players turn is legal
    # player_color -> string : valid_color() (the color of the player making the turn)
    # tile_index -> int : 0 - 34 (represents the index in all_tiles)
    # rotation -> int : 0 - 3 (represents the number of roations for the given tile)
    # boar_coordinate -> string : valid_cooridinate() (coordinate the tile is placed at)
    # tile_choices -> array[int] : 2 - 3 (tile options the player had to choose from)
    def rule_check(self, player_color, tile_index, rotation, board_coordinate,
                   tile_choices):
        player = self.player_dictionary[player_color]
        players_tiles = self.deck.get_tiles(tile_choices)
        player.tiles = players_tiles

        tile = self.deck.get_tile(tile_index)
        number_of_rotations = get_number_of_rotations(rotation)
        tile.rotate(number_of_rotations)

        return self.rule_checker.check_turn(self.board, tile, board_coordinate,
                                            player)

    # performs a players turn, returns the result or validity of that turn (if not valid kills player)
    # player_color -> string : valid_color() (the color of the player making the turn)
    # tile_index -> int : 0 - 34 (represents the index in all_tiles)
    # rotation -> int : 0 - 3 (represents the number of roations for the given tile)
    # boar_coordinate -> string : valid_cooridinate() (coordinate the tile is placed at)
    # tile_choices -> array[int] : 2 - 3 (tile options the player had to choose from)
    def player_take_turn(self, player_color, tile_index, rotation,
                         board_coordinate, tile_choices):
        rule_check = self.rule_check(player_color, tile_index, rotation,
                                     board_coordinate, tile_choices)
        if rule_check[LEGAL]:
            player = self.player_dictionary[player_color]

            tile = self.deck.get_tile(tile_index)
            number_of_rotations = get_number_of_rotations(rotation)
            tile.rotate(number_of_rotations)

            self.board.take_turn(tile, board_coordinate, player)
            players_killed = self.update_other_players_positions(
                player, board_coordinate)
            result = self.get_turn_results(players_killed)
            self.dead_players.extend(players_killed)

            return result
        else:
            self.dead_players.append(player_color)
            return rule_check

    #################### Private methods #######################

    # returns a set of the remaining living player colors
    def get_living_players(self):
        players_set = set(self.player_dictionary.keys())
        dead_players_set = set(self.dead_players)
        living_players_set = players_set.difference(dead_players_set)
        return living_players_set

    # given a list of player colors move those players
    # expectation that these players are all moveable otherwise
    # throws an exception
    def move_players(self, players_to_move):
        for player_color in players_to_move:
            player = self.player_dictionary[player_color]
            self.board.move_player(player)

    # updates the positions of the other players still on the board
    # given the current player and where they placed the tile on their turn
    # returns the players killed in this turn
    def update_other_players_positions(self, current_player, board_coordinate):
        players_killed = []
        if current_player.is_player_dead():
            players_killed.append(current_player.color)

        living_players = self.get_living_players()
        living_players.discard(current_player.color)
        players_to_move = []

        for player_color in living_players:
            player = self.player_dictionary[player_color]
            if player.get_connecting_coordinate() == board_coordinate:
                players_to_move.append(player.color)

        self.move_players(players_to_move)

        for player_color in players_to_move:
            if self.player_dictionary[player_color].is_player_dead():
                players_killed.append(player_color)

        return players_killed

    # given the players killed during a turn return the results of a legal move
    def get_turn_results(self, players_killed):
        result = {LEGAL: True, PLAYERS_KILLED: [], GAME_OVER: False}
        is_game_over = len(self.player_dictionary) - len(self.dead_players) < 2
        is_tie = len(self.player_dictionary) == len(self.dead_players)

        if is_game_over:
            result[GAME_OVER] = True
            if is_tie:
                result[WINNERS] = players_killed
                result[LOSERS] = self.dead_players
            else:
                result[WINNERS] = self.get_living_players()
                result[LOSERS] = self.dead_players
        else:
            self.dead_players.extend(players_killed)
            result[PLAYERS_KILLED] = players_killed

        return result
Пример #15
0
 def refresh_checker(self):
     self.C: RuleChecker = RuleChecker(self.T, self.A)
    def test_check_first_turn(self):
        rc = RuleChecker()
        empty_board = Board()
        player = Avatar("white")
        suicide_tile = HandTile([('s1', 's2'), ('e2', 'e1'), ('n2', 'n1'),
                                 ('w1', 'w2')])
        tile = HandTile([('n1', 's2'), ('n2', 'e2'), ('e1', 'w2'),
                         ('s1', 'w1')])

        # Not on edge
        not_the_edge = rc.check_first_turn(empty_board, suicide_tile, "c7",
                                           "w2")
        self.assertAlmostEqual(not_the_edge["legal"], False)
        self.assertAlmostEqual(not_the_edge["rules broken"], [
            "tile placement is not on the board's edge",
            "starting port is invalid"
        ])

        # No suicides
        suicide_move = rc.check_first_turn(empty_board, suicide_tile, "a1",
                                           "n1")
        self.assertAlmostEqual(suicide_move["legal"], False)
        self.assertAlmostEqual(suicide_move["rules broken"],
                               ["tile placement is avoidable suicide"])
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, suicide_tile, "a1",
                                "n2")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, suicide_tile, "a1",
                                "w1")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, suicide_tile, "a1",
                                "w2")["legal"], False)

        # No iterior ports allowed
        interior_port_move = rc.check_first_turn(empty_board, suicide_tile,
                                                 "a1", "e2")
        self.assertAlmostEqual(interior_port_move["legal"], False)
        self.assertAlmostEqual(interior_port_move["rules broken"],
                               ["starting port is invalid"])
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "a1", "n2")["legal"], True)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "a1", "s2")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "a1", "w2")["legal"], True)

        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "a2", "e1")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "a2", "n1")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "a2", "s1")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "a2", "w1")["legal"], True)

        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "b1", "e2")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "b1", "n2")["legal"], True)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "b1", "s2")["legal"], False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "b1", "w2")["legal"], False)

        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "j10", "e2")["legal"], True)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "j10", "n2")["legal"],
            False)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "j10", "s2")["legal"], True)
        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "j10", "w2")["legal"],
            False)

        empty_board.first_turn(player, tile, "a1", "n1")

        # No neighbors
        placed_on_occupied_spot = rc.check_first_turn(empty_board, tile, "a1",
                                                      "s2")
        self.assertAlmostEqual(placed_on_occupied_spot["legal"], False)
        self.assertAlmostEqual(placed_on_occupied_spot["rules broken"], [
            'coordinate is already occupied', 'starting port is invalid',
            'tile placement is avoidable suicide'
        ])

        placed_tile_with_neighbors = rc.check_first_turn(
            empty_board, tile, "a1", "s1")
        self.assertAlmostEqual(placed_tile_with_neighbors["legal"], False)
        self.assertAlmostEqual(placed_tile_with_neighbors["rules broken"], [
            'coordinate is already occupied', 'starting port is invalid',
            'tile placement is avoidable suicide'
        ])

        self.assertAlmostEqual(
            rc.check_first_turn(empty_board, tile, "b1", "e2")["legal"], False)