Changeset - 2a5d1585e748
[Not reviewed]
default
0 3 0
Laman - 8 years ago 2017-02-05 20:50:59

getting rid of last CRLF files
3 files changed with 249 insertions and 249 deletions:
0 comments (0 inline, 0 general)
src/diana.py
Show inline comments
 
import os
 
import re
 
import sys
 
 
import go
 
from go import BLACK,WHITE,EMPTY
 
from sgfParser.collection import Collection
 
 
from drawer.svg import Svg
 
from drawer.tikz import Tikz
 
 
 
templateDir=os.path.join(os.path.dirname(__file__),"templ")
 
with open(os.path.join(templateDir,"templ.svg")) as f:
 
	template=f.read()
 
 
 
if len(sys.argv)>1:
 
	files=sys.argv[1:]
 
else:
 
	sys.exit("no input file specified")
 
 
movesPerDiagram=75
 
minMovesPerDiagram=10
 
 
t=sys.stdout
 
 
 
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]
 
 
 
def processFile(fileName):
 
	shortName="".join(re.split(r'[/\\]',fileName)[-1].split('.')[:-1])
 
	
 
	game=go.Go()
 
	global t
 
 
	games=Collection(open(fileName, 'r', encoding="utf-8").read()).listGames()
 
	record=list(games)[0]
 
 
	moves=list(collectMoves(record))
 
 
	localBoard=dict()
 
	overlays=""
 
	letters=dict()
 
	letter='a'
 
 
	diagramsNeeded=(len(moves)-minMovesPerDiagram)//movesPerDiagram+1
 
	moveNumber=0
 
	
 
	for i in range(diagramsNeeded):
 
		# initialize the diagram
 
		diagram=Svg()
 
		
 
		for lineNumber,line in enumerate(game.board):
 
			for itemNumber,item in enumerate(line):
 
				if item==BLACK: diagram.addStone(itemNumber,lineNumber,"b")
 
				if item==WHITE: diagram.addStone(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]!=EMPTY}
 
		
 
		for j in range(movesPerDiagram):
 
			# draw the moves
 
			if moveNumber>=len(moves): break
 
 
			c,(x,y)=moves[moveNumber]
 
			c=c.lower()
 
			
 
			if not game.move(BLACK if c=='b' else WHITE, x,y):
 
				print("illegal move: {0} at {1},{2}".format(moveNumber+1,x,y))
 
				moveNumber+=1
 
				continue
 
 
			# draw the move on an empty intersection
 
			if not (x,y) in localBoard:
 
				localBoard[(x,y)]=moveNumber+1
 
				diagram.addMove(x,y,c,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'
 
					diagram.addMove(x,y,color,letter)
 
					letter=chr(ord(letter)+1)
 
				overlays+="{0} = {1}\n".format(moveNumber+1,letters[(x,y)])
 
			# intersection occupied by a numbered stone
 
			else: overlays+="{0} = {1}\n".format(moveNumber+1,localBoard[(x,y)])
 
			
 
			moveNumber+=1
 
			
 
		# finish and save the diagram
 
		t=open(os.path.join("out","{0}-{1}.{2}".format(shortName,i+1,diagram.extension)),'w') # a new file
 
		t.write(diagram.render(template))
 
		t.close()
 
			
 
	notes=open(os.path.join("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))
 
import os
 
import re
 
import sys
 

	
 
import go
 
from go import BLACK,WHITE,EMPTY
 
from sgfParser.collection import Collection
 

	
 
from drawer.svg import Svg
 
from drawer.tikz import Tikz
 

	
 

	
 
templateDir=os.path.join(os.path.dirname(__file__),"templ")
 
with open(os.path.join(templateDir,"templ.svg")) as f:
 
	template=f.read()
 

	
 

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

	
 
movesPerDiagram=75
 
minMovesPerDiagram=10
 

	
 
t=sys.stdout
 

	
 

	
 
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]
 

	
 

	
 
def processFile(fileName):
 
	shortName="".join(re.split(r'[/\\]',fileName)[-1].split('.')[:-1])
 
	
 
	game=go.Go()
 
	global t
 

	
 
	games=Collection(open(fileName, 'r', encoding="utf-8").read()).listGames()
 
	record=list(games)[0]
 

	
 
	moves=list(collectMoves(record))
 

	
 
	localBoard=dict()
 
	overlays=""
 
	letters=dict()
 
	letter='a'
 

	
 
	diagramsNeeded=(len(moves)-minMovesPerDiagram)//movesPerDiagram+1
 
	moveNumber=0
 
	
 
	for i in range(diagramsNeeded):
 
		# initialize the diagram
 
		diagram=Svg()
 
		
 
		for lineNumber,line in enumerate(game.board):
 
			for itemNumber,item in enumerate(line):
 
				if item==BLACK: diagram.addStone(itemNumber,lineNumber,"b")
 
				if item==WHITE: diagram.addStone(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]!=EMPTY}
 
		
 
		for j in range(movesPerDiagram):
 
			# draw the moves
 
			if moveNumber>=len(moves): break
 

	
 
			c,(x,y)=moves[moveNumber]
 
			c=c.lower()
 
			
 
			if not game.move(BLACK if c=='b' else WHITE, x,y):
 
				print("illegal move: {0} at {1},{2}".format(moveNumber+1,x,y))
 
				moveNumber+=1
 
				continue
 

	
 
			# draw the move on an empty intersection
 
			if not (x,y) in localBoard:
 
				localBoard[(x,y)]=moveNumber+1
 
				diagram.addMove(x,y,c,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'
 
					diagram.addMove(x,y,color,letter)
 
					letter=chr(ord(letter)+1)
 
				overlays+="{0} = {1}\n".format(moveNumber+1,letters[(x,y)])
 
			# intersection occupied by a numbered stone
 
			else: overlays+="{0} = {1}\n".format(moveNumber+1,localBoard[(x,y)])
 
			
 
			moveNumber+=1
 
			
 
		# finish and save the diagram
 
		t=open(os.path.join("out","{0}-{1}.{2}".format(shortName,i+1,diagram.extension)),'w') # a new file
 
		t.write(diagram.render(template))
 
		t.close()
 
			
 
	notes=open(os.path.join("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))
src/go.py
Show inline comments
 
BLACK=1
 
WHITE=-1
 
EMPTY=0
 
 
 
class Go:
 
	board=[[EMPTY]*19 for i in range(19)]
 
	
 
	def __init__(self): self.board=[[EMPTY]*19 for i in range(19)]
 
	
 
	def move(self,color,y,x):
 
		if self.board[x][y]!=EMPTY: return False
 
 
		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]=EMPTY
 
			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]==EMPTY: 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]=EMPTY
 
BLACK=1
 
WHITE=-1
 
EMPTY=0
 

	
 

	
 
class Go:
 
	board=[[EMPTY]*19 for i in range(19)]
 
	
 
	def __init__(self): self.board=[[EMPTY]*19 for i in range(19)]
 
	
 
	def move(self,color,y,x):
 
		if self.board[x][y]!=EMPTY: return False
 

	
 
		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]=EMPTY
 
			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]==EMPTY: 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]=EMPTY
