def is_point_an_eye(board, point, color):
    if board.get(point) is not None:  # <1>
        return False
    for neighbor in point.neighbors():  # <2>
        if board.is_on_grid(neighbor):
            neighbor_color = board.get(neighbor)
            if neighbor_color != color:
                return False

    friendly_corners = 0  # <3>
    off_board_corners = 0
    corners = [
        Point(point.row - 1, point.col - 1),
        Point(point.row - 1, point.col + 1),
        Point(point.row + 1, point.col - 1),
        Point(point.row + 1, point.col + 1),
    ]
    for corner in corners:
        if board.is_on_grid(corner):
            corner_color = board.get(corner)
            if corner_color == color:
                friendly_corners += 1
        else:
            off_board_corners += 1
    if off_board_corners > 0:
        return off_board_corners + friendly_corners == 4  # <4>
    return friendly_corners >= 3  # <5>


# <1> An eye is an empty point.
# <2> All adjacent points must contain friendly stones.
# <3> We must control 3 out of 4 corners if the point is in the middle of the board; on the edge we must control all corners.
# <4> Point is on the edge or corner.
# <5> Point is in the middle.
# end::eye[]
Esempio n. 2
0
def is_point_an_eye(board, point, color):
    if board.get(point) is not None:
        return False
    # All adjacent points must contain friendly stones.
    for neighbor in board.neighbors(point):
        neighbor_color = board.get(neighbor)
        if neighbor_color != color:
            return False
    # We must control 3 out of 4 corners if the point is in the middle
    # of the board; on the edge we must control all corners.
    friendly_corners = 0
    off_board_corners = 0
    corners = [
        Point(point.row - 1, point.col - 1),
        Point(point.row - 1, point.col + 1),
        Point(point.row + 1, point.col - 1),
        Point(point.row + 1, point.col + 1),
    ]
    for corner in corners:
        if board.is_on_grid(corner):
            corner_color = board.get(corner)
            if corner_color == color:
                friendly_corners += 1
        else:
            off_board_corners += 1
    if off_board_corners > 0:
        # Point is on the edge or corner.
        return off_board_corners + friendly_corners == 4
    # Point is in the middle.
    return friendly_corners >= 3
Esempio n. 3
0
def init_neighbor_table(dim):
    rows, cols = dim
    new_table = {}
    for r in range(1, rows + 1):
        for c in range(1, cols + 1):
            p = Point(row=r, col=c)
            full_neighbors = p.neighbors()
            true_neighbors = [
                n for n in full_neighbors
                if 1 <= n.row <= rows and 1 <= n.col <= cols
            ]
            new_table[p] = true_neighbors
    neighbor_tables[dim] = new_table
Esempio n. 4
0
    def process_zip(self, zip_file_name, data_file_name, game_list):
        pid_header = str(os.getpid()) + ": "
        print(dt.now().strftime("%H:%M:%S.%f\t") + pid_header + "working on " +
              zip_file_name)
        tar_file = self.unzip_data(zip_file_name)
        zip_file = tarfile.open(self.data_dir + '/' + tar_file)

        name_list = zip_file.getnames()
        total_examples = self.num_total_examples(zip_file, game_list,
                                                 name_list)

        shape = self.encoder.shape()
        feature_shape = np.insert(shape, 0, np.asarray([total_examples]))
        features = np.zeros(feature_shape)
        labels = np.zeros((total_examples, ))

        counter = 0
        for index in game_list:
            name = name_list[index + 1]
            if not name.endswith('.sgf'):
                raise ValueError(name + ' is not a valid sgf')
            sgf_content = zip_file.extractfile(name).read()
            sgf = Sgf_game.from_string(sgf_content)

            game_state, first_move_done = self.get_handicap(sgf)

            for item in sgf.main_sequence_iter():
                color, move_tuple = item.get_move()
                point = None
                if color is not None:
                    if move_tuple is not None:
                        row, col = move_tuple
                        point = Point(row + 1, col + 1)
                        move = Move.play(point)
                    else:
                        move = Move.pass_turn()
                    if first_move_done and point is not None:
                        features[counter] = self.encoder.encode(game_state)
                        labels[counter] = self.encoder.encode_point(point)
                        counter += 1
                    game_state = game_state.apply_move(move)
                    first_move_done = True

        feature_file_base = self.data_dir + '/' + data_file_name + '_features_%d'
        label_file_base = self.data_dir + '/' + data_file_name + '_labels_%d'

        chunk = 0  # Due to files with large content, split up after chunksize
        chunksize = 1024
        while features.shape[0] >= chunksize:
            feature_file = feature_file_base % chunk
            label_file = label_file_base % chunk
            chunk += 1
            current_features, features = features[:chunksize], features[
                chunksize:]
            current_labels, labels = labels[:chunksize], labels[chunksize:]
            np.save(feature_file, current_features)
            np.save(label_file, current_labels)
        print(dt.now().strftime("%H:%M:%S.%f\t") + pid_header + "completed " +
              zip_file_name)
