3 files changed
+155
-4
No files matched your search
@@ -132,7 +132,9 @@ class SGFNode:
|
||||
|
||||
def add_list_property(self, property: str, values: List):
|
||||
"""Add some values to the property list."""
|
||||
self.properties[property] += values
|
||||
# SiZe[19] ==> SZ[19] etc. for old SGF
|
||||
normalized_property = re.sub("[a-z]", "", property)
|
||||
self.properties[normalized_property] += values
|
||||
|
||||
def get_list_property(self, property, default=None) -> Any:
|
||||
"""Get the list of values for a property."""
|
||||
@@ -323,11 +325,14 @@ class SGF:
|
||||
_NODE_CLASS = SGFNode # Class used for SGF Nodes, can change this to something that inherits from SGFNode
|
||||
# https://xkcd.com/1171/
|
||||
SGFPROP_PAT = re.compile(r"\s*(?:\(|\)|;|(\w+)((\s*\[([^\]\\]|\\.)*\])+))", flags=re.DOTALL)
|
||||
SGF_PAT = re.compile(r"\(;.*\)", flags=re.DOTALL)
|
||||
|
||||
@classmethod
|
||||
def parse_sgf(cls, input_str) -> SGFNode:
|
||||
"""Parse a string as SGF."""
|
||||
return cls(input_str).root
|
||||
match = re.search(cls.SGF_PAT, input_str)
|
||||
clipped_str = match.group() if match else input_str
|
||||
return cls(clipped_str).root
|
||||
|
||||
@classmethod
|
||||
def parse_file(cls, filename, encoding=None) -> SGFNode:
|
||||
@@ -375,7 +380,10 @@ class SGF:
|
||||
if matched_item == "(":
|
||||
self._parse_branch(self._NODE_CLASS(parent=current_move))
|
||||
elif matched_item == ";":
|
||||
if not current_move.empty: # ignore ; that generate empty nodes
|
||||
# ignore ;) for old SGF
|
||||
useless = self.ix < len(self.contents) and self.contents[self.ix] == ")"
|
||||
# ignore ; that generate empty nodes
|
||||
if not (current_move.empty or useless):
|
||||
current_move = self._NODE_CLASS(parent=current_move)
|
||||
else:
|
||||
property, value = match[1], match[2].strip()[1:-1]
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
(
|
||||
;
|
||||
FileFormat[1]GaMe[1]
|
||||
VieW[]
|
||||
SiZe[9]
|
||||
PlayerBlack[hi]
|
||||
PlayerWhite[ka]
|
||||
KoMi[-1.5]
|
||||
Black[ff]
|
||||
;
|
||||
White[gd]
|
||||
;
|
||||
Black[fd]
|
||||
;
|
||||
White[fe]
|
||||
;
|
||||
Black[ge]
|
||||
;
|
||||
White[ee]
|
||||
;
|
||||
Black[gc]
|
||||
;
|
||||
White[hd]
|
||||
;
|
||||
Black[hc]
|
||||
;
|
||||
White[he]
|
||||
;
|
||||
Black[gf]
|
||||
;
|
||||
White[hf]
|
||||
;
|
||||
Black[ed]
|
||||
;
|
||||
White[ef]
|
||||
;
|
||||
Black[eg]
|
||||
;
|
||||
White[dg]
|
||||
;
|
||||
Black[fg]
|
||||
;
|
||||
White[gh]
|
||||
;
|
||||
Black[cg]
|
||||
;
|
||||
White[dh]
|
||||
;
|
||||
Black[df]
|
||||
;
|
||||
White[de]
|
||||
;
|
||||
Black[cf]
|
||||
;
|
||||
White[dd]
|
||||
;
|
||||
Black[dc]
|
||||
;
|
||||
White[ec]
|
||||
;
|
||||
Black[fc]
|
||||
;
|
||||
White[cc]
|
||||
;
|
||||
Black[eb]
|
||||
;
|
||||
White[be]
|
||||
;
|
||||
Black[bf]
|
||||
;
|
||||
White[ce]
|
||||
;
|
||||
Black[bd]
|
||||
;
|
||||
White[ae]
|
||||
;
|
||||
Black[af]
|
||||
;
|
||||
White[db]
|
||||
;
|
||||
Black[ec]
|
||||
;
|
||||
White[bc]
|
||||
;
|
||||
Black[eh]
|
||||
;
|
||||
White[gg]
|
||||
;
|
||||
Black[ch]
|
||||
;
|
||||
White[fh]
|
||||
;
|
||||
Black[di]
|
||||
;
|
||||
White[ic]
|
||||
;
|
||||
Black[cb]
|
||||
;
|
||||
White[bb]
|
||||
;
|
||||
Black[da]
|
||||
;
|
||||
White[hb]
|
||||
;
|
||||
Black[gb]
|
||||
;
|
||||
White[ba]
|
||||
;
|
||||
Black[ca]
|
||||
;
|
||||
White[fi]
|
||||
;
|
||||
Black[id]
|
||||
;
|
||||
White[ib]
|
||||
;
|
||||
Black[ha]
|
||||
;
|
||||
White[ie]
|
||||
;
|
||||
Black[ga]
|
||||
;
|
||||
White[hg]
|
||||
;
|
||||
Black[ia]
|
||||
;
|
||||
Comment[Black: 13 + 4 = 17
|
||||
|
||||
White: 13 + 2 + -1.5 = 13.5
|
||||
|
||||
Black wins by 3.5]
|
||||
White[id]
|
||||
)
|
||||
+11
-1
@@ -59,7 +59,7 @@ def test_pandanet():
|
||||
"GM",
|
||||
"EV",
|
||||
"US",
|
||||
"CoPyright",
|
||||
"CP",
|
||||
"GN",
|
||||
"RE",
|
||||
"PW",
|
||||
@@ -91,6 +91,16 @@ def test_pandanet():
|
||||
assert move is root
|
||||
|
||||
|
||||
def test_old_long_properties():
|
||||
file = os.path.join(os.path.dirname(__file__), "data/xmgt97.sgf")
|
||||
SGF.parse_file(file)
|
||||
|
||||
|
||||
def test_old_server_style():
|
||||
input_sgf = "... 01:23:45 +0900 (JST) ... (;SZ[19];B[aa];W[ba];)"
|
||||
SGF.parse_sgf(input_sgf)
|
||||
|
||||
|
||||
def test_ogs():
|
||||
file = os.path.join(os.path.dirname(__file__), "data/ogs.sgf")
|
||||
tree = SGF.parse_file(file)
|
||||
|
||||
Reference in new issue
Block a user