def get_sgf_props(sgf_path): with open(sgf_path) as f: sgf_contents = f.read() collection = sgf.parse(sgf_contents) game = collection.children[0] props = game.root.properties return props
def replay_sgf(sgf_contents): ''' Wrapper for sgf files, exposing contents as position_w_context instances with open(filename) as f: for position_w_context in replay_sgf(f.read()): print(position_w_context.position) ''' collection = sgf.parse(sgf_contents) game = collection.children[0] props = game.root.properties assert int(sgf_prop(props.get('GM', ['1']))) == 1, "Not a Go SGF!" komi = 0 if props.get('KM') != None: komi = float(sgf_prop(props.get('KM'))) metadata = GameMetadata(result=sgf_prop(props.get('RE')), handicap=int(sgf_prop(props.get('HA', [0]))), board_size=int(sgf_prop(props.get('SZ')))) go.set_board_size(metadata.board_size) pos = Position(komi=komi) current_node = game.root while pos is not None and current_node is not None: pos = handle_node(pos, current_node) maybe_correct_next(pos, current_node.next) next_move = get_next_move(current_node) yield PositionWithContext(pos, next_move, metadata) current_node = current_node.next
def replay_sgf(sgf_contents): ''' Wrapper for sgf files, returning go.PositionWithContext instances. It does NOT return the very final position, as there is no follow up. To get the final position, call pwc.position.play_move(pwc.next_move) on the last PositionWithContext returned. Example usage: with open(filename) as f: for position_w_context in replay_sgf(f.read()): print(position_w_context.position) ''' collection = sgf.parse(sgf_contents) game = collection.children[0] props = game.root.properties assert int(sgf_prop(props.get('GM', ['1']))) == 1, "Not a Go SGF!" komi = 0 if props.get('KM') != None: komi = float(sgf_prop(props.get('KM'))) result = utils.parse_game_result(sgf_prop(props.get('RE'))) pos = Position(komi=komi) current_node = game.root while pos is not None and current_node.next is not None: pos = handle_node(pos, current_node) maybe_correct_next(pos, current_node.next) next_move = get_next_move(current_node) yield PositionWithContext(pos, next_move, result) current_node = current_node.next
def replay_sgf(sgf_contents): ''' Wrapper for sgf files, exposing contents as position_w_context instances with open(filename) as f: for position_w_context in replay_sgf(f.read()): print(position_w_context.position) ''' collection = sgf.parse(sgf_contents) game = collection.children[0] props = game.root.properties assert int(sgf_prop(props.get('GM', ['1']))) == 1, "Not a Go SGF!" komi = 0 if props.get('KM') != None: komi = float(sgf_prop(props.get('KM'))) metadata = GameMetadata( result=sgf_prop(props.get('RE')), handicap=int(sgf_prop(props.get('HA', [0]))), board_size=int(sgf_prop(props.get('SZ')))) go.set_board_size(metadata.board_size) pos = Position(komi=komi) current_node = game.root while pos is not None and current_node is not None: pos = handle_node(pos, current_node) maybe_correct_next(pos, current_node.next) next_move = get_next_move(current_node) yield PositionWithContext(pos, next_move, metadata) current_node = current_node.next
def replay_game(sgf_line, func): """Simply recreate a game from a sgf file More of a proof-of-concept or example than really a necessary function. We will use some modified version of this to create the training data. """ collection = sgf.parse(sgf_line) # This all only works if the SGF contains only one game game_tree = collection.children[0] game_properties = game_tree.nodes[0].properties # game_id = game_properties['GN'][0] if not (game_properties['RE'][0].startswith('B') or game_properties['RE'][0].startswith('W')): return None black_win = True if game_properties['RE'][0].startswith('B') else False game = Game(game_properties) # board = Board([[0]*9]*9) out = [] for n in game_tree.nodes[1:]: player_color = list(n.properties.keys())[0] move = Move.from_sgf(str(n.properties[player_color][0])) # board[move.to_matrix_location()] = 1 if player_color=='b' else -1 # neighbors = board.get_all_neigh game.play(move, player_color.lower(), checking=False) out.append(func(game, player_color.lower(), black_win)) out = np.stack(out) # print(out.shape) return out
def check(sgf_path: str): with open(sgf_path) as f: collection = sgf.parse(f.read()) for game in collection: if not check_game(game): return False return True
def importSingleFile(self, currfile): with open(currfile) as f: collection = sgf.parse(f.read()) game = collection[0] # some collections have more games than one, I ignore them for now node = game.nodes moves = [0] * (len(node) - 1) # the node at 0 is the game info (i think) player = [0] * (len(node) - 1) # we need to keep track of who played that move, B=-1, W=+1 boards = [0] * len(node) boards[0] = np.zeros(self.n * self.n, dtype=np.int32) # first board of the game is always empty board boardMatrix = np.zeros((self.n, self.n), dtype=np.int32) for i in range(1, len(node)): # first we extract the next move moves[i - 1] = list(node[i].properties.values())[0][0] player[i - 1] = int(((ord(list(node[i].properties.keys())[0][0]) - 66) / 21 - 0.5) * 2) m = moves[i - 1] if len(m) > 0 and type(m) is str: if 97+self.n > ord(m[0]) > 97: # there are some corrupted files with e.g. "54" as entry, (game 2981) boardMatrix[ord(m[1]) - 97, ord(m[0]) - 97] = player[i - 1] boards[i] = boardMatrix.flatten() self.addToDict(boards[i - 1], boardMatrix, player[i - 1]) # now we play the move on the board and see if we have to remove stones coords = self.toCoords(np.absolute(boards[i] - boards[i - 1])) if type(coords) is not str: self.board.play_stone(coords[1],coords[0],player[i-1]) boards[i] = self.board.vertices.flatten() boardMatrix = self.board.vertices
def replay_sgf(sgf_contents): ''' ''' collection=sgf.parse(sgf_contents) #collection能把数据对象化 便于操作 game=collection.children[0] prop=game.root.properties assert int(sgf_prop(prop.get('GM',['1'])))==1,"这不是围棋棋谱!" #prop.get 取到一个元素 字符转数字 komi=0 #初始化贴子规则 if prop.get('KM') != None: komi=float(sgf_prop(prop.get('KM'))) metadata=GameMetadata( result=sgf_prop(prop.get('RE')), #比赛结果 handicap=int(sgf_prop(prop.get('HA', [0]))), #让子 board_size=int(sgf_prop(prop.get('SZ'))) #棋盘大小 ) go.set_board_size(metadata.board_size) pos=Position(komi=komi) current_node=game.root while pos is not None and current_node is not None : #开始遍历棋谱节点 sgf字母结点 转为纯数字结点 pos = handle_node(pos, current_node) maybe_correct_next(pos, current_node.next) next_move = get_next_move(current_node) yield PositionWithContext(pos, next_move, metadata) current_node = current_node.next pass
def init_collection(self): with open(self.joseki_file) as f: self.joseki_collection = sgf.parse(f.read()) self.current_variation = self.joseki_collection[0] self.node_ind = 0 self.stones = []
def sgf_iter_states(sgf_string, include_end=True): """Iterates over (GameState, move, player) tuples in the first game of the given SGF file. Ignores variations - only the main line is returned. The state object is modified in-place, so don't try to, for example, keep track of it through time If include_end is False, the final tuple yielded is the penultimate state, but the state will still be left in the final position at the end of iteration because 'gs' is modified in-place the state. See sgf_to_gamestate """ collection = sgf.parse(sgf_string) game = collection[0] gs = _sgf_init_gamestate(game.root) if game.rest is not None: for node in game.rest: props = node.properties if 'W' in props: move = _parse_sgf_move(props['W'][0]) player = go.WHITE elif 'B' in props: move = _parse_sgf_move(props['B'][0]) player = go.BLACK yield (gs, move, player) # update state to n+1 gs.do_move(move, player) if include_end: yield (gs, None, None)
def get_sgf_props(sgf_path): # TODO(sethtroisi): move this to sgf_wrapper. with open(sgf_path) as f: sgf_contents = f.read() collection = sgf.parse(sgf_contents) game = collection.children[0] props = game.root.properties return props
def replay_useful(replay): with open(replay, "r") as f: collection = sgf.parse(f.read()) try: sgf_to_npy(collection) except: return False return True
def __init__(self, path): assert path.endswith('.sgf') with open(path, 'r') as f: self.parser = sgf.parse(f.read()) assert len(self.parser.children) > 0 self.game = self.parser.children[0] self.board_size = self.parse_board_size() self.player_black = self.parse_player('B') self.player_white = self.parse_player('W') self.moves = self.parse_moves()
def parse_file(file_name): printer = pprint.PrettyPrinter(indent=2) with open(file_name) as f: collection = sgf.parse(f.read()) print(len(collection.children)) for child in collection.children: # printer.pprint(child.nodes[0].properties) if "PB" in child.nodes[0].properties: print(child.nodes[0].properties["PB"]) if "PW" in child.nodes[0].properties: print(child.nodes[0].properties["PW"])
def process(sgf_path: str) -> str: with open(sgf_path) as f: collection = sgf.parse(f.read()) for game in collection: properties = game.root.properties result = [sgf_path, properties.get("DT",[""])[0], properties.get("PB",[""])[0], properties.get("PW",[""])[0], properties.get("RE",[""])[0]] result = list(map(lambda e: '"' + e + '"', result)) try: result += list(map(lambda e: str(e), winrates_of(game))) except Exception as e: result.append("\"invalid sgf\"") return ",".join(result)
def open(self, filename): self.filepath = filename with open(filename, 'rt') as f: self.sgf = sgf.parse(f.read()) self.nodes = self.sgf.children[0].nodes # 保存了所有落子的记录 self.root = self.sgf.children[0].root # 状态节点(编号0) self.total = len(self.nodes) # 总的状态数 self.step = 0 # 目前是第step步 self.cur = self.root # 当前所处的树节点 self.value = 1 if self.root.properties['RE'][0] == 'W' else -1 # 白方赢为1 #self.board = np.zeros((9,9)) self.status = GoStatus() self.end = False
def game_length(sgf_string: str) -> int: collection = sgf.parse(sgf_string) game = collection[0] if not game.rest: return 0 num_moves = 0 for node in game.rest: if 'W' in node.properties or 'B' in node.properties: num_moves += 1 return num_moves
def parse_sgf(sgf_path): with open(sgf_path) as f: sgf_contents = f.read() collection = sgf.parse(sgf_contents) game = collection.children[0] props = game.root.properties assert int(sgf_prop(props.get('GM', ['1']))) == 1, "Not a Go SGF!" result = utils.parse_game_result(sgf_prop(props.get('RE'))) positions, moves = zip(*[(p.position, p.next_move) for p in sgf_wrapper.replay_sgf(sgf_contents)]) return positions, moves, result, props
def generate_training_set(sgf_files): samples = [] for i in range(len(sgf_files)): t = sgf_files[i] h = open(t) collection = sgf.parse(h.read()) game=collection.children[0] node = game.root a = gamereplay(node) samples.append(a) if i % 1000 == 0: print(str(i)+" sgf files has been read") precessed_data = wishdata(samples) print("%s training set has been generated" % len(precessed_data)) return precessed_data
def parse_sgf(sgf_path): # TODO(sethtroisi): Replace uses with call to sgf_wrapper. with open(sgf_path) as f: sgf_contents = f.read() collection = sgf.parse(sgf_contents) game = collection.children[0] props = game.root.properties assert int(sgf_prop_get(props, 'GM', '1')) == 1, "Not a Go SGF!" result = parse_game_result(sgf_prop_get(props, 'RE', '')) positions, moves = zip(*[(p.position, p.next_move) for p in replay_sgf(sgf_contents)]) return positions, moves, result, props
def from_sgf(cls, sgf_string): # given an SGF file (passed in as a Unicode string), # play out the moves and return the resulting Game collection = sgf.parse(sgf_string) # only look at the first game in the SGF file gametree = collection.children[0] game = None board_size = None rule_set = None # for each node in the game... # (note: we only look at the main variation) for j, node in enumerate(gametree): p = node.properties if 'SZ' in p: board_size = int(p['SZ'][0]) if 'RU' in p: rule_set = { 'Japanese': JAPANESE, 'Chinese': CHINESE }[p['RU'][0]] # if game is not initialized yet, and we have enough info to do so, # initialize it now if (game is None) and (board_size and rule_set): game = Game(board_size, rule_set=rule_set) print 'initialized game, board_size', board_size # todo:add player names, etc def decode_sgf_coordinate(s): # convert from an SGF coordinate string like "bc" to integer coordinates like 2,3 y, x = map(lambda x: ord(x) - ord('a'), s) return (x, y) if 'B' in p: # Black player plays print 'black at', decode_sgf_coordinate(p['B'][0]) game.board.add_move(BLACK, decode_sgf_coordinate(p['B'][0])) if 'W' in p: # White player plays print 'white at', decode_sgf_coordinate(p['W'][0]) game.board.add_move(WHITE, decode_sgf_coordinate(p['W'][0])) return game
def parse_game(self, sgfGame): # list of Move info, contains MoveState objects, plus next moves moves = [] collection = sgf.parse(sgfGame) # always 1 game per file.. for game in collection.children: moveState = MoveState() for node in game: # process each move into a Move object ret = self.process_node(moveState, node) # print(moveState.board) if ret is 0: moves.append(moveState) return moves
def read_manual_data(self, filename): self.board.init_board() states, mcts_probs, current_players = [], [], [] try: with open(filename) as f: collection = sgf.parse(f.read()) for child in collection.children: for node in child.nodes: if len(node.properties) > 1: if node.properties['RE'] == ['黑胜']: winner = 1 elif node.properties['RE'] == ['白胜']: winner = 2 else: winner = -1 print('winner: ', winner) elif len(node.properties) == 1: if 'B' in node.properties: loc = node.properties['B'] elif 'W' in node.properties: loc = node.properties['W'] move = self.location_to_move(loc) # store the data states.append(self.board.current_state()) probs = np.zeros(self.board.width*self.board.height) probs[[move]] = 1 mcts_probs.append(probs) current_players.append(self.board.current_player) # perform a move self.board.do_move(move) else: # winner from the perspective of the current player of each state winners_z = np.zeros(len(current_players)) if winner != -1: winners_z[np.array(current_players) == winner] = 1.0 winners_z[np.array(current_players) != winner] = -1.0 print('winner: ', winner) print('states:', states) print('probs: ', mcts_probs) print('winners_z:') print(winners_z) return winner, zip(states, mcts_probs, winners_z) except: winner0 = 0 print('read chess manual fail') return winner0, zip(states, mcts_probs, np.zeros(len(current_players)))
def test_util(self): path = "D:\\dodi\\BetaGo\\tests\\test_data\\sgf" """ for (dirpath, subdirs, files) in os.walk(path): print dirpath, subdirs, files """ # files = list_sgfs(path) files = walk_all_sgfs(path) for file_name in files: with open(file_name, 'r') as file_object: collection = sgf.parse(file_object.read()) print collection[0].rest prop = collection[0].root.properties print str(prop) #properties is a dict state_action_iterator = sgf_iter_states(file_object.read(), include_end=False) print state_action_iterator
def sgf_iter_states(sgf_string, include_end=True): """ Iterates over (GameState, move, player) tuples in the first game of the given SGF file. Ignores variations - only the main line is returned. The state object is modified in-place, so don't try to, for example, keep track of it through time If include_end is False, the final tuple yielded is the penultimate state, but the state will still be left in the final position at the end of iteration because 'gs' is modified in-place the state. See sgf_to_gamestate """ collection = sgf.parse(sgf_string) game = collection[0] gs = _sgf_init_gamestate(game.root) game_result = game.nodes[0].properties.get('RE') # No result if game_result is None: yield (None, None, None, None) else: if game_result[0][0:2] == 'W+': winner = go.WHITE elif game_result[0][0:2] == 'B+': winner = go.BLACK else: # Non standard result winner = go.EMPTY yield (None, None, None, None) if game.rest is not None: for node in game.rest: props = node.properties if 'W' in props: move = _parse_sgf_move(props['W'][0]) player = go.WHITE elif 'B' in props: move = _parse_sgf_move(props['B'][0]) player = go.BLACK result = 1 if winner == player else -1 yield (gs, move, player, result) # update state to n+1 gs.do_move(move, player) if include_end: yield (gs, go.PASS_MOVE, None, 0)
def main(filename: str) -> None: delta_winrates, file_indices = get_delta_winrates(filename) indices = np.argsort(delta_winrates) print("AI's suggestion") count = 0 for idx in indices: file_index = 0 sgf_filename = file_indices[file_index] for i in file_indices: if i <= idx: file_index = i sgf_filename = file_indices[i] else: break with open(sgf_filename) as f: collection = sgf.parse(f.read()) move_number = idx - file_index + 1 n = 0 for node in collection[0].rest: if "B" in node.properties or "W" in node.properties: n += 1 if n == move_number: winrate, visits = parse_comment(node.properties["C"][0]) if visits >= 400: print(sgf_filename, move_number, delta_winrates[idx]) count += 1 break if count >= 100: break print("surprising move") for idx in indices[::-1]: if delta_winrates[idx] < 0.5: break file_index = 0 sgf_filename = file_indices[file_index] for i in file_indices: if i <= idx: file_index = i sgf_filename = file_indices[i] else: break print(sgf_filename, idx - file_index + 1, delta_winrates[idx])
def sgf_iter_states(sgf_string, include_end=True): collection = sgf.parse(sgf_string) game = collection[0] gs = _sgf_init_gamestate(game.root) if game.rest is not None: for node in game.rest: props = node.properties if 'W' in props: move = _parse_sgf_move(props['W'][0]) player = go.WHITE elif 'B' in props: move = _parse_sgf_move(props['B'][0]) player = go.BLACK yield (gs, move, player) # update state to n+1 gs.do_move(move, player) if include_end: yield (gs, None, None)
def findJoseki(inFile, outputCreater): movesPlayed = 0 joseki = JosekiOnBoard() with open(inFile) as sgfFile: gameCollection = sgf.parse(sgfFile.read()) game = gameCollection[0] for node in game.rest: #first node is header info move = node.current_prop_value[0] colour = node.current_property joseki.addMove(move, colour) movesPlayed += 1 if joseki.numUnsettledCorners <= 0: break for jList in joseki.josekiList[:-1]: outputCreater.addJoseki(jList)
def generate_numpy_dataset(source, location): for key, data in source.items(): print("--- Converting %s Set ---" % key) examples_location = location / key / "examples" labels_location = location / key / "labels" actions_location = location / key / "actions" makedirs(str(examples_location), exist_ok=True) makedirs(str(labels_location), exist_ok=True) makedirs(str(actions_location), exist_ok=True) for idx, replay in enumerate(data): with open(replay, "r") as f: collection = sgf.parse(f.read()) examples, actions, labels = sgf_to_npy(collection) np.save(examples_location / ("%d.npy" % idx), examples) np.save(labels_location / ("%d.npy" % idx), labels) np.save(actions_location / ("%d.npy" % idx), actions) print("%d Replays created." % idx)
def replay_sgf(sgf_contents): collection = sgf.parse(sgf_contents) game = collection.children[0] handicap = 0 HA = game.root.properties.get('HA') if HA is not None: handicap = int(HA[0]) if handicap == 0: position = go.POSITION_POOL.pop() node = game.root while node is not None: s = '' if 'B' in node.properties: s = node.properties.get('B', [''])[0] elif 'W' in node.properties: s = node.properties.get('W', [''])[0] vertex = 0 if len(s) == 2: j = SGF_COLUMNS.index(s[0]) i = SGF_COLUMNS.index(s[1]) vertex = (i + 1) * go.M + j + 1 pos = position.move(vertex) if pos is None: return None # position.debug() # print(s + ": %d, %d, %d" % (i, j, vertex)) pos.update_group() position = pos node = node.next return position return None
def sgf_generator(sgf_string: str, board_size: int, go, include_end=True) -> Generator[Tuple, None, None]: collection = sgf.parse(sgf_string) game = collection[0] root_props = game.root.properties state = _set_up_state(root_props, board_size, go) if 'RE' not in root_props: raise SgfContentError("SGF file does not contain 'RE' property") winner, score = parse_sgf_result(root_props['RE'][0]) if winner == SgfColor.BLACK: winner = go.Color.BLACK elif winner == SgfColor.WHITE: winner = go.Color.WHITE else: winner = go.Color.EMPTY for node in game.rest: props = node.properties if 'W' in props: move = parse_sgf_move(props['W'][0]) player = go.Color.WHITE elif 'B' in props: move = parse_sgf_move(props['B'][0]) player = go.Color.BLACK else: raise SgfContentError("Found a node without move properties") state.current_player = player comment = props.get('C', [''])[0] yield state, move, winner, score, comment state.make_move(move) if include_end: yield state, None, winner, score, ''
def sgf_iter_states(sgf_string): """Iterates over (GameState, move, player) tuples in the first game of the given SGF file. Ignores variations - only the main line is returned. Note that the final tuple returned is the penultimate state, but because 'gs' is modified in-place the state is at the final position after iteration completes. See sgf_to_gamestate """ collection = sgf.parse(sgf_string) game = collection[0] gs = _sgf_init_gamestate(game.root) for node in game.rest: props = node.properties if 'W' in props: move = _parse_sgf_move(props['W'][0]) player = go.WHITE elif 'B' in props: move = _parse_sgf_move(props['B'][0]) player = go.BLACK yield (gs, move, player) # update state to n+1 gs.do_move(move, player)
import goutil import sgf path = input("File: ") board = goutil.Board(path, sgf.parse(open(path).read()).children[0]) while True: try: m = input("Move: ") if m == "n": nb = board.copy() move = nb.next() if move is not None: board = nb print(board.highlight(move[0], move[1], move[2])) else: ms = m.split(' ') x = int(ms[0]) y = int(ms[1]) c = int(ms[2]) if c == 0: c = -1 nb = board.copy() if not nb.make_move(x, y, c): print("Invalid move") else: board = nb print(board.highlight(x, y, c)) except Exception as e: print(e)
CORRECT = 0 # How many predictions did we make? TOTAL = 0 for g in range(0, NUM_RECORDS): # Pick a random record from our list of files. filename = random.choice(FILES) FILES.remove(filename) filename = PATH + filename with open(filename, 'r') as f: r = f.read() board = np.zeros((imgo.CHANNELS, imgo.BOARD_SIZE, imgo.BOARD_SIZE), dtype=np.uint8) game = sgf.parse(r).children[0] # Loop through each move of the game. for node in game.rest: # Run the game through our network. net.blobs['data'].data[...] = board net.forward() pr = net.blobs['loss'].data[0] # Find the 5 moves we think are most likely. moves = [] for i in range(0, 10): idx = pr.argmax() moves.append(idx) pr[idx] = 0 # Don't take moves more than once.
#!/usr/bin/env python import glob import sgf try: from StringIO import StringIO # pragma: no cover except ImportError: # pragma: no cover from io import StringIO # pragma: no cover for filename in glob.glob("examples/*.sgf"): with open(filename) as f: sgf.parse(f.read()) example = "(;FF[4]GM[1]SZ[19];B[aa];W[bb];B[cc];W[dd];B[ad];W[bd])" collection = sgf.parse(example) for game in collection: for node in game: pass out = StringIO() collection[0].nodes[1].output(out) assert out.getvalue() == ";B[aa]" out.close() out = StringIO() collection.output(out) assert out.getvalue() == example