Files
@ 69f9170d3c89
Branch filter:
Location: Diana/src/diana.py
69f9170d3c89
4.4 KiB
text/x-python
cleaned redundant whitespace in SVG, cleaned old files
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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | import os
import re
from jinja2 import Environment,FileSystemLoader
import config as cfg
import go
from go import BLACK,WHITE,EMPTY
from sgfParser import ParserError
from sgfParser.collection import Collection
from drawer.svg import Svg
from drawer.tikz import Tikz
curDir=os.path.dirname(__file__)
templateDir=os.path.join(curDir,"templ")
env=Environment(loader=FileSystemLoader(templateDir))
env.trim_blocks=True
env.lstrip_blocks=True
def collectMoves(root):
node=root
while len(node.children)>0:
b=node.getProp("B")
w=node.getProp("W")
if b is not None: yield ("b",b)
elif w is not None: yield ("w",w)
# else: yield None # !! not really robust
node=node.children[0]
class SourceFile:
def __init__(self,fileName):
self.fileName=fileName
self._shortName= "".join(re.split(r'[/\\]', fileName)[-1].split('.')[:-1])
self._game=go.Go()
self._moveNumber=0
self._record=None
self._moves=[]
def process(self):
print("{0}... ".format(self.fileName), end="")
try:
games=Collection(open(self.fileName, 'r', encoding=cfg.encoding).read()).listGames()
except ParserError as e:
print("Couldn't parse {0}, following error occured: {1}".format(self.fileName,e))
return False
self._record=list(games)[0]
self._moves=list(collectMoves(self._record.root))
diagramsNeeded=(len(self._moves)-cfg.minMovesPerDiagram)//cfg.movesPerDiagram+1
for i in range(diagramsNeeded):
self.createDiagram(i+1)
notes=open(os.path.join(cfg.outputDir,"{0}.txt".format(self._shortName)), 'w')
notes.write(self.createGameInfo())
notes.close()
print("done")
def createDiagram(self,diagramNumber):
# initialize the diagram
template=Svg()
overlays=[]
letters=dict()
letter="a"
for lineNumber,line in enumerate(self._game.board):
for itemNumber,item in enumerate(line):
if item==BLACK: template.addStone(itemNumber,lineNumber,"b")
if item==WHITE: template.addStone(itemNumber,lineNumber,"w")
localBoard={(a,b):self._game.board[b][a]-1 for a in range(19) for b in range(19) if self._game.board[b][a]!=EMPTY}
for j in range(cfg.movesPerDiagram):
# draw the moves
if self._moveNumber>=len(self._moves): break
c,move=self._moves[self._moveNumber]
c=c.lower()
if move==tuple():
overlays.append("{0} pass".format(self._moveNumber))
self._moveNumber+=1
continue
else:
(x,y)=move
if not self._game.move(BLACK if c=='b' else WHITE, x,y):
# !! we do not honor http://red-bean.com/sgf/ff5/m_vs_ax.htm at the moment
msg="illegal move: {0} at {1},{2}".format(self._moveNumber+1,x,y)
if cfg.keepBroken:
print(msg)
self._moveNumber+=1
continue
else:
msg+=". aborted"
print(msg)
return False
# draw the move on an empty intersection
if not (x,y) in localBoard:
localBoard[(x,y)]=self._moveNumber+1
template.addMove(x,y,c,self._moveNumber+1)
# intersection occupied by an unlabeled stone
elif localBoard[(x,y)]<1:
# intersection not labeled even by a letter
if not (x,y) in letters:
letters[(x,y)]=letter
color='b' if localBoard[(x,y)]==EMPTY else 'w'
template.addMove(x,y,color,letter)
letter=chr(ord(letter)+1)
overlays.append("{0} = {1}".format(self._moveNumber+1,letters[(x,y)]))
# intersection occupied by a numbered stone
else: overlays.append("{0} = {1}".format(self._moveNumber+1,localBoard[(x,y)]))
self._moveNumber+=1
# finish and save the diagram
file=open(os.path.join(cfg.outputDir,"{0}-{1}.{2}".format(self._shortName,diagramNumber,template.extension)),'w') # a new file
file.write(template.render(env.get_template("templ.svg")))
file.close()
notes=open(os.path.join(cfg.outputDir,"{0}-{1}.txt".format(self._shortName,diagramNumber)), 'w')
notes.write("\n".join(overlays))
notes.close()
def createGameInfo(self):
rec=self._record
return """{title}
B: {black} {bRank}
W: {white} {wRank}
{date}
{result}""".format(title=rec.get("GN",""), black=rec.get("PB",""), bRank=rec.get("BR",""), white=rec.get("PW",""), wRank=rec.get("WR",""), date=rec.get("DT",""), result=rec.get("RE",""))
print("processing:")
files=cfg.inputFiles[:]
for item in files:
if os.path.isfile(item):
f=SourceFile(item)
f.process()
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))
|