Files @ c95fa8ab1067
Branch filter:

Location: Diana/src/diana/sgfParser/collection.py

Laman
changed imports
from .node import Node
from . import skipWhitespace, ParserError
from .gameRecord import GameRecord


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.parent=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.parent=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):
		if len(self.nodes)==0: return None
		for node in self.nodes[0].listGINodes():
			yield GameRecord(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 moved from the seedNode.
	def _buildSubtree(self,seedNode):
		node=seedNode.copy()
		node.setChildren(seedNode.children)
		seedNode.children=[]

		while node.parent:
			newNode=node.parent.copy()
			newNode.addChild(node)
			node=newNode

		return node