def is_point_an_eye(board, point, color): # 判断该点是否为一个真眼 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 off_board_corners > 0: return off_board_corners + friendly_corners == 4 return friendly_corners >= 3
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
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(): # All adjacent points must contain friendly stones if board.is_on_grid(neighbor): neighbor_color = board.get(neighbor) if neighbor_color != color: return False friendly_corners = 0 # We must control three out of four corners 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
def is_point_an_eye(board, point, color): #이 점은 집인가 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 off_board_corners > 0: return off_board_corners + friendly_corners == 4 return friendly_corners >= 3
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
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: continue stone = board.get(p) if stone is not None: status[p] = board.get(p) else: group, neighbors = _collect_region(p, board) if len(neighbors) == 1: neighbor_stone = neighbors.pop() stone_str = 'b' if neighbor_stone == Player.black else 'w' fill_with = 'territory_' + stone_str else: fill_with = 'dame' for pos in group: status[pos] = fill_with return Territory(status)
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
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))
def fix_mixed_neighbors(white_probs, game_state, terrmap): print('fix_mixed_neighbors()') BSZ = game_state.board.num_rows white_probs_out = white_probs.copy() board = game_state.board for col in range(0, 19): for row in range(0, 19): p = Point(row + 1, col + 1) if board.get(p): continue # It's empty w = False b = False for n in board.neighbors(p): ncol = board.get(n) if not ncol: continue terrcol = terrmap[n] dead = (((ncol == Player.white) and (terrcol == 'territory_b')) or ((ncol == Player.black) and (terrcol == 'territory_w'))) if dead: continue if ncol == Player.white: w = True elif ncol == Player.black: b = True if w and b: white_probs_out[row * BSZ + col] = 0.5 return white_probs_out
def fix_same_neighbors(white_probs, game_state, terrmap): print('fix_same_neighbors') BSZ = game_state.board.num_rows white_probs_out = white_probs.copy() board = game_state.board for col in range(0, 19): for row in range(0, 19): p = Point(row + 1, col + 1) if board.get(p): continue # It's empty wcount = 0 bcount = 0 ncount = len(board.neighbors(p)) for n in board.neighbors(p): ncol = board.get(n) if not ncol: continue terrcol = terrmap[n] dead = (((ncol == Player.white) and (terrcol == 'territory_b')) or ((ncol == Player.black) and (terrcol == 'territory_w'))) if dead: continue if ncol == Player.white: wcount += 1 elif ncol == Player.black: bcount += 1 if wcount == ncount: white_probs_out[row * BSZ + col] = 1.0 elif bcount == ncount: white_probs_out[row * BSZ + col] = 0.0 return white_probs_out
def probs2terr(white_probs, game_state): BSZ = game_state.board.num_rows # Fix terrmap such that all stones in a string are alive or dead. # Decide by average score. #---------------------------------------------------------------- def enforce_strings(terrmap): strs = game_state.board.get_go_strings() for gostr in strs: avg_col = 0.0 for idx, point in enumerate(gostr.stones): prob_white = white_probs[(point.row - 1) * BSZ + point.col - 1] avg_col = avg_col * (idx / (idx + 1)) + prob_white / (idx + 1) truecolor = 'territory_b' if avg_col < 0.5 else 'territory_w' for point in gostr.stones: terrmap[point] = truecolor colcounts = {'territory_b': 0, 'territory_w': 0, 'dame': 0} for p in terrmap: colcounts[terrmap[p]] += 1 return colcounts['territory_b'], colcounts['territory_w'], colcounts[ 'dame'] terrmap = {} for r in range(1, BSZ + 1): for c in range(1, BSZ + 1): p = Point(row=r, col=c) prob_white = white_probs[(r - 1) * BSZ + c - 1] if color(prob_white) == 'w': terrmap[p] = 'territory_w' elif color(prob_white) == 'b': terrmap[p] = 'territory_b' else: terrmap[p] = 'dame' bpoints, wpoints, dame = enforce_strings(terrmap) print('black:%d' % len( [terrmap[k] for k in terrmap.keys() if terrmap[k] == 'territory_b'])) print('white:%d' % len( [terrmap[k] for k in terrmap.keys() if terrmap[k] == 'territory_w'])) print('dame:%d' % len([terrmap[k] for k in terrmap.keys() if terrmap[k] == 'dame'])) # Split neutral points evenly between players player = game_state.next_player print('%s to move' % ('b' if player == Player.black else 'w')) for i in range(dame): if player == Player.black: bpoints += 1 else: wpoints += 1 player = player.other print('bpoints:%d wpoints:%d dame:%d' % (bpoints, wpoints, dame)) print('result:%d' % (bpoints - wpoints)) return terrmap, bpoints, wpoints, dame
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
def select_move(self, game_state): candidates = [] for r in range(1, game_state.board.num_rows + 1): # range()函数为前一个参数到后一个参数之间,包括之前,不包括之后 for c in range(1, game_state.board.num_cols + 1): candidate = Point(r, 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))
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))
def select_move(self, game_state): """본인의 집을 지킬 수 있는 임의의 유효한 수를 선택한다""" 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))
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) moves.append(Move.pass_turn()) moves.append(Move.resign()) return moves
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
def compute_nn_game_result(labels, next_player): mid = 0.5 # Between B and W #tol = 0.075 # Closer to 0.5 than tol is dame. Smaller means less dame. tol = 0.15 # Closer to 0.5 than tol is dame. Smaller means less dame. labels = labels[0, :] n_isecs = len(labels) boardsize = int(round(np.sqrt(n_isecs))) terrmap = {} bpoints = 0 wpoints = 0 dame = 0 ssum = 0 for r in range(1, boardsize + 1): for c in range(1, boardsize + 1): p = Point(row=r, col=c) prob_white = labels[(r - 1) * boardsize + c - 1] wpoints += prob_white if prob_white < mid - tol: terrmap[p] = 'territory_b' #bpoints += 1 elif prob_white > mid + tol: terrmap[p] = 'territory_w' #wpoints += 1 else: terrmap[p] = 'dame' dame += 1 territory = Territory(terrmap) # bpoints += int( dame / 2) # wpoints += int( dame / 2) wpoints = int(round(wpoints)) bpoints = n_isecs - wpoints # if dame % 2: # if next_player == Player.white: # wpoints += 1 # else: # bpoints += 1 return ( territory, GameResult( bpoints, wpoints, # territory.num_black_territory, # territory.num_white_territory, komi=0))
from dlgo import goboard_slow from dlgo import gotypes from dlgo.utils import print_board, print_move from goboard_slow import Board,GameState, GoString from gotypes import Point, Player ngame = GameState.new_game(9) gobrd = Board(9,9) p1 = Point(row=2,col=2) p2 = Point(row=3,col=3) player = Player.black str = gobrd.place_stone(player, p1) print(str) str = gobrd.place_stone(player, p2) print_board(ngame.board)
import random from gotypes import Player, Point def to_python(player_state): if player_state is None: return 'None' if player_state == Player.black: return Player.black return Player.white MAX63 = 0x7fffffffffffffff table = {} empty_board = 0 for row in range(1, 20): for col in range(1, 20): for state in (Player.black, Player.white): code = random.randint(0, MAX63) table[Point(row, col), state] = code print('from .gotypes import Player, Point') print('') print("__all__ = ['HASH_CODE', 'EMPTY_BOARD']") print('') print('HASH_CODE = {') for (pt, state), hash_code in table.items(): print (' (%r, %s): %r,' % (pt, to_python(state), hash_code)) print('}') print('') print('EMPTY_BOARD = %d' % empty_board,)
def move2coords(move): row, col = move p = Point(row + 1, col + 1) coords = coords_from_point(p) return coords
# http://github.com/timestocome # adapted from: # https://github.com/maxpumperla/betago # https://www.manning.com/books/deep-learning-and-the-game-of-go from gotypes import Player, Point __all__ = ['HASH_CODE', 'EMPTY_BOARD'] HASH_CODE = { (Point(row=16, col=6), Player.white): 2100715686744579875, (Point(row=19, col=5), Player.white): 3992848412730594894, (Point(row=13, col=8), Player.white): 7895486627807721150, (Point(row=19, col=9), Player.black): 7993789417102786953, (Point(row=15, col=5), Player.white): 4551652533125319304, (Point(row=7, col=3), Player.white): 6735711222076572769, (Point(row=17, col=2), Player.black): 8721348491798519293, (Point(row=9, col=7), Player.black): 646172821948969044, (Point(row=4, col=19), Player.black): 887353174930870061, (Point(row=2, col=10), Player.black): 59323898532297044, (Point(row=19, col=7), Player.white): 6797333315934722670, (Point(row=10, col=16), Player.white): 6260575650306244985, (Point(row=18, col=19), Player.black): 7644622523295526128, (Point(row=13, col=5), Player.black): 4841889978183989699, (Point(row=1, col=16), Player.white): 9206555578704673141, (Point(row=5, col=6), Player.black): 8430701632286430282, (Point(row=7, col=11), Player.white): 7727928650614215754, (Point(row=14, col=9), Player.black): 2851509807391420024,