src/sgfParser/collection.py
Show inline comments
 
from sgfParser.node import Node
 
from . import skipWhitespace, ParserError
 
 
 
class Collection:
 
	def __init__(self,s):
 
		self.gameTrees=[]
 
		i=skipWhitespace(s,0)
 
		if i>=len(s): return
 
		elif not GameTree.fits(s,i):
 
			raise ParserError("expected a GameTree starting with '('",s,i)
 
		while GameTree.fits(s,i):
 
			i,x=GameTree.create(s,i)
 
			self.gameTrees.append(x)
 
		if i<len(s):
 
			raise ParserError("expected EOF",s,i)
 
 
	def listGames(self):
 
		for tree in self.gameTrees:
 
			for game in tree.listGames(): yield game
 
 
 
class GameTree:
 
	def __init__(self):
 
		self.nodes=[]
 
		self.branches=[]
 
 
	@staticmethod
 
	def fits(s,i):
 
		return i<len(s) and s[i]=="("
 
 
	@staticmethod
 
	def create(s,start):
 
		assert GameTree.fits(s,start)
 
		res=GameTree()
 
 
		i=skipWhitespace(s,start+1)
 
		if not Node.fits(s,i):
 
			raise ParserError("expected a Node starting with ';'",s,i)
 
 
		y=None
 
		while Node.fits(s,i):
 
			i,x=Node.create(s,i)
 
			res.nodes.append(x)
 
			if y: y.addChild(x)
 
			x.setParent(y)
 
			y=x
 
			i=skipWhitespace(s,i)
 
 
		while GameTree.fits(s,i):
 
			i,x=GameTree.create(s,i)
 
			res.branches.append(x)
 
			subroot=x.getNode(0)
 
			subroot.setParent(y)
 
			if y: y.addChild(subroot)
 
			i=skipWhitespace(s,i)
 
		if i>=len(s) or s[i]!=")":
 
			raise ParserError("expected end of a GameTree marked by ')'",s,i)
 
		i=skipWhitespace(s,i+1)
 
		return (i,res)
 
 
	## Expand multiple games into distinct GameTrees and yield each.
 
	def listGames(self):
 
		for node in self._listGINodes():
 
			yield self._buildSubtree(node)
 
 
	def getNode(self,i):
 
		if 0<=i<len(self.nodes):
 
			return self.nodes[i]
 
		return None
 
 
	## Create and return a new game tree containing the provided Node.
 
	#
 
	# Ancestor nodes are copied, descendants are shared.
 
	def _buildSubtree(self,seedNode):
 
		node=seedNode.copy()
 
 
		while node.parent:
 
			newNode=node.parent.copy()
 
			node.parent=newNode
 
			newNode.setChildren([node])
 
			node=newNode
 
 
		return node
 
 
	## Find and yield Game Info nodes.
 
	def _listGINodes(self):
 
		for node in self.nodes:
 
			if node.isGINode():
 
				yield node
 
		for tree in self.branches:
 
			for node in tree._listGINodes():
 
				yield node
 
