Files @ 36762e70d969
Branch filter:

Location: Diana/src/diana/diana.py - annotation

Laman
work on proper parsing
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
a81abb4e0968
a81abb4e0968
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
e7fafcf5b27a
import os
import re
import sys

import sgf
import go

if len(sys.argv)>1:
	files=sys.argv[1:]
else:
	sys.exit("no input file specified")

movesPerDiagram=75
minMovesPerDiagram=10

t=sys.stdout
c=28
padding=15
highNumbers=True

class Svg:
	content=""
	footer=""
	extension="svg"

	padding=15
	gridSize=28
	highNumbers=True
	
	def __init__(self):
		self.content='''<?xml version="1.0" standalone="no"?>
<svg width="{0}" height="{0}" version="1.1" xmlns="http://www.w3.org/2000/svg" alignment-baseline="center">
	<defs>
		<style type="text/css"><![CDATA[
		text{{font-family:"DejaVu Sans";text-anchor:middle;}}
		line{{stroke:black;stroke-width:0.7}}
		circle{{stroke:black}}
		.b{{fill:black}}
		.w{{fill:white}}
		]]></style>
	</defs>
	<rect width="{0}" height="{0}" x="0" y="0" style="fill:white;stroke:white"/>\n'''.format(2*self.padding+18*self.gridSize)
		self.footer="</svg>\n"

		grid='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" />\n'

		# okraje desky
		for i in (0,18):
			self.content+='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" style="stroke-width:1"/>\n'.format(self.padding, 18*self.gridSize+self.padding, self.gridSize*i+self.padding, self.gridSize*i+self.padding)
			self.content+='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" style="stroke-width:1"/>\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+='  <circle cx="{0}" cy="{1}" r="{2}" class="b"/>\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+='  <circle cx="{0}" cy="{1}" r="{2}" class="{3}" />\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 writeLabel(self,x,y,label,color):
		label=str(label)
		fontSize=self.getFontSize(label)
		self.content+='  <text x="{0}" y="{1}" class="{2}" font-size="{3}">{4}</text>\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

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

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