示例#1
0
文件: helpers.py 项目: olk/ki-go
def is_point_an_eye(board, point, color):
    # an eye is an empty point
    if board.get(point) is not None:
        return False
    for neighbor in point.neighbors():
        if board.is_on_grid(neighbor):
            neighbor_color = board.get(neighbor)
            if neighbor_color != color:
                return False
    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 0 < off_board_corners:
        # point is on the edge or corner
        return 4 == off_board_corners + friendly_corners
    # point is in the middle
    return 3 <= friendly_corners
示例#2
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
示例#3
0
文件: mcts.py 项目: olk/ki-go
 def _update_cache(self, dim):
     self.dim = dim
     rows, cols = dim
     self.point_cache = []
     for r in range(1, rows + 1):
         for c in range(1, cols + 1):
             self.point_cache.append(Point(row=r, col=c))
示例#4
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
示例#5
0
def print_board(board):
    for row in range(board.num_rows, 0, -1):
        bump = " " if row <= 9 else ""
        line = []
        for col in range(1, board.num_cols + 1):
            stone = board.get(Point(row=row, col=col))
            line.append(STONE_TO_CHAR[stone])
        print('%s%d %s' % (bump, row, ''.join(line)))
    print('    ' + '  '.join(COLS[:board.num_cols]))
示例#6
0
文件: dataset.py 项目: olk/ki-go
 def _encode_and_persist(self, sgf_p):
     sgf = SGFGame.from_string(sgf_p.read_text())
     ## determine winner
     #winner = sgf.get_winner()
     #if winner is None:
     #    print('no winner: %s' % sgf_p.name)
     #    return
     # determine the initial game state by applying all handicap stones
     game_state, first_move_done = self._get_handicap(sgf)
     label = []
     data = []
     # iterate over all moves in the SGF (game)
     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:
                 # get coordinates of this move
                 row, col = move_tuple
                 point = Point(row + 1, col + 1)
                 move = Move.play(point)
                 # allow only valid moves
                 if not game_state.is_valid_move(move):
                     print('invalid move: %s' % sgf_p.name)
                     return
             else:
                 # pass
                 move = Move.pass_turn()
             if first_move_done and point is not None:
             # use only winner's moves
             #if first_move_done and point is not None and winner == color:
                 # encode the current game state as feature
                 d = self.encoder.encode(game_state)
                 # next move is the label for the this feature
                 l = self.encoder.encode_point(point)
                 data.append(d)
                 label.append(l)
             # apply move to board and proceed with next one
             game_state = game_state.apply_move(move)
             first_move_done = True
     # create numpy compressed file
     size = len(data)
     if 0 == size:
         print('empty: %s' % sgf_p.name)
         return
     assert len(label) == size, 'label with invalid size'
     assert len(data) == size, 'data with invalid size'
     npz_p = self.processed_p.joinpath('%s-%s-%d' % (self.encoder.name(), sgf_p.stem, size))
     label = np.array(label, dtype=np.int)
     data = np.array(data, dtype=np.int)
     np.savez_compressed(str(npz_p), d=data, l=label)
示例#7
0
文件: random.py 项目: olk/ki-go
 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))
示例#8
0
    def legal_moves(self):
        if self.is_over():
            return []
        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
示例#9
0
def capture_diff(game_state):
    black_stones = 0
    white_stones = 0
    for r in range(1, game_state.board.num_rows + 1):
        for c in range(1, game_state.board.num_cols + 1):
            p = Point(r, c)
            color = game_state.board.get(p)
            if color == Player.black:
                black_stones += 1
            elif color == Player.white:
                white_stones += 1
    diff = black_stones - white_stones
    if game_state.next_player == Player.black:
        return diff
    return -1 * diff
示例#10
0
文件: dataset.py 项目: olk/ki-go
 def _get_handicap(self, sgf):
     board = Board(19, 19)
     first_move_done = False
     game_state = GameState.new_game(19)
     if sgf.get_handicap() is not None:
         point = None
         for setup in sgf.get_root().get_setup_stones():
             for move in setup:
                 row, col = move
                 point = Point(row + 1, col + 1)
                 board.place_stone(Player.black, point)
         first_move_done = True
         if point is not None:
             game_state = GameState(board, Player.white, None, Move.play(point))
     return game_state, first_move_done
示例#11
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)
示例#12
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
示例#13
0
def gtp_position_to_coords(gtp_position):
    col_str, row_str = gtp_position[0], gtp_position[1:]
    point = Point(int(row_str), COLS.find(col_str.upper()) + 1)
    return point
示例#14
0
def point_from_coords(coords):
    col = COLS.index(coords[0]) + 1
    row = int(coords[1:])
    return Point(row=row, col=col)