Files @ 31266616bb87
Branch filter:

Location: Diana/src/diana.py - annotation

Laman
split diagram notes into separate text files, refactored diana.py
2a5d1585e748
2a5d1585e748
2a5d1585e748
c705c709565b
c705c709565b
69ccf3e0aefe
2a5d1585e748
2a5d1585e748
69ccf3e0aefe
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
69ccf3e0aefe
69ccf3e0aefe
c705c709565b
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
2a5d1585e748
31266616bb87
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
31266616bb87
69ccf3e0aefe
2a5d1585e748
31266616bb87
2a5d1585e748
31266616bb87
2a5d1585e748
69ccf3e0aefe
31266616bb87
31266616bb87
69ccf3e0aefe
69ccf3e0aefe
69ccf3e0aefe
31266616bb87
31266616bb87
69ccf3e0aefe
31266616bb87
69ccf3e0aefe
69ccf3e0aefe
31266616bb87
69ccf3e0aefe
69ccf3e0aefe
69ccf3e0aefe
69ccf3e0aefe
69ccf3e0aefe
2a5d1585e748
2a5d1585e748
2a5d1585e748
31266616bb87
31266616bb87
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
31266616bb87
2a5d1585e748
31266616bb87
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
31266616bb87
2a5d1585e748
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
31266616bb87
69ccf3e0aefe
69ccf3e0aefe
2a5d1585e748
69ccf3e0aefe
69ccf3e0aefe
2a5d1585e748
2a5d1585e748
31266616bb87
31266616bb87
2a5d1585e748
2a5d1585e748
2a5d1585e748
2a5d1585e748
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))


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._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
		record=list(games)[0]

		self._moves=list(collectMoves(record))

		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(overlays)
		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()


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))