-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsgf_parser.py
127 lines (119 loc) · 4.39 KB
/
sgf_parser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
from board import Board
from tree import Tree, NodeKey
from datetime import datetime
def _load_sgf_based(sgf, sgf_board, sgf_tree, raise_err):
def process_key_value(key, val, board, tree):
def as_vertex_move(m, board):
if len(m) == 0 or m == "tt":
return board.PASS_VERTEX
x = ord(m[0]) - ord('a')
y = ord(m[1]) - ord('a')
y = board.board_size - 1 - y
return board.get_vertex(x, y)
if key == "SZ":
board_size = int(val)
board.reset(board_size, board.komi, board.scoring_rule)
if not tree is None:
tree.get_val()["board"].copy_from(board)
elif key == "KM":
komi = float(val)
board.reset(board.board_size, komi, board.scoring_rule)
if not tree is None:
tree.get_val()["board"].copy_from(board)
elif key == "RU":
scoring_rule = board.transform_scoring_rule(val)
board.reset(board.board_size, board.komi, scoring_rule)
if not tree is None:
tree.get_val()["board"].copy_from(board)
elif key == "C":
if not tree is None:
tree.get_val()["comment"] = val
elif key == "B":
vtx = board.get_gtp_vertex(as_vertex_move(val, board))
col = board.get_gtp_color(board.BLACK)
board.play(vtx, to_move=col)
if not tree is None:
tree.add_and_forward(NodeKey(col, vtx), { "board" : board.copy() })
elif key == "W":
vtx = board.get_gtp_vertex(as_vertex_move(val, board))
col = board.get_gtp_color(board.WHITE)
board.play(vtx, to_move=col)
if not tree is None:
tree.add_and_forward(NodeKey(col, vtx), { "board" : board.copy() })
elif key == "AB" or key == "AW":
raise Exception("Do not support for AB/AW tag in the SGF file.")
try:
level = 0
idx = 0
node_cnt = 0
key = str()
while idx < len(sgf):
c = sgf[idx]
idx += 1;
if c == '(':
level += 1
elif c == ')':
level -= 1
if c in ['(', ')', '\t', '\n', '\r'] or level != 1:
continue
elif c == ';':
node_cnt += 1
elif c == '[':
end = sgf.find(']', idx)
val = sgf[idx:end]
process_key_value(key, val, sgf_board, sgf_tree)
key = str()
idx = end+1
else:
key += c
except Exception as err:
if raise_err:
raise err
def load_sgf_as_tree(sgf, raise_err=False):
board = Board(19, 7.5, Board.SCORING_AREA)
tree = Tree({ "board" : board.copy() })
try:
_load_sgf_based(sgf, board, tree, raise_err)
except Exception as err:
if raise_err:
raise err
return None
return tree
def load_sgf_as_board(sgf, raise_err=False):
board = Board(19, 7.5, Board.SCORING_AREA)
tree = Tree({ "board" : board.copy() })
try:
_load_sgf_based(sgf, board, tree, raise_err)
except Exception as err:
if raise_err:
raise err
return None
return board
def transform_tree_to_sgf(tree, black="NA", white="NA", result=None):
board = tree.get_val()["board"]
sgf = "(;GM[1]FF[4]SZ[{}]KM[{}]RU[{}]PB[{}]PW[{}]DT[{}]".format(
board.board_size, board.komi,
board.transform_scoring_rule(board.scoring_rule),
black, white,
datetime.now().strftime("%Y-%m-%d-%H:%M:%S"))
if result:
sgf += "RE[{}]".format(result)
for node in tree.get_root_mainpath():
if not node.get_key() is None:
col, vtx = node.get_key().unpack()
cstr = "B" if col.is_black() else "W"
if vtx.is_pass():
vstr = "tt" if board.board_size <= 19 else ""
elif vtx.is_resign():
pass
else:
x, y = vtx.get()
y = board.board_size - 1 - y
vstr = str()
vstr += chr(x + ord('a'))
vstr += chr(y + ord('a'))
sgf += ";{}[{}]".format(cstr, vstr)
if not node.get_val().get("comment") is None:
sgf += "C[{}]".format(node.get_val()["comment"])
sgf += ")"
return sgf