Esempio n. 5
0
 def get_handicap(sgf):  # Get handicap stones
     go_board = Board(19, 19)
     first_move_done = False
     move = None
     row = col = None
     game_state = GameState.new_game(19)
     if sgf.get_handicap() is not None and sgf.get_handicap() != 0:
         for setup in sgf.get_root().get_setup_stones():
             for move in setup:
                 row, col = move
                 go_board.place_stone(Player.black,
                                      Point(row + 1,
                                            col + 1))  # black gets handicap
         first_move_done = True
         move = Move(Point(row=row, col=col))
         game_state = GameState(go_board, Player.white, None, move)
     return game_state, first_move_done
Esempio n. 6
0
def init_corner_table(dim):
    rows, cols = dim
    new_table = {}
    for r in range(1, rows + 1):
        for c in range(1, cols + 1):
            p = Point(row=r, col=c)
            full_corners = [
                Point(row=p.row - 1, col=p.col - 1),
                Point(row=p.row - 1, col=p.col + 1),
                Point(row=p.row + 1, col=p.col - 1),
                Point(row=p.row + 1, col=p.col + 1),
            ]
            true_corners = [
                n for n in full_corners
                if 1 <= n.row <= rows and 1 <= n.col <= cols
            ]
            new_table[p] = true_corners
    corner_tables[dim] = new_table
Esempio n. 7
0
    def legal_moves(self):
        moves = []
        for row in range(1, self.board.num_rows + 1):
            for col in range(1, self.board.num_cols + 1):
                move = Move.play(Point(row, col))
                if self.is_valid_move(move):
                    moves.append(move)
        # These two moves are always legal.
        moves.append(Move.pass_turn())
        moves.append(Move.resign())

        return moves
Esempio n. 8
0
    def select_move(self, game_state):
        """Choose a random valid move that preserves our own eyes."""
        candidates = []
        for r in range(1, game_state.board.num_rows + 1):
            for c in range(1, game_state.board.num_cols + 1):
                candidate = Point(row=r, col=c)
                if game_state.is_valid_move(Move.play(candidate)) and \
                        not is_point_an_eye(game_state.board,
                                            candidate,
                                            game_state.next_player):
                    candidates.append(candidate)
        if not candidates:
            return Move.pass_turn()
        return Move.play(random.choice(candidates))


# end::random_bot[]
Esempio n. 9
0
def evaluate_territory(board):
    status = {}
    for r in range(1, board.num_rows + 1):
        for c in range(1, board.num_cols + 1):
            p = Point(row=r, col=c)
            if p in status:  # <1>
                continue
            stone = board.get(p)
            if stone is not None:  # <2>
                status[p] = board.get(p)
            else:
                group, neighbors = _collect_region(p, board)
                if len(neighbors) == 1:  # <3>
                    neighbor_stone = neighbors.pop()
                    stone_str = 'b' if neighbor_stone == Player.black else 'w'
                    fill_with = 'territory_' + stone_str
                else:
                    fill_with = 'dame'  # <4>
                for pos in group:
                    status[pos] = fill_with
    return Territory(status)
