Files @ 2ed7f0dab5ef
Branch filter:

Location: Diana/src/sgfParser/collection.py - annotation

Laman
expanding compressed game trees
from sgfParser.node import Node
from . import skipWhitespace


class Collection:
	def __init__(self,s):
		self.gameTrees=[]
		i,x=GameTree.create(s,0)
		if x is None:
			print("error when parsing Collection")
			return
		while x is not None:
			self.gameTrees.append(x)
			i,x=GameTree.create(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 create(s,start):
		res=GameTree()
		i=skipWhitespace(s,start)
		if i>=len(s) or s[i]!="(":
			# print("error when parsing GameTree")
			return (start,None)
		i,x=Node.create(s,i+1)
		if x is None:
			# print("error when parsing GameTree")
			return (i,None)
		y=None
		while x is not None:
			res.nodes.append(x)
			if y: y.addChild(x)
			x.setParent(y)
			y=x
			i=skipWhitespace(s,i)
			i,x= Node.create(s, i)
		i=skipWhitespace(s,i)
		i,x=GameTree.create(s,i)
		while x is not None:
			res.branches.append(x)
			subroot=x.getNode(0)
			if subroot:
				subroot.setParent(y)
			if y: y.addChild(subroot)
			i=skipWhitespace(s,i)
			i,x=GameTree.create(s,i)
		if s[i]!=")":
			# print("error when parsing GameTree")
			return (i,None)
		return (i+1,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 taken directly.
	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