from .node import Node
 
from . import skipWhitespace, ParserError
 

	
 

	
 
class Collection:
 
	def __init__(self,s):
 
		self.gameTrees=[]
 
		i=skipWhitespace(s,0)
 
		if i>=len(s): return
 
		elif not GameTree.fits(s,i):
 
			raise ParserError("expected a GameTree starting with '('",s,i)
 
		while GameTree.fits(s,i):
 
			i,x=GameTree.create(s,i)
 
			self.gameTrees.append(x)
 
		if i<len(s):
 
			raise ParserError("expected EOF",s,i)
 

	
 
	def listGames(self):
 
		for tree in self.gameTrees:
 
			for game in tree.listGames(): yield game
 

	
 

	
 
class GameTree:
 
	def __init__(self):
 
		self.nodes=[]
 
		self.branches=[]
 

	
 
	@staticmethod
 
	def fits(s,i):
 
		return i<len(s) and s[i]=="("
 

	
 
	@staticmethod
 
	def create(s,start):
 
		assert GameTree.fits(s,start)
 
		res=GameTree()
 

	
 
		i=skipWhitespace(s,start+1)
 
		if not Node.fits(s,i):
 
			raise ParserError("expected a Node starting with ';'",s,i)
 

	
 
		y=None
 
		while Node.fits(s,i):
 
			i,x=Node.create(s,i)
 
			res.nodes.append(x)
 
			if y: y.addChild(x)
 
			x.setParent(y)
 
			y=x
 
			i=skipWhitespace(s,i)
 

	
 
		while GameTree.fits(s,i):
 
			i,x=GameTree.create(s,i)
 
			res.branches.append(x)
 
			subroot=x.getNode(0)
 
			subroot.setParent(y)
 
			if y: y.addChild(subroot)
 
			i=skipWhitespace(s,i)
 
		if i>=len(s) or s[i]!=")":
 
			raise ParserError("expected end of a GameTree marked by ')'",s,i)
 
		i=skipWhitespace(s,i+1)
 
		return (i,res)
 

	
 
	## Expand multiple games into distinct GameTrees and yield each.
 
	def listGames(self):
 
		for node in self._listGINodes():
 
			yield self._buildSubtree(node)
 

	
 
	def getNode(self,i):
 
		if 0<=i<len(self.nodes):
 
			return self.nodes[i]
 
		return None
 

	
 
	## Create and return a new game tree containing the provided Node.
 
	#
 
	# Ancestor nodes are copied, descendants are shared.
 
	def _buildSubtree(self,seedNode):
 
		node=seedNode.copy()
 

	
 
		while node.parent:
 
			newNode=node.parent.copy()
 
			node.parent=newNode
 
			newNode.setChildren([node])
 
			node=newNode
 

	
 
		return node
 

	
 
	## Find and yield Game Info nodes.
 
	def _listGINodes(self):
 
		for node in self.nodes:
 
			if node.isGINode():
 
				yield node
 
		for tree in self.branches:
 
			for node in tree._listGINodes():
 
				yield node
0 comments (0 inline, 0 general)