# HG changeset patch
# User Laman
# Date 2016-08-14 08:55:54
# Node ID f90261363a85072562c36adfdc8d60dbf6656140
# Parent daac513eadcc24546f4f1182cf8a8e8c32ba6cc4
spaces to tabs
diff --git a/diana.py b/diana.py
--- a/diana.py
+++ b/diana.py
@@ -5,9 +5,9 @@ import os
import sgf
if len(sys.argv)>1:
- files=sys.argv[1:]
+ files=sys.argv[1:]
else:
- sys.exit("no input file specified")
+ sys.exit("no input file specified")
movesPerDiagram=75
minMovesPerDiagram=10
@@ -18,190 +18,190 @@ padding=15
highNumbers=True
class Svg:
- content=""
- footer=""
- extension="svg"
+ content=""
+ footer=""
+ extension="svg"
- padding=15
- gridSize=28
- highNumbers=True
-
- def __init__(self):
- self.content='''
+ padding=15
+ gridSize=28
+ highNumbers=True
+
+ def __init__(self):
+ self.content='''
\n"
+
+
+
+ \n'''.format(2*self.padding+18*self.gridSize)
+ self.footer="\n"
- grid=' \n'
+ grid=' \n'
- # okraje desky
- for i in (0,18):
- self.content+=' \n'.format(self.padding, 18*self.gridSize+self.padding, self.gridSize*i+self.padding, self.gridSize*i+self.padding)
- self.content+=' \n'.format(self.gridSize*i+self.padding, self.gridSize*i+self.padding, self.padding, 18*self.gridSize+self.padding)
-
- # mřížka
- for i in range(1,18):
- self.content+=grid.format(padding, 18*c+padding, c*i+padding, c*i+padding)
- self.content+=grid.format(c*i+padding, c*i+padding, padding, 18*c+padding)
+ # okraje desky
+ for i in (0,18):
+ self.content+=' \n'.format(self.padding, 18*self.gridSize+self.padding, self.gridSize*i+self.padding, self.gridSize*i+self.padding)
+ self.content+=' \n'.format(self.gridSize*i+self.padding, self.gridSize*i+self.padding, self.padding, 18*self.gridSize+self.padding)
+
+ # mřížka
+ for i in range(1,18):
+ self.content+=grid.format(padding, 18*c+padding, c*i+padding, c*i+padding)
+ self.content+=grid.format(c*i+padding, c*i+padding, padding, 18*c+padding)
- # hvězdy
- for i in range(3):
- for j in range(3):
- self.content+=' \n'.format(padding+3*c+6*i*c, padding+3*c+6*j*c, 2)
-
- def __str__(self):
- return self.content+self.footer
-
- def drawStone(self,x,y,color):
- self.content+=' \n'.format(padding+x*c, padding+y*c, c/2-1, color)
+ # hvězdy
+ for i in range(3):
+ for j in range(3):
+ self.content+=' \n'.format(padding+3*c+6*i*c, padding+3*c+6*j*c, 2)
+
+ def __str__(self):
+ return self.content+self.footer
+
+ def drawStone(self,x,y,color):
+ self.content+=' \n'.format(padding+x*c, padding+y*c, c/2-1, color)
- def getFontSize(self,text):
- if len(text)<2: return round(0.7*c)
- elif len(text)<3: return round(0.55*c)
- else: return round(0.4*c)
+ def getFontSize(self,text):
+ if len(text)<2: return round(0.7*c)
+ elif len(text)<3: return round(0.55*c)
+ else: return round(0.4*c)
- def writeLabel(self,x,y,label,color):
- label=str(label)
- fontSize=self.getFontSize(label)
- self.content+=' {4}\n'.format(padding+x*c, padding+y*c+0.35*fontSize, color, fontSize, label)
-
- def drawMove(self,x,y,label,color):
- labelColor="w" if color=="b" else "b"
-
- if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
-
- self.drawStone(x,y,color)
- self.writeLabel(x,y,label,labelColor)
-
- def getContent(self):
- return self.content+self.footer
+ def writeLabel(self,x,y,label,color):
+ label=str(label)
+ fontSize=self.getFontSize(label)
+ self.content+=' {4}\n'.format(padding+x*c, padding+y*c+0.35*fontSize, color, fontSize, label)
+
+ def drawMove(self,x,y,label,color):
+ labelColor="w" if color=="b" else "b"
+
+ if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
+
+ self.drawStone(x,y,color)
+ self.writeLabel(x,y,label,labelColor)
+
+ def getContent(self):
+ return self.content+self.footer
class Tikz:
- content=""
- footer=""
- extension="tex"
-
- highNumbers=True
-
- def __init__(self):
- self.content=r'''\begin{tikzpicture}
- \draw[step=\boardSquare,gray,very thin] (0,0) grid (18\boardSquare,18\boardSquare);
- \draw (0,0) rectangle (18\boardSquare,18\boardSquare);
-
- '''
-
- # hvězdy
- for i in range(3):
- for j in range(3):
- self.content+=r''' \filldraw[fill=black] ({0}\boardSquare,{1}\boardSquare) circle[radius=0.04];'''.format(6*i+3, 6*j+3)+'\n'
- self.content+='\n'
-
- self.footer=r'\end{tikzpicture}' '\n'
-
- def __str__(self):
- return self.content+self.footer
+ content=""
+ footer=""
+ extension="tex"
+
+ highNumbers=True
+
+ def __init__(self):
+ self.content=r'''\begin{tikzpicture}
+ \draw[step=\boardSquare,gray,very thin] (0,0) grid (18\boardSquare,18\boardSquare);
+ \draw (0,0) rectangle (18\boardSquare,18\boardSquare);
+
+ '''
+
+ # hvězdy
+ for i in range(3):
+ for j in range(3):
+ self.content+=r''' \filldraw[fill=black] ({0}\boardSquare,{1}\boardSquare) circle[radius=0.04];'''.format(6*i+3, 6*j+3)+'\n'
+ self.content+='\n'
+
+ self.footer=r'\end{tikzpicture}' '\n'
+
+ def __str__(self):
+ return self.content+self.footer
- def drawStone(self,x,y,color):
- fill="black" if color=="b" else "white"
- self.content+=r' \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare];'.format(fill,x,18-y)+'\n'
-
- def drawMove(self,x,y,label,color):
- fill="black" if color=="b" else "white"
- labelColor="white" if color=="b" else "black"
- if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
-
- self.content+=r' \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare] node[color={3}]{{{4}}};'.format(fill,x,18-y,labelColor,label)+'\n'
-
- def getContent(self):
- return self.content+self.footer
+ def drawStone(self,x,y,color):
+ fill="black" if color=="b" else "white"
+ self.content+=r' \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare];'.format(fill,x,18-y)+'\n'
+
+ def drawMove(self,x,y,label,color):
+ fill="black" if color=="b" else "white"
+ labelColor="white" if color=="b" else "black"
+ if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
+
+ self.content+=r' \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare] node[color={3}]{{{4}}};'.format(fill,x,18-y,labelColor,label)+'\n'
+
+ def getContent(self):
+ return self.content+self.footer
def processFile(fileName):
- shortName="".join(re.split(r'[/\\]',fileName)[-1].split('.')[:-1])
-
- game=go.Go()
- global t
-
- record=sgf.Sgf(open(fileName,'r',encoding="utf-8").read())
- moves=record.getMoves()
+ shortName="".join(re.split(r'[/\\]',fileName)[-1].split('.')[:-1])
+
+ game=go.Go()
+ global t
+
+ record=sgf.Sgf(open(fileName,'r',encoding="utf-8").read())
+ moves=record.getMoves()
- localBoard=dict()
- overlays=""
- letters=dict()
- letter='a'
+ localBoard=dict()
+ overlays=""
+ letters=dict()
+ letter='a'
- diagramsNeeded=(len(moves)-minMovesPerDiagram)//movesPerDiagram+1
- moveNumber=0
-
- for i in range(diagramsNeeded):
- # inicializuj diagram
- diagram=Tikz()
-
- for lineNumber,line in enumerate(game.board):
- for itemNumber,item in enumerate(line):
- if item==1: diagram.drawStone(itemNumber,lineNumber,"b")
- if item==-1: diagram.drawStone(itemNumber,lineNumber,"w")
- localBoard={(a,b):game.board[b][a]-1 for a in range(19) for b in range(19) if game.board[b][a]!=0}
-
- for j in range(movesPerDiagram):
- # kresli tahy
- if moveNumber>=len(moves): break
-
- c,(x,y)=moves[moveNumber]
- c=c.lower()
-
- if not game.move(1 if c=='b' else -1,x,y):
- print("illegal move: {0} at {1},{2}".format(moveNumber+1,x,y))
- moveNumber+=1
- continue
-
- # zapíšu tah na volný průsečík
- if not (x,y) in localBoard:
- localBoard[(x,y)]=moveNumber+1
- diagram.drawMove(x,y,moveNumber+1,c)
- # průsečík je obsazený nepopsaným kamenem
- elif localBoard[(x,y)]<1:
- # průsečík není popsaný ani písmenem
- if not (x,y) in letters:
- letters[(x,y)]=letter
- color='b' if localBoard[(x,y)]==0 else 'w'
- diagram.drawMove(x,y,letter,color)
- letter=chr(ord(letter)+1)
- overlays+="{0} = {1}\n".format(moveNumber+1,letters[(x,y)])
- # průsečík je obsazený očíslovaným kamenem
- else: overlays+="{0} = {1}\n".format(moveNumber+1,localBoard[(x,y)])
-
- moveNumber+=1
-
- # dokonči a ulož diagram
+ diagramsNeeded=(len(moves)-minMovesPerDiagram)//movesPerDiagram+1
+ moveNumber=0
+
+ for i in range(diagramsNeeded):
+ # inicializuj diagram
+ diagram=Tikz()
+
+ for lineNumber,line in enumerate(game.board):
+ for itemNumber,item in enumerate(line):
+ if item==1: diagram.drawStone(itemNumber,lineNumber,"b")
+ if item==-1: diagram.drawStone(itemNumber,lineNumber,"w")
+ localBoard={(a,b):game.board[b][a]-1 for a in range(19) for b in range(19) if game.board[b][a]!=0}
+
+ for j in range(movesPerDiagram):
+ # kresli tahy
+ if moveNumber>=len(moves): break
+
+ c,(x,y)=moves[moveNumber]
+ c=c.lower()
+
+ if not game.move(1 if c=='b' else -1,x,y):
+ print("illegal move: {0} at {1},{2}".format(moveNumber+1,x,y))
+ moveNumber+=1
+ continue
+
+ # zapíšu tah na volný průsečík
+ if not (x,y) in localBoard:
+ localBoard[(x,y)]=moveNumber+1
+ diagram.drawMove(x,y,moveNumber+1,c)
+ # průsečík je obsazený nepopsaným kamenem
+ elif localBoard[(x,y)]<1:
+ # průsečík není popsaný ani písmenem
+ if not (x,y) in letters:
+ letters[(x,y)]=letter
+ color='b' if localBoard[(x,y)]==0 else 'w'
+ diagram.drawMove(x,y,letter,color)
+ letter=chr(ord(letter)+1)
+ overlays+="{0} = {1}\n".format(moveNumber+1,letters[(x,y)])
+ # průsečík je obsazený očíslovaným kamenem
+ else: overlays+="{0} = {1}\n".format(moveNumber+1,localBoard[(x,y)])
+
+ moveNumber+=1
+
+ # dokonči a ulož diagram
# TODO rozumně pracovat s adresáři
- t=open(os.path.join(os.path.dirname(__file__),"out","{0}-{1}.{2}".format(shortName,i+1,diagram.extension)),'w') # nový soubor
- t.write(diagram.getContent())
- t.close()
-
- notes=open(os.path.join(os.path.dirname(__file__),"out","{0}.txt".format(shortName)),'w')
- notes.write(overlays)
- notes.close()
-
+ t=open(os.path.join(os.path.dirname(__file__),"out","{0}-{1}.{2}".format(shortName,i+1,diagram.extension)),'w') # nový soubor
+ t.write(diagram.getContent())
+ t.close()
+
+ notes=open(os.path.join(os.path.dirname(__file__),"out","{0}.txt".format(shortName)),'w')
+ notes.write(overlays)
+ notes.close()
+
print("processing:")
for item in files:
- # relativně vůči work directory nebo vůči skriptu?
- # item=os.path.join(os.path.dirname(__file__),item)
- if os.path.isfile(item):
- print("{0}... ".format(item),end="")
- processFile(item)
- print("done")
- elif os.path.isdir(item):
- files+=[os.path.join(item,child) for child in os.listdir(item)]
- print("contents of the '{0}' directory added to the queue".format(item))
- else: print("the '{0}' path could not be resolved to either a file nor a directory".format(item))
+ # relativně vůči work directory nebo vůči skriptu?
+ # item=os.path.join(os.path.dirname(__file__),item)
+ if os.path.isfile(item):
+ print("{0}... ".format(item),end="")
+ processFile(item)
+ print("done")
+ elif os.path.isdir(item):
+ files+=[os.path.join(item,child) for child in os.listdir(item)]
+ print("contents of the '{0}' directory added to the queue".format(item))
+ else: print("the '{0}' path could not be resolved to either a file nor a directory".format(item))
diff --git a/go.py b/go.py
--- a/go.py
+++ b/go.py
@@ -1,33 +1,33 @@
class Go:
- # 1: B, 0: _, -1: W
- # resp. jakákoli čísla s opačnými znaménky
- board=[[0]*19 for i in range(19)]
-
- def __init__(self): self.board=[[0]*19 for i in range(19)]
-
- def move(self,color,y,x):
- if self.board[x][y]!=0: return False
+ # 1: B, 0: _, -1: W
+ # resp. jakákoli čísla s opačnými znaménky
+ board=[[0]*19 for i in range(19)]
+
+ def __init__(self): self.board=[[0]*19 for i in range(19)]
+
+ def move(self,color,y,x):
+ if self.board[x][y]!=0: return False
- self.board[x][y]=color
+ self.board[x][y]=color
- for i,j in ((-1,0),(1,0),(0,-1),(0,1)):
- self.temp=[[False]*19 for i in range(19)]
- if not self._floodFill(-color,x+i,y+j): self._remove()
- self.temp=[[False]*19 for i in range(19)]
- if not self._floodFill(color,x,y):
- self.board[x][y]=0
- return False
- return True
+ for i,j in ((-1,0),(1,0),(0,-1),(0,1)):
+ self.temp=[[False]*19 for i in range(19)]
+ if not self._floodFill(-color,x+i,y+j): self._remove()
+ self.temp=[[False]*19 for i in range(19)]
+ if not self._floodFill(color,x,y):
+ self.board[x][y]=0
+ return False
+ return True
- def _floodFill(self,color,x,y):
- if x<0 or x>18 or y<0 or y>18: return False
- if self.temp[x][y]: return False
- if self.board[x][y]==0: return True
- if self.board[x][y]!=color: return False
- self.temp[x][y]=True
- return self._floodFill(color,x-1,y) or self._floodFill(color,x+1,y) or self._floodFill(color,x,y-1) or self._floodFill(color,x,y+1)
-
- def _remove(self):
- for i in range(19):
- for j in range(19):
- if self.temp[i][j]: self.board[i][j]=0
+ def _floodFill(self,color,x,y):
+ if x<0 or x>18 or y<0 or y>18: return False
+ if self.temp[x][y]: return False
+ if self.board[x][y]==0: return True
+ if self.board[x][y]!=color: return False
+ self.temp[x][y]=True
+ return self._floodFill(color,x-1,y) or self._floodFill(color,x+1,y) or self._floodFill(color,x,y-1) or self._floodFill(color,x,y+1)
+
+ def _remove(self):
+ for i in range(19):
+ for j in range(19):
+ if self.temp[i][j]: self.board[i][j]=0
diff --git a/sgf-compresor.py b/sgf-compresor.py
deleted file mode 100755
--- a/sgf-compresor.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import re
-import sys
-
-def compressValues(s):
- vals=[]
- indicesX=[]
- for m in re.finditer(r"\[.*?[^\\]\]",s,flags=re.DOTALL):
- vals.append(m.group(0)[1:-1])
- indicesX.append(m.span())
- i=len(indicesX)-1
- for start,end in reversed(indicesX):
- s=s[:start+1]+"$"+str(i)+s[end-1:]
- i-=1
- return s,vals
-
-s=open("c:/Users/Laman/Documents/go/EuroGoTV1-x.sgf",encoding="utf8").read()
-s,d=compressValues(s)
-
-print(s)
-print(d[:20])
-
-sys.exit(0)
-
-# # #
-
-# http://en.wikipedia.org/wiki/Recursive_descent_parser
-
-# # #
-
-import collections
-import re
-
-Token = collections.namedtuple('Token', ['typ', 'value'])
-
-def tokenize(s):
- keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
- token_specification = [
- ('PROPID',r'[A-Z]+'),
- ('PROPVAL',r'\[\$\d+\]'),
- ('NODE',r';'),
- ('LPARENTHESIS',r'\('),
- ('RPARENTHESIS',r'\)'),
- ('SKIP',r'\s')
- ]
- tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
- get_token = re.compile(tok_regex).match
- line = 1
- pos = line_start = 0
- mo = get_token(s)
- while mo is not None:
- typ = mo.lastgroup
- if typ == 'NEWLINE':
- line_start = pos
- line += 1
- elif typ != 'SKIP':
- val = mo.group(typ)
- if typ == 'ID' and val in keywords:
- typ = val
- yield Token(typ, val, line, mo.start()-line_start)
- pos = mo.end()
- mo = get_token(s, pos)
- if pos != len(s):
- raise RuntimeError('Unexpected character %r on line %d' %(s[pos], line))
-
-statements = '''
- IF quantity THEN
- total := total + price * quantity;
- tax := price * 0.05;
- ENDIF;
-'''
-
-for token in tokenize(statements):
- print(token)
-
-tokens=["list of tokens"]
-i=0
-sym
-
-def getSym():
- sym=token[i]
- i+=1
-
-def accept(s):
- if sym==s:
- getSym()
- return True
- else:
- return False
-
-def expect(s):
- if accept(s):
- return True
- else:
- pass # error
- return False
-
-def propValue():
- if accept(lbracket) and cValueType() and expect(rbracket):
- pass
- else:
- pass # error
-
-def propIdent():
- accept(ident)
-
-def propertyX():
- propIdent()
- while propValue(): pass
-
-def node():
- accept(semicolon)
- propertyX()
-
-def sequence():
- while node(): pass
-
-def gameTree():
- accept(lparenthesis)
- sequence()
- while gameTree(): pass
- expect(rparenthesis)
-
-def collection():
- while gameTree(): pass
\ No newline at end of file
diff --git a/sgf.py b/sgf.py
--- a/sgf.py
+++ b/sgf.py
@@ -2,493 +2,493 @@
class Collection:
- gameTrees=[]
-
- def export(self):
- res=""
- for root in gameTrees:
- res+="({0})\n".format(root.fullExport())
- return res
-
+ gameTrees=[]
+
+ def export(self):
+ res=""
+ for root in gameTrees:
+ res+="({0})\n".format(root.fullExport())
+ return res
+
class Node:
- parent=None
- children=[]
- properties={}
-
- def newChild(self):
- child=Node()
- child.parent=self
- self.children.append(child)
- return child
-
- def addChild(self,child):
- child.parent=self
- self.children.append(child)
-
- def delChild(self,index):
- del self.children[index]
-
- def setProperty(self): pass
- def getProperty(self): pass
-
- def fullExport(self):
- res=self.export()
- if len(self.children)==1: res+=children[0].fullExport()
- else:
- for child in self.children:
- res+=child.fullExport()
- return res
-
- def export(self):
- res=";"
- for name,value in properties.items():
- res+="{0}[{1}]".format(name,value) # !! str(value)
- res+="\n"
- return res
-
+ parent=None
+ children=[]
+ properties={}
+
+ def newChild(self):
+ child=Node()
+ child.parent=self
+ self.children.append(child)
+ return child
+
+ def addChild(self,child):
+ child.parent=self
+ self.children.append(child)
+
+ def delChild(self,index):
+ del self.children[index]
+
+ def setProperty(self): pass
+ def getProperty(self): pass
+
+ def fullExport(self):
+ res=self.export()
+ if len(self.children)==1: res+=children[0].fullExport()
+ else:
+ for child in self.children:
+ res+=child.fullExport()
+ return res
+
+ def export(self):
+ res=";"
+ for name,value in properties.items():
+ res+="{0}[{1}]".format(name,value) # !! str(value)
+ res+="\n"
+ return res
+
class Property:
- name=""
- value=None
+ name=""
+ value=None
class ListOf(Property):
- values=[]
- vType=None
+ values=[]
+ vType=None
- def __str__(self):
- return "["+"][".join(self.values)+"]"
-
+ def __str__(self):
+ return "["+"][".join(self.values)+"]"
+
class Composed(Property):
- value=()
-
- def __str__(self):
- return self.value[0]+":"+self.value[1] # !! str(self.value[0])
+ value=()
+
+ def __str__(self):
+ return self.value[0]+":"+self.value[1] # !! str(self.value[0])
class Point(Property): # !! pass
- row=0
- col=0
-
- def __str__(self):
- f=lambda x: chr(x+ord("a")) if x<26 else chr(x-26+ord("A"))
- row=f(self.row)
- col=f(self.col)
-
- return col+row
-
+ row=0
+ col=0
+
+ def __str__(self):
+ f=lambda x: chr(x+ord("a")) if x<26 else chr(x-26+ord("A"))
+ row=f(self.row)
+ col=f(self.col)
+
+ return col+row
+
-
+
def skipWhitespace(str,start):
- i=start
- while i=len(str) or str[i]!="(":
- # print("error when parsing GameTree")
- return (start,None)
- i=skipWhitespace(str,i)
- i,x=Node.create(str,start+1)
- if x is None:
- # print("error when parsing GameTree")
- return (i,None)
- while x is not None:
- res.nodes.append(x)
- i=skipWhitespace(str,i)
- i,x=Node.create(str,i)
- i=skipWhitespace(str,i)
- i,x=GameTree.create(str,i)
- while x is not None:
- res.branches.append(x)
- i=skipWhitespace(str,i)
- i,x=GameTree.create(str,i)
- if str[i]!=")":
- # print("error when parsing GameTree")
- return (i,None)
- return (i+1,res)
-
+ nodes=[]
+ branches=[]
+
+ def create(str,start):
+ res=GameTree()
+ i=skipWhitespace(str,start)
+ if i>=len(str) or str[i]!="(":
+ # print("error when parsing GameTree")
+ return (start,None)
+ i=skipWhitespace(str,i)
+ i,x=Node.create(str,start+1)
+ if x is None:
+ # print("error when parsing GameTree")
+ return (i,None)
+ while x is not None:
+ res.nodes.append(x)
+ i=skipWhitespace(str,i)
+ i,x=Node.create(str,i)
+ i=skipWhitespace(str,i)
+ i,x=GameTree.create(str,i)
+ while x is not None:
+ res.branches.append(x)
+ i=skipWhitespace(str,i)
+ i,x=GameTree.create(str,i)
+ if str[i]!=")":
+ # print("error when parsing GameTree")
+ return (i,None)
+ return (i+1,res)
+
class Node:
- properties=dict()
-
- def create(str,start):
- res=Node()
- if str[start]!=";":
- # print("error when parsing Node")
- return (start,None)
- i=skipWhitespace(str,start+1)
- i,x=Property.create(str,i)
- while x is not None:
- if x.name in res.properties:
- print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
- else:
- res.properties[x.name]=x
- i=skipWhitespace(str,i)
- i,x=Property.create(str,i)
- return (i,res)
-
- def setProperty(self,name,value):
- self.properties[name]=value
- # zkontrolovat typ value
-
- def getProperty(self,name):
- if name in self.properties: return self.properties[name]
- else: return None
-
+ properties=dict()
+
+ def create(str,start):
+ res=Node()
+ if str[start]!=";":
+ # print("error when parsing Node")
+ return (start,None)
+ i=skipWhitespace(str,start+1)
+ i,x=Property.create(str,i)
+ while x is not None:
+ if x.name in res.properties:
+ print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
+ else:
+ res.properties[x.name]=x
+ i=skipWhitespace(str,i)
+ i,x=Property.create(str,i)
+ return (i,res)
+
+ def setProperty(self,name,value):
+ self.properties[name]=value
+ # zkontrolovat typ value
+
+ def getProperty(self,name):
+ if name in self.properties: return self.properties[name]
+ else: return None
+
class Property:
- name=""
- value=""
-
- def create(str,start):
- res=Property()
- i,x=Property.ident(str,start)
- if x is None:
- return (start,None)
- res.name=x
- i,x=PropValue.create(str,i,res.name)
- if x is None:
- print('error when parsing property "{0}" at position {1}'.format(res.name,i))
- return (start,None)
- # while x is not None: # přesunuto do PropValue.listOf
- # res.values.append(x)
- # i=skipWhitespace(str,i)
- # i,x=PropValue.create(str,i,res.name)
- res.values.append(x) # !! podezřelé
- return (i,res)
-
- def ident(str,start):
- r=re.compile(r"[A-Z]+")
- m=r.match(str,start)
- if m is None: return (start,None)
- return (m.end(),m.group())
+ name=""
+ value=""
+
+ def create(str,start):
+ res=Property()
+ i,x=Property.ident(str,start)
+ if x is None:
+ return (start,None)
+ res.name=x
+ i,x=PropValue.create(str,i,res.name)
+ if x is None:
+ print('error when parsing property "{0}" at position {1}'.format(res.name,i))
+ return (start,None)
+ # while x is not None: # přesunuto do PropValue.listOf
+ # res.values.append(x)
+ # i=skipWhitespace(str,i)
+ # i,x=PropValue.create(str,i,res.name)
+ res.values.append(x) # !! podezřelé
+ return (i,res)
+
+ def ident(str,start):
+ r=re.compile(r"[A-Z]+")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ return (m.end(),m.group())
class PropValue:
- type=""
- value=None
- patterns=dict()
-
- def create(str,start,name):
- if name in PropValue.patterns:
- return PropValue.patterns[name](str,start)
- else:
- print('warning, unknown property "{0}" at position {1}'.format(name,start))
- return PropValue.singleton(PropValue.anything)(str,start)
-
- # def singleton(str,start,vType):
- # if str[start]!="[":
- # return (start,None)
- # i,x=vType(str,start+1)
- # if x is None: return (start,None)
- # if str[i]!="]":
- # return (start,None)
- # return (i+1,x)
-
- def choose(*vTypes):
- def f(str,start):
- for vType in vTypes:
- i,x=vType(str,start)
- if x is not None: return (i,x)
- return (start,None)
- return f
-
- def singleton(vType):
- def f(str,start):
- if str[start]!="[":
- return (start,None)
- i,x=vType(str,start+1)
- if x is None: return (start,None)
- if str[i]!="]":
- return (start,None)
- return (i+1,x)
- return f
-
- # def listOf(str,start,vType,allowEmpty=False):
- # res=[]
- # i,x=singleton(str,start,vType)
- # # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
- # while x!=None:
- # res.append(x)
- # i,x=singleton(str,i,vType)
- # if len(res)==0 and not allowEmpty: return (start,None)
- # return (i,res)
-
- def listOf(vType,allowEmpty=False):
- def f(str,start):
- res=[]
- single=singleton(vType)
- i,x=single(str,start)
- while x!=None:
- res.append(x)
- i,x=single(str,i)
- if len(res)==0 and not allowEmpty: return (start,None)
- return (i,res)
- return f
-
- # def compose(str,start,vTypeA,vTypeB):
- # i,a=vTypeA(str,start)
- # if a==None or str[i]!=":": return (start,None)
- # i,b=vTypeB(str,i+1)
- # if b==None: return start,None
- # return (i,(a,b))
-
- def compose(vTypeA,vTypeB):
- def f(str,start):
- i,a=vTypeA(str,start)
- # print(">",i,a)
- if a==None or str[i]!=":": return (start,None)
- i,b=vTypeB(str,i+1)
- # print(">",i,b)
- if b==None: return start,None
- return (i,(a,b))
- return f
-
- def number(str,start):
- r=re.compile(r"(\+|-|)\d+")
- m=r.match(str,start)
- if m is None: return (start,None)
- res=int(m.group(0))
- return (m.end(),res)
-
- def real(str,start):
- r=re.compile(r"(\+|-|)\d+(\.\d+)?")
- m=r.match(str,start)
- if m is None: return (start,None)
- res=float(m.group(0))
- return (m.end(),res)
-
- def double(str,start):
- r=re.compile(r"1|2")
- m=r.match(str,start)
- if m is None: return (start,None)
- res=int(m.group(0))
- return (m.end(),res)
-
- def color(str,start):
- r=re.compile(r"B|W")
- m=r.match(str,start)
- if m is None: return (start,None)
- return (m.end(),m.group(0))
-
- # def simpleText(str,start):
- # res=""
- # esc=False
- # lineBreak=False
- # for c in str:
- # if esc:
- # res+=c
- # esc=False
- # elif c=="\\":
- # esc=True
- # elif c=="]":
- # break
- # else:
- # res+=c
- # return res
-
- def text(simple=True,composed=False):
- def f(str,start):
- res=""
- esc=False
- lastC=""
- for i,c in enumerate(str[start:],start):
- if esc:
- if c!="\n" and c!="\r": res+=c
- esc=False
- elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
- elif c=="\r" or c=="\n" and not simple:
- res+="\n"
- elif c.isspace():
- res+=" "
- elif c=="\\":
- esc=True
- elif c=="]" or (c==":" and composed):
- break
- else:
- res+=c
- lastC=c
- return (i,res)
- return f
-
- def empty(str,start): return (start,"")
-
- def anything(str,start): # přidat listOf
- esc=False
- for i,c in enumerate(str[start:],start):
- if esc: esc=False
- elif c=="\\": esc=True
- elif c=="]": break
- return (i,str[start:i])
-
- # go specific
- def point(str,start):
- r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
- m=r.match(str,start)
- if m is None: return (start,None)
- if m.group(0)=="": # pass, !! tt
- return (m.end(),tuple())
- col=m.group(0)[0]
- row=m.group(0)[1]
- col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
- row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
- return (m.end(),(col,row))
+ type=""
+ value=None
+ patterns=dict()
+
+ def create(str,start,name):
+ if name in PropValue.patterns:
+ return PropValue.patterns[name](str,start)
+ else:
+ print('warning, unknown property "{0}" at position {1}'.format(name,start))
+ return PropValue.singleton(PropValue.anything)(str,start)
+
+ # def singleton(str,start,vType):
+ # if str[start]!="[":
+ # return (start,None)
+ # i,x=vType(str,start+1)
+ # if x is None: return (start,None)
+ # if str[i]!="]":
+ # return (start,None)
+ # return (i+1,x)
+
+ def choose(*vTypes):
+ def f(str,start):
+ for vType in vTypes:
+ i,x=vType(str,start)
+ if x is not None: return (i,x)
+ return (start,None)
+ return f
+
+ def singleton(vType):
+ def f(str,start):
+ if str[start]!="[":
+ return (start,None)
+ i,x=vType(str,start+1)
+ if x is None: return (start,None)
+ if str[i]!="]":
+ return (start,None)
+ return (i+1,x)
+ return f
+
+ # def listOf(str,start,vType,allowEmpty=False):
+ # res=[]
+ # i,x=singleton(str,start,vType)
+ # # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
+ # while x!=None:
+ # res.append(x)
+ # i,x=singleton(str,i,vType)
+ # if len(res)==0 and not allowEmpty: return (start,None)
+ # return (i,res)
+
+ def listOf(vType,allowEmpty=False):
+ def f(str,start):
+ res=[]
+ single=singleton(vType)
+ i,x=single(str,start)
+ while x!=None:
+ res.append(x)
+ i,x=single(str,i)
+ if len(res)==0 and not allowEmpty: return (start,None)
+ return (i,res)
+ return f
+
+ # def compose(str,start,vTypeA,vTypeB):
+ # i,a=vTypeA(str,start)
+ # if a==None or str[i]!=":": return (start,None)
+ # i,b=vTypeB(str,i+1)
+ # if b==None: return start,None
+ # return (i,(a,b))
+
+ def compose(vTypeA,vTypeB):
+ def f(str,start):
+ i,a=vTypeA(str,start)
+ # print(">",i,a)
+ if a==None or str[i]!=":": return (start,None)
+ i,b=vTypeB(str,i+1)
+ # print(">",i,b)
+ if b==None: return start,None
+ return (i,(a,b))
+ return f
+
+ def number(str,start):
+ r=re.compile(r"(\+|-|)\d+")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ res=int(m.group(0))
+ return (m.end(),res)
+
+ def real(str,start):
+ r=re.compile(r"(\+|-|)\d+(\.\d+)?")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ res=float(m.group(0))
+ return (m.end(),res)
+
+ def double(str,start):
+ r=re.compile(r"1|2")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ res=int(m.group(0))
+ return (m.end(),res)
+
+ def color(str,start):
+ r=re.compile(r"B|W")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ return (m.end(),m.group(0))
+
+ # def simpleText(str,start):
+ # res=""
+ # esc=False
+ # lineBreak=False
+ # for c in str:
+ # if esc:
+ # res+=c
+ # esc=False
+ # elif c=="\\":
+ # esc=True
+ # elif c=="]":
+ # break
+ # else:
+ # res+=c
+ # return res
+
+ def text(simple=True,composed=False):
+ def f(str,start):
+ res=""
+ esc=False
+ lastC=""
+ for i,c in enumerate(str[start:],start):
+ if esc:
+ if c!="\n" and c!="\r": res+=c
+ esc=False
+ elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
+ elif c=="\r" or c=="\n" and not simple:
+ res+="\n"
+ elif c.isspace():
+ res+=" "
+ elif c=="\\":
+ esc=True
+ elif c=="]" or (c==":" and composed):
+ break
+ else:
+ res+=c
+ lastC=c
+ return (i,res)
+ return f
+
+ def empty(str,start): return (start,"")
+
+ def anything(str,start): # přidat listOf
+ esc=False
+ for i,c in enumerate(str[start:],start):
+ if esc: esc=False
+ elif c=="\\": esc=True
+ elif c=="]": break
+ return (i,str[start:i])
+
+ # go specific
+ def point(str,start):
+ r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ if m.group(0)=="": # pass, !! tt
+ return (m.end(),tuple())
+ col=m.group(0)[0]
+ row=m.group(0)[1]
+ col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
+ row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
+ return (m.end(),(col,row))
- move=point
- stone=point
-
- patterns={
- "B":singleton(move),
- "KO":singleton(empty),
- "MN":singleton(number),
- "W":singleton(move),
- "AB":listOf(stone), #
- "AE":listOf(point), #
- "AW":listOf(stone), #
- "PL":singleton(color),
- "C":singleton(text(simple=False)),
- "DM":singleton(double),
- "GB":singleton(double),
- "GW":singleton(double),
- "HO":singleton(double),
- "N":singleton(text()),
- "UC":singleton(double),
- "V":singleton(real),
- "BM":singleton(double),
- "DO":singleton(empty),
- "IT":singleton(empty),
- "TE":singleton(double),
- "AR":listOf(compose(point,point)), #
- "CR":listOf(point), #
- "DD":listOf(point,allowEmpty=True), #
- "LB":listOf(compose(point,text())), #
- "LN":listOf(compose(point,point)), #
- "MA":listOf(point), #
- "SL":listOf(point), #
- "SQ":listOf(point), #
- "TR":listOf(point), #
- "AP":singleton(compose(text(composed=True),text())), #
- "CA":singleton(text()),
- "FF":singleton(number),
- "GM":singleton(number),
- "ST":singleton(number),
- "SZ":choose(singleton(number),singleton(compose(number,number))), #
- "AN":singleton(text()),
- "BR":singleton(text()),
- "BT":singleton(text()),
- "CP":singleton(text()),
- "DT":singleton(text()),
- "EV":singleton(text()),
- "GN":singleton(text()),
- "GC":singleton(text(simple=False)),
- "ON":singleton(text()),
- "OT":singleton(text()),
- "PB":singleton(text()),
- "PC":singleton(text()),
- "PW":singleton(text()),
- "RE":singleton(text()),
- "RO":singleton(text()),
- "RU":singleton(text()),
- "SO":singleton(text()),
- "TM":singleton(real),
- "US":singleton(text()),
- "WR":singleton(text()),
- "WT":singleton(text()),
- "BL":singleton(real),
- "OB":singleton(number),
- "OW":singleton(number),
- "WL":singleton(real),
- "FG":choose(singleton(empty),singleton(compose(number,text()))), #
- "PM":singleton(number),
- "VW":listOf(point,allowEmpty=True), #
-
- # go specific
- "HA":singleton(number),
- "KM":singleton(real),
- "TB":listOf(point,allowEmpty=True),
- "TW":listOf(point,allowEmpty=True)
- }
+ move=point
+ stone=point
+
+ patterns={
+ "B":singleton(move),
+ "KO":singleton(empty),
+ "MN":singleton(number),
+ "W":singleton(move),
+ "AB":listOf(stone), #
+ "AE":listOf(point), #
+ "AW":listOf(stone), #
+ "PL":singleton(color),
+ "C":singleton(text(simple=False)),
+ "DM":singleton(double),
+ "GB":singleton(double),
+ "GW":singleton(double),
+ "HO":singleton(double),
+ "N":singleton(text()),
+ "UC":singleton(double),
+ "V":singleton(real),
+ "BM":singleton(double),
+ "DO":singleton(empty),
+ "IT":singleton(empty),
+ "TE":singleton(double),
+ "AR":listOf(compose(point,point)), #
+ "CR":listOf(point), #
+ "DD":listOf(point,allowEmpty=True), #
+ "LB":listOf(compose(point,text())), #
+ "LN":listOf(compose(point,point)), #
+ "MA":listOf(point), #
+ "SL":listOf(point), #
+ "SQ":listOf(point), #
+ "TR":listOf(point), #
+ "AP":singleton(compose(text(composed=True),text())), #
+ "CA":singleton(text()),
+ "FF":singleton(number),
+ "GM":singleton(number),
+ "ST":singleton(number),
+ "SZ":choose(singleton(number),singleton(compose(number,number))), #
+ "AN":singleton(text()),
+ "BR":singleton(text()),
+ "BT":singleton(text()),
+ "CP":singleton(text()),
+ "DT":singleton(text()),
+ "EV":singleton(text()),
+ "GN":singleton(text()),
+ "GC":singleton(text(simple=False)),
+ "ON":singleton(text()),
+ "OT":singleton(text()),
+ "PB":singleton(text()),
+ "PC":singleton(text()),
+ "PW":singleton(text()),
+ "RE":singleton(text()),
+ "RO":singleton(text()),
+ "RU":singleton(text()),
+ "SO":singleton(text()),
+ "TM":singleton(real),
+ "US":singleton(text()),
+ "WR":singleton(text()),
+ "WT":singleton(text()),
+ "BL":singleton(real),
+ "OB":singleton(number),
+ "OW":singleton(number),
+ "WL":singleton(real),
+ "FG":choose(singleton(empty),singleton(compose(number,text()))), #
+ "PM":singleton(number),
+ "VW":listOf(point,allowEmpty=True), #
+
+ # go specific
+ "HA":singleton(number),
+ "KM":singleton(real),
+ "TB":listOf(point,allowEmpty=True),
+ "TW":listOf(point,allowEmpty=True)
+ }
"""def property(str):
- # i=propIdent(str)
- # if i<0: return -1
- # j=i
- # i=propValue(str[i:])
- # while i>=0:
- # j+=i
- # i=propValue(str[i:])
- # return j
+ # i=propIdent(str)
+ # if i<0: return -1
+ # j=i
+ # i=propValue(str[i:])
+ # while i>=0:
+ # j+=i
+ # i=propValue(str[i:])
+ # return j
def propIdent(str):
- m=re.match(r"[A-Z]+",str)
- if m is None: return -1
- return m.end()
+ m=re.match(r"[A-Z]+",str)
+ if m is None: return -1
+ return m.end()
def propValue(str):
- i=cValueType(str[1:])
- if str[0]=="[" and i>=0 and str[i]=="]": return i+1
- else: return -1
+ i=cValueType(str[1:])
+ if str[0]=="[" and i>=0 and str[i]=="]": return i+1
+ else: return -1
class propValue:
- pass
+ pass
def cValueType(str,start):
- matches=[real,number,double,color,simpleText]
- for f in matches:
- i,x=f(str,start)
- if x is not None: return i,x
- return 1/0
+ matches=[real,number,double,color,simpleText]
+ for f in matches:
+ i,x=f(str,start)
+ if x is not None: return i,x
+ return 1/0
def number(str,start):
- r=re.compile(r"(\+|-|)\d+")
- m=r.match(str,start)
- if m is None: return (-1,None)
- x=int(m.group(0))
- return (m.end(),x)
+ r=re.compile(r"(\+|-|)\d+")
+ m=r.match(str,start)
+ if m is None: return (-1,None)
+ x=int(m.group(0))
+ return (m.end(),x)
def real(str):
- m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
- if m is None: return -1
- return m.end()
+ m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
+ if m is None: return -1
+ return m.end()
def double(str):
- m=re.match(r"1|2",str)
- if m is None: return -1
- return m.end()
-
+ m=re.match(r"1|2",str)
+ if m is None: return -1
+ return m.end()
+
def color(str):
- m=re.match(r"B|W",str)
- if m is None: return -1
- return m.end()
-
+ m=re.match(r"B|W",str)
+ if m is None: return -1
+ return m.end()
+
def simpleText(str):
- res=r""
- esc=False
- for c in str:
- if esc:
- res+=c
- esc=False
- elif c=="\\":
- esc=True
- elif c=="]":
- break
- else:
- res+=c
- return res"""
+ res=r""
+ esc=False
+ for c in str:
+ if esc:
+ res+=c
+ esc=False
+ elif c=="\\":
+ esc=True
+ elif c=="]":
+ break
+ else:
+ res+=c
+ return res"""
sgf=open("in/1-Hora-Simara.sgf").read()
diff --git a/sgfParser.py b/sgfParser.py
--- a/sgfParser.py
+++ b/sgfParser.py
@@ -1,434 +1,434 @@
import re
-
+
def skipWhitespace(str,start):
- i=start
- while i=len(str) or str[i]!="(":
- # print("error when parsing GameTree")
- return (start,None)
- i,x=Node.create(str,start+1)
- if x is None:
- # print("error when parsing GameTree")
- return (i,None)
- while x is not None:
- res.nodes.append(x)
- i=skipWhitespace(str,i)
- i,x=Node.create(str,i)
- i=skipWhitespace(str,i)
- i,x=GameTree.create(str,i)
- while x is not None:
- res.branches.append(x)
- i=skipWhitespace(str,i)
- i,x=GameTree.create(str,i)
- if str[i]!=")":
- # print("error when parsing GameTree")
- return (i,None)
- return (i+1,res)
-
+ nodes=[]
+ branches=[]
+
+ # def __init__(self,str,start):
+ # self.nodes=[]
+ # self.branches=[]
+ # if str[start]!="(":
+ # print("error when parsing GameTree")
+ # return (-1,None)
+ # i,x=Node(str,start+1)
+ # if x is None:
+ # print("error when parsing GameTree")
+ # return (-1,None)
+ # while x is not None:
+ # self.nodes.append(x)
+ # i,x=Node(str,i)
+ # if str[i]!=")":
+ # print("error when parsing GameTree")
+ # return (-1,None)
+ # return (i+1,self)
+
+ def create(str,start):
+ res=GameTree()
+ i=skipWhitespace(str,start)
+ if i>=len(str) or str[i]!="(":
+ # print("error when parsing GameTree")
+ return (start,None)
+ i,x=Node.create(str,start+1)
+ if x is None:
+ # print("error when parsing GameTree")
+ return (i,None)
+ while x is not None:
+ res.nodes.append(x)
+ i=skipWhitespace(str,i)
+ i,x=Node.create(str,i)
+ i=skipWhitespace(str,i)
+ i,x=GameTree.create(str,i)
+ while x is not None:
+ res.branches.append(x)
+ i=skipWhitespace(str,i)
+ i,x=GameTree.create(str,i)
+ if str[i]!=")":
+ # print("error when parsing GameTree")
+ return (i,None)
+ return (i+1,res)
+
class Node:
- properties=dict()
-
- def create(str,start):
- res=Node()
- if str[start]!=";":
- # print("error when parsing Node")
- return (start,None)
- i=skipWhitespace(str,start+1)
- i,x=Property.create(str,start+1)
- while x is not None:
- if x.name in res.properties:
- print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
- else:
- res.properties[x.name]=x
- i=skipWhitespace(str,i)
- i,x=Property.create(str,i)
- return (i,res)
-
- def setProperty(self,name,value):
- self.properties[name]=value
- # zkontrolovat typ value
-
- def getProperty(self,name):
- if name in self.properties: return self.properties[name]
- else: return None
-
+ properties=dict()
+
+ def create(str,start):
+ res=Node()
+ if str[start]!=";":
+ # print("error when parsing Node")
+ return (start,None)
+ i=skipWhitespace(str,start+1)
+ i,x=Property.create(str,start+1)
+ while x is not None:
+ if x.name in res.properties:
+ print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
+ else:
+ res.properties[x.name]=x
+ i=skipWhitespace(str,i)
+ i,x=Property.create(str,i)
+ return (i,res)
+
+ def setProperty(self,name,value):
+ self.properties[name]=value
+ # zkontrolovat typ value
+
+ def getProperty(self,name):
+ if name in self.properties: return self.properties[name]
+ else: return None
+
class Property:
- name=""
- value=""
-
- def create(str,start):
- res=Property()
- i,x=Property.ident(str,start)
- if x is None:
- return (start,None)
- res.name=x
- i,x=PropValue.create(str,i,res.name)
- if x is None:
- print('error when parsing property "{0}" at position {1}'.format(res.name,i))
- return (start,None)
- # while x is not None: # přesunuto do PropValue.listOf
- # res.values.append(x)
- # i=skipWhitespace(str,i)
- # i,x=PropValue.create(str,i,res.name)
- return (i,res)
-
- def ident(str,start):
- r=re.compile(r"[A-Z]+")
- m=r.match(str,start)
- if m is None: return (start,None)
- return (m.end(),m.group())
+ name=""
+ value=""
+
+ def create(str,start):
+ res=Property()
+ i,x=Property.ident(str,start)
+ if x is None:
+ return (start,None)
+ res.name=x
+ i,x=PropValue.create(str,i,res.name)
+ if x is None:
+ print('error when parsing property "{0}" at position {1}'.format(res.name,i))
+ return (start,None)
+ # while x is not None: # přesunuto do PropValue.listOf
+ # res.values.append(x)
+ # i=skipWhitespace(str,i)
+ # i,x=PropValue.create(str,i,res.name)
+ return (i,res)
+
+ def ident(str,start):
+ r=re.compile(r"[A-Z]+")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ return (m.end(),m.group())
class PropValue:
- type=""
- value=None
- patterns=dict()
-
- def create(str,start,name):
- if name in PropValue.patterns:
- return PropValue.patterns[name](str,start)
- else:
- print('warning, unknown property "{0}" at position {1}'.format(name,start))
- return PropValue.singleton(PropValue.anything)(str,start)
-
- # def singleton(str,start,vType):
- # if str[start]!="[":
- # return (start,None)
- # i,x=vType(str,start+1)
- # if x is None: return (start,None)
- # if str[i]!="]":
- # return (start,None)
- # return (i+1,x)
-
- def choose(*vTypes):
- def f(str,start):
- for vType in vTypes:
- i,x=vType(str,start)
- if x is not None: return (i,x)
- return (start,None)
- return f
-
- def singleton(vType):
- def f(str,start):
- if str[start]!="[":
- return (start,None)
- i,x=vType(str,start+1)
- if x is None: return (start,None)
- if str[i]!="]":
- return (start,None)
- return (i+1,x)
- return f
-
- # def listOf(str,start,vType,allowEmpty=False):
- # res=[]
- # i,x=singleton(str,start,vType)
- # # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
- # while x!=None:
- # res.append(x)
- # i,x=singleton(str,i,vType)
- # if len(res)==0 and not allowEmpty: return (start,None)
- # return (i,res)
-
- def listOf(vType,allowEmpty=False):
- def f(str,start):
- res=[]
- single=singleton(vType)
- i,x=single(str,start)
- while x!=None:
- res.append(x)
- i,x=single(str,i)
- if len(res)==0 and not allowEmpty: return (start,None)
- return (i,res)
- return f
-
- # def compose(str,start,vTypeA,vTypeB):
- # i,a=vTypeA(str,start)
- # if a==None or str[i]!=":": return (start,None)
- # i,b=vTypeB(str,i+1)
- # if b==None: return start,None
- # return (i,(a,b))
-
- def compose(vTypeA,vTypeB):
- def f(str,start):
- i,a=vTypeA(str,start)
- # print(">",i,a)
- if a==None or str[i]!=":": return (start,None)
- i,b=vTypeB(str,i+1)
- # print(">",i,b)
- if b==None: return start,None
- return (i,(a,b))
- return f
-
- def number(str,start):
- r=re.compile(r"(\+|-|)\d+")
- m=r.match(str,start)
- if m is None: return (start,None)
- res=int(m.group(0))
- return (m.end(),res)
-
- def real(str,start):
- r=re.compile(r"(\+|-|)\d+(\.\d+)?")
- m=r.match(str,start)
- if m is None: return (start,None)
- res=float(m.group(0))
- return (m.end(),res)
-
- def double(str,start):
- r=re.compile(r"1|2")
- m=r.match(str,start)
- if m is None: return (start,None)
- res=int(m.group(0))
- return (m.end(),res)
-
- def color(str,start):
- r=re.compile(r"B|W")
- m=r.match(str,start)
- if m is None: return (start,None)
- return (m.end(),m.group(0))
-
- # def simpleText(str,start):
- # res=""
- # esc=False
- # lineBreak=False
- # for c in str:
- # if esc:
- # res+=c
- # esc=False
- # elif c=="\\":
- # esc=True
- # elif c=="]":
- # break
- # else:
- # res+=c
- # return res
-
- def text(simple=True,composed=False):
- def f(str,start):
- res=""
- esc=False
- lastC=""
- for i,c in enumerate(str[start:],start):
- if esc:
- if c!="\n" and c!="\r": res+=c
- esc=False
- elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
- elif c=="\r" or c=="\n" and not simple:
- res+="\n"
- elif c.isspace():
- res+=" "
- elif c=="\\":
- esc=True
- elif c=="]" or (c==":" and composed):
- break
- else:
- res+=c
- lastC=c
- return (i,res)
- return f
-
- def empty(str,start): return (start,"")
-
- def anything(str,start):
- esc=False
- for i,c in enumerate(str[start:],start):
- if esc: esc=False
- elif c=="\\": esc=True
- elif c=="]": break
- return (i,str[start:i])
-
- # go specific
- def point(str,start):
- r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
- m=r.match(str,start)
- if m is None: return (start,None)
- if m.group(0)=="": # pass, !! tt
- return (m.end(),tuple())
- col=m.group(0)[0]
- row=m.group(0)[1]
- col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
- row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
- return (m.end(),(col,row))
+ type=""
+ value=None
+ patterns=dict()
+
+ def create(str,start,name):
+ if name in PropValue.patterns:
+ return PropValue.patterns[name](str,start)
+ else:
+ print('warning, unknown property "{0}" at position {1}'.format(name,start))
+ return PropValue.singleton(PropValue.anything)(str,start)
+
+ # def singleton(str,start,vType):
+ # if str[start]!="[":
+ # return (start,None)
+ # i,x=vType(str,start+1)
+ # if x is None: return (start,None)
+ # if str[i]!="]":
+ # return (start,None)
+ # return (i+1,x)
+
+ def choose(*vTypes):
+ def f(str,start):
+ for vType in vTypes:
+ i,x=vType(str,start)
+ if x is not None: return (i,x)
+ return (start,None)
+ return f
+
+ def singleton(vType):
+ def f(str,start):
+ if str[start]!="[":
+ return (start,None)
+ i,x=vType(str,start+1)
+ if x is None: return (start,None)
+ if str[i]!="]":
+ return (start,None)
+ return (i+1,x)
+ return f
+
+ # def listOf(str,start,vType,allowEmpty=False):
+ # res=[]
+ # i,x=singleton(str,start,vType)
+ # # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
+ # while x!=None:
+ # res.append(x)
+ # i,x=singleton(str,i,vType)
+ # if len(res)==0 and not allowEmpty: return (start,None)
+ # return (i,res)
+
+ def listOf(vType,allowEmpty=False):
+ def f(str,start):
+ res=[]
+ single=singleton(vType)
+ i,x=single(str,start)
+ while x!=None:
+ res.append(x)
+ i,x=single(str,i)
+ if len(res)==0 and not allowEmpty: return (start,None)
+ return (i,res)
+ return f
+
+ # def compose(str,start,vTypeA,vTypeB):
+ # i,a=vTypeA(str,start)
+ # if a==None or str[i]!=":": return (start,None)
+ # i,b=vTypeB(str,i+1)
+ # if b==None: return start,None
+ # return (i,(a,b))
+
+ def compose(vTypeA,vTypeB):
+ def f(str,start):
+ i,a=vTypeA(str,start)
+ # print(">",i,a)
+ if a==None or str[i]!=":": return (start,None)
+ i,b=vTypeB(str,i+1)
+ # print(">",i,b)
+ if b==None: return start,None
+ return (i,(a,b))
+ return f
+
+ def number(str,start):
+ r=re.compile(r"(\+|-|)\d+")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ res=int(m.group(0))
+ return (m.end(),res)
+
+ def real(str,start):
+ r=re.compile(r"(\+|-|)\d+(\.\d+)?")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ res=float(m.group(0))
+ return (m.end(),res)
+
+ def double(str,start):
+ r=re.compile(r"1|2")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ res=int(m.group(0))
+ return (m.end(),res)
+
+ def color(str,start):
+ r=re.compile(r"B|W")
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ return (m.end(),m.group(0))
+
+ # def simpleText(str,start):
+ # res=""
+ # esc=False
+ # lineBreak=False
+ # for c in str:
+ # if esc:
+ # res+=c
+ # esc=False
+ # elif c=="\\":
+ # esc=True
+ # elif c=="]":
+ # break
+ # else:
+ # res+=c
+ # return res
+
+ def text(simple=True,composed=False):
+ def f(str,start):
+ res=""
+ esc=False
+ lastC=""
+ for i,c in enumerate(str[start:],start):
+ if esc:
+ if c!="\n" and c!="\r": res+=c
+ esc=False
+ elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
+ elif c=="\r" or c=="\n" and not simple:
+ res+="\n"
+ elif c.isspace():
+ res+=" "
+ elif c=="\\":
+ esc=True
+ elif c=="]" or (c==":" and composed):
+ break
+ else:
+ res+=c
+ lastC=c
+ return (i,res)
+ return f
+
+ def empty(str,start): return (start,"")
+
+ def anything(str,start):
+ esc=False
+ for i,c in enumerate(str[start:],start):
+ if esc: esc=False
+ elif c=="\\": esc=True
+ elif c=="]": break
+ return (i,str[start:i])
+
+ # go specific
+ def point(str,start):
+ r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
+ m=r.match(str,start)
+ if m is None: return (start,None)
+ if m.group(0)=="": # pass, !! tt
+ return (m.end(),tuple())
+ col=m.group(0)[0]
+ row=m.group(0)[1]
+ col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
+ row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
+ return (m.end(),(col,row))
- move=point
- stone=point
-
- patterns={
- "B":singleton(move),
- "KO":singleton(empty),
- "MN":singleton(number),
- "W":singleton(move),
- "AB":listOf(stone), #
- "AE":listOf(point), #
- "AW":listOf(stone), #
- "PL":singleton(color),
- "C":singleton(text(simple=False)),
- "DM":singleton(double),
- "GB":singleton(double),
- "GW":singleton(double),
- "HO":singleton(double),
- "N":singleton(text()),
- "UC":singleton(double),
- "V":singleton(real),
- "BM":singleton(double),
- "DO":singleton(empty),
- "IT":singleton(empty),
- "TE":singleton(double),
- "AR":listOf(compose(point,point)), #
- "CR":listOf(point), #
- "DD":listOf(point,allowEmpty=True), #
- "LB":listOf(compose(point,text())), #
- "LN":listOf(compose(point,point)), #
- "MA":listOf(point), #
- "SL":listOf(point), #
- "SQ":listOf(point), #
- "TR":listOf(point), #
- "AP":singleton(compose(text(composed=True),text())), #
- "CA":singleton(text()),
- "FF":singleton(number),
- "GM":singleton(number),
- "ST":singleton(number),
- "SZ":choose(singleton(number),singleton(compose(number,number))), #
- "AN":singleton(text()),
- "BR":singleton(text()),
- "BT":singleton(text()),
- "CP":singleton(text()),
- "DT":singleton(text()),
- "EV":singleton(text()),
- "GN":singleton(text()),
- "GC":singleton(text(simple=False)),
- "ON":singleton(text()),
- "OT":singleton(text()),
- "PB":singleton(text()),
- "PC":singleton(text()),
- "PW":singleton(text()),
- "RE":singleton(text()),
- "RO":singleton(text()),
- "RU":singleton(text()),
- "SO":singleton(text()),
- "TM":singleton(real),
- "US":singleton(text()),
- "WR":singleton(text()),
- "WT":singleton(text()),
- "BL":singleton(real),
- "OB":singleton(number),
- "OW":singleton(number),
- "WL":singleton(real),
- "FG":choose(singleton(empty),singleton(compose(number,text()))), #
- "PM":singleton(number),
- "VW":listOf(point,allowEmpty=True), #
-
- # go specific
- "HA":singleton(number),
- "KM":singleton(real),
- "TB":listOf(point,allowEmpty=True),
- "TW":listOf(point,allowEmpty=True)
- }
+ move=point
+ stone=point
+
+ patterns={
+ "B":singleton(move),
+ "KO":singleton(empty),
+ "MN":singleton(number),
+ "W":singleton(move),
+ "AB":listOf(stone), #
+ "AE":listOf(point), #
+ "AW":listOf(stone), #
+ "PL":singleton(color),
+ "C":singleton(text(simple=False)),
+ "DM":singleton(double),
+ "GB":singleton(double),
+ "GW":singleton(double),
+ "HO":singleton(double),
+ "N":singleton(text()),
+ "UC":singleton(double),
+ "V":singleton(real),
+ "BM":singleton(double),
+ "DO":singleton(empty),
+ "IT":singleton(empty),
+ "TE":singleton(double),
+ "AR":listOf(compose(point,point)), #
+ "CR":listOf(point), #
+ "DD":listOf(point,allowEmpty=True), #
+ "LB":listOf(compose(point,text())), #
+ "LN":listOf(compose(point,point)), #
+ "MA":listOf(point), #
+ "SL":listOf(point), #
+ "SQ":listOf(point), #
+ "TR":listOf(point), #
+ "AP":singleton(compose(text(composed=True),text())), #
+ "CA":singleton(text()),
+ "FF":singleton(number),
+ "GM":singleton(number),
+ "ST":singleton(number),
+ "SZ":choose(singleton(number),singleton(compose(number,number))), #
+ "AN":singleton(text()),
+ "BR":singleton(text()),
+ "BT":singleton(text()),
+ "CP":singleton(text()),
+ "DT":singleton(text()),
+ "EV":singleton(text()),
+ "GN":singleton(text()),
+ "GC":singleton(text(simple=False)),
+ "ON":singleton(text()),
+ "OT":singleton(text()),
+ "PB":singleton(text()),
+ "PC":singleton(text()),
+ "PW":singleton(text()),
+ "RE":singleton(text()),
+ "RO":singleton(text()),
+ "RU":singleton(text()),
+ "SO":singleton(text()),
+ "TM":singleton(real),
+ "US":singleton(text()),
+ "WR":singleton(text()),
+ "WT":singleton(text()),
+ "BL":singleton(real),
+ "OB":singleton(number),
+ "OW":singleton(number),
+ "WL":singleton(real),
+ "FG":choose(singleton(empty),singleton(compose(number,text()))), #
+ "PM":singleton(number),
+ "VW":listOf(point,allowEmpty=True), #
+
+ # go specific
+ "HA":singleton(number),
+ "KM":singleton(real),
+ "TB":listOf(point,allowEmpty=True),
+ "TW":listOf(point,allowEmpty=True)
+ }
"""def property(str):
- # i=propIdent(str)
- # if i<0: return -1
- # j=i
- # i=propValue(str[i:])
- # while i>=0:
- # j+=i
- # i=propValue(str[i:])
- # return j
+ # i=propIdent(str)
+ # if i<0: return -1
+ # j=i
+ # i=propValue(str[i:])
+ # while i>=0:
+ # j+=i
+ # i=propValue(str[i:])
+ # return j
def propIdent(str):
- m=re.match(r"[A-Z]+",str)
- if m is None: return -1
- return m.end()
+ m=re.match(r"[A-Z]+",str)
+ if m is None: return -1
+ return m.end()
def propValue(str):
- i=cValueType(str[1:])
- if str[0]=="[" and i>=0 and str[i]=="]": return i+1
- else: return -1
+ i=cValueType(str[1:])
+ if str[0]=="[" and i>=0 and str[i]=="]": return i+1
+ else: return -1
class propValue:
- pass
+ pass
def cValueType(str,start):
- matches=[real,number,double,color,simpleText]
- for f in matches:
- i,x=f(str,start)
- if x is not None: return i,x
- return 1/0
+ matches=[real,number,double,color,simpleText]
+ for f in matches:
+ i,x=f(str,start)
+ if x is not None: return i,x
+ return 1/0
def number(str,start):
- r=re.compile(r"(\+|-|)\d+")
- m=r.match(str,start)
- if m is None: return (-1,None)
- x=int(m.group(0))
- return (m.end(),x)
+ r=re.compile(r"(\+|-|)\d+")
+ m=r.match(str,start)
+ if m is None: return (-1,None)
+ x=int(m.group(0))
+ return (m.end(),x)
def real(str):
- m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
- if m is None: return -1
- return m.end()
+ m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
+ if m is None: return -1
+ return m.end()
def double(str):
- m=re.match(r"1|2",str)
- if m is None: return -1
- return m.end()
-
+ m=re.match(r"1|2",str)
+ if m is None: return -1
+ return m.end()
+
def color(str):
- m=re.match(r"B|W",str)
- if m is None: return -1
- return m.end()
-
+ m=re.match(r"B|W",str)
+ if m is None: return -1
+ return m.end()
+
def simpleText(str):
- res=r""
- esc=False
- for c in str:
- if esc:
- res+=c
- esc=False
- elif c=="\\":
- esc=True
- elif c=="]":
- break
- else:
- res+=c
- return res"""
+ res=r""
+ esc=False
+ for c in str:
+ if esc:
+ res+=c
+ esc=False
+ elif c=="\\":
+ esc=True
+ elif c=="]":
+ break
+ else:
+ res+=c
+ return res"""
sgf=open("in/1-Hora-Simara.sgf").read()