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