Esempio n. 10
0
def _collect_region(start_pos, board, visited=None):

    if visited is None:
        visited = {}
    if start_pos in visited:
        return [], set()
    all_points = [start_pos]
    all_borders = set()
    visited[start_pos] = True
    here = board.get(start_pos)
    deltas = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    for delta_r, delta_c in deltas:
        next_p = Point(row=start_pos.row + delta_r, col=start_pos.col + delta_c)
        if not board.is_on_grid(next_p):
            continue
        neighbor = board.get(next_p)
        if neighbor == here:
            points, borders = _collect_region(next_p, board, visited)
            all_points += points
            all_borders |= borders
        else:
            all_borders.add(neighbor)
    return all_points, all_borders
Esempio n. 11
0
    def encode(self, game_state):
        board_tensor = np.zeros(
            (self.num_planes, self.board_height, self.board_width))
        for r in range(self.board_height):
            for c in range(self.board_width):
                point = Point(row=r + 1, col=c + 1)

                go_string = game_state.board.get_go_string(point)
                if go_string and go_string.color == game_state.next_player:
                    board_tensor[offset("stone_color")][r][c] = 1
                elif go_string and go_string.color == game_state.next_player.other:
                    board_tensor[offset("stone_color") + 1][r][c] = 1
                else:
                    board_tensor[offset("stone_color") + 2][r][c] = 1

                board_tensor[offset("ones")] = self.ones()
                board_tensor[offset("zeros")] = self.zeros()

                if not is_point_an_eye(game_state.board, point,
                                       game_state.next_player):
                    board_tensor[offset("sensibleness")][r][c] = 1

                ages = min(game_state.board.move_ages.get(r, c), 8)
                if ages > 0:
                    board_tensor[int(offset("turns_since") + ages)][r][c] = 1

                if game_state.board.get_go_string(point):
                    liberties = min(
                        game_state.board.get_go_string(point).num_liberties, 8)
                    board_tensor[int(offset("liberties") +
                                     liberties)][r][c] = 1

                move = Move(point)
                if game_state.is_valid_move(move):
                    new_state = game_state.apply_move(move)
                    liberties = min(
                        new_state.board.get_go_string(point).num_liberties, 8)
                    board_tensor[int(offset("liberties_after") +
                                     liberties)][r][c] = 1

                    adjacent_strings = [
                        game_state.board.get_go_string(nb)
                        for nb in point.neighbors()
                    ]
                    capture_count = 0
                    for go_string in adjacent_strings:
                        other_player = game_state.next_player.other
                        if go_string and go_string.num_liberties == 1 and go_string.color == other_player:
                            capture_count += len(go_string.stones)
                    capture_count = min(capture_count, 8)
                    board_tensor[int(offset("capture_size") +
                                     capture_count)][r][c] = 1

                if go_string and go_string.num_liberties == 1:
                    go_string = game_state.board.get_go_string(point)
                    if go_string:
                        num_atari_stones = min(len(go_string.stones), 8)
                        board_tensor[int(
                            offset("self_atari_size") +
                            num_atari_stones)][r][c] = 1

                if is_ladder_capture(game_state, point):
                    board_tensor[offset("ladder_capture")][r][c] = 1

                if is_ladder_escape(game_state, point):
                    board_tensor[offset("ladder_escape")][r][c] = 1

                if self.use_player_plane:
                    if game_state.next_player == Player.black:
                        board_tensor[offset("ones")] = self.ones()
                    else:
                        board_tensor[offset("zeros")] = self.zeros()
        return board_tensor
Esempio n. 12
0
 def decode_point_index(self, index):
     row = index // self.board_width
     col = index % self.board_width
     return Point(row=row + 1, col=col + 1)