import os import re 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 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() games=Collection(open(self.fileName, 'r', encoding=cfg.encoding).read()).listGames() self._record=list(games)[0] self._moves=list(collectMoves(self._record.root)) def process(self): print("{0}... ".format(self.fileName), end="") i=1 for k in range(0,len(self._moves),cfg.movesPerDiagram): filename=os.path.join(cfg.outputDir,"{0}-{1}".format(self._shortName,i)) self.createDiagram(k,k+cfg.movesPerDiagram).save(filename,"templ-pleb.svg") 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,start,end): # initialize the diagram template=Svg() self._setMove(start) # draw current state for lineNumber,line in enumerate(self._game.board): for itemNumber,item in enumerate(line): if item!=EMPTY: template.addStone(itemNumber,lineNumber,"b" if item==BLACK else "w") # draw the moves for k in range(start,end): if k>=len(self._moves): break color,move=self._moves[k] if move==tuple(): template.overlays.append((k,"pass")) # !! continue else: (c,r)=move if not self._move(color,c,r): if cfg.keepBroken: continue else: return False # draw the move template.addMove(c,r,color,k+1) return template 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","")) def _setMove(self,k): self._game=go.Go() blackStones=self._record.root.getProp("AB") whiteStones=self._record.root.getProp("AW") if blackStones: for p in blackStones: self._game.board[p.c][p.r]=BLACK if whiteStones: for p in whiteStones: self._game.board[p.c][p.r]=WHITE for i in range(k): (color,move)=self._moves[i] if move==tuple(): continue # pass self._move(color,*move) def _move(self,color,c,r): if not self._game.move(BLACK if color=='b' else WHITE, c,r): # !! 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._game.moveCount+1,c,r) if cfg.keepBroken: print(msg) else: msg+=". aborted" print(msg) return False return True if __name__=="__main__": print("processing:") files=cfg.inputFiles[:] for item in files: if os.path.isfile(item): try: f=SourceFile(item) f.process() except ParserError as e: print("Couldn't parse {0}, following error occured: {1}".format(item,e)) 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))