Files @ d57d0d4ede15
Branch filter:

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

Laman
changed the naming convention to follow standards
from .node import Node
from . import skip_whitespace, ParserError
from .gameRecord import GameRecord


class Collection:
	def __init__(self, s):
		self.game_trees = []
		i = skip_whitespace(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.game_trees.append(x)
		if i < len(s):
			raise ParserError("expected EOF", s, i)

	def list_games(self):
		for tree in self.game_trees:
			for game in tree.list_games():
				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 = skip_whitespace(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.add_child(x)
			x.parent = y
			y = x
			i = skip_whitespace(s, i)

		while GameTree.fits(s, i):
			(i, x) = GameTree.create(s, i)
			res.branches.append(x)
			subroot = x.get_node(0)
			subroot.parent = y
			if y:
				y.add_child(subroot)
			i = skip_whitespace(s, i)

		if i >= len(s) or s[i] != ")":
			raise ParserError("expected end of a GameTree marked by ')'", s, i)
		i = skip_whitespace(s, i + 1)
		return (i, res)

	## Expand multiple games into distinct GameTrees and yield each.
	def list_games(self):
		if len(self.nodes) == 0:
			return None
		for node in self.nodes[0].list_gi_nodes():
			yield GameRecord(self._build_subtree(node))

	def get_node(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 seed_node.
	def _build_subtree(self, seed_node):
		node = seed_node.copy()
		node.set_children(seed_node.children)
		seed_node.children = []

		while node.parent:
			new_node = node.parent.copy()
			new_node.add_child(node)
			node = new_node

		return node