Changeset - 966ee650fabf
[Not reviewed]
default
0 7 0
Laman - 3 years ago 2022-03-05 23:24:13

updated comments
7 files changed with 81 insertions and 15 deletions:
0 comments (0 inline, 0 general)
src/diana/diana.py
Show inline comments
 
@@ -11,6 +11,11 @@ from .drawer.tikz import Tikz
 

	
 

	
 
def collect_moves(root):
 
	"""Walk the primary variation and collect the move coordinates.
 

	
 
	:param Node root: a node serving as a root for the tree traversal
 
	:return: sequence of move colors and coordinates (col, row)
 
	:rtype: Iterator[("b" or "w", (int, int))]"""
 
	node = root
 
	while len(node.children) > 0:
 
		b = node.get_prop("B")
 
@@ -55,6 +60,13 @@ W: {PW} {WR}
 
		print("done")
 

	
 
	def create_diagram(self, start, end):
 
		"""Create and return a diagram drawer instance.
 

	
 
		:param int start: the initial move
 
		:param int end: the first omitted move, similar to sequence slices
 
		:return: a diagram instance
 
		:rtype: Drawer"""
 

	
 
		# initialize the diagram
 
		template = Svg()
 

	
 
@@ -73,7 +85,7 @@ W: {PW} {WR}
 

	
 
			color, move = self._moves[k]
 
			if move == tuple():
 
				template.overlays.append((k, "pass"))  # !!
 
				template.overlays.append((k, "pass"))
 
				continue
 
			else:
 
				(c, r) = move
 
@@ -93,6 +105,9 @@ W: {PW} {WR}
 
		return {k: self._record.get(k, default) for k in field_names}
 

	
 
	def _set_move(self, k):
 
		"""Rewind the internal game state to move k.
 

	
 
		:param int k: the move number"""
 
		self._game = go.Go()
 

	
 
		black_stones = self._record.root.get_prop("AB")
 
@@ -107,13 +122,20 @@ W: {PW} {WR}
 
		for i in range(k):
 
			(color, move) = self._moves[i]
 
			if move == tuple():
 
				continue # pass
 
				continue  # pass
 
			self._move(color, *move)
 

	
 
	def _move(self, color, c, r):
 
		"""Make a single move.
 

	
 
		:param str color: "b" or "w"
 
		:param int c: column
 
		:param int r: row
 
		:return: True if we can continue with another move, False on abort"""
 
		if not self._game.move(BLACK if color=='b' else WHITE, c, r):
 
			# !! we do not honor http://red-bean.com/sgf/ff5/m_vs_ax.htm at the moment
 
			msg = "illegal move: {0} at {1},{2}".format(self._game.move_count + 1, c, r)
 
			# we do not honor http://red-bean.com/sgf/ff5/m_vs_ax.htm at the moment
 
			# we accept and process only legal moves
 
			msg = "illegal move: {0} at {1},{2}".format(self._game.move_count+1, c, r)
 
			if cfg.keep_broken:
 
				print(msg)
 
			else:
src/diana/drawer/svg.py
Show inline comments
 
@@ -23,6 +23,12 @@ class Svg(Drawer):
 
		self.padding = 30
 

	
 
	def render(self, template_name, bgcolor=""):
 
		"""Render the template with the current drawer state.
 

	
 
		:param str template_name: a template file name in the templ directory
 
		:param bgcolor: a background color
 
		:type bgcolor: an SVG color, which is the same as a CSS color
 
		:return: the rendered template string"""
 
		points = [p for (i, p) in sorted(self._index.values(), key=lambda x: x[0])]
 

	
 
		stones = [p for p in points if p.color and p.label == ""]
 
@@ -36,6 +42,12 @@ class Svg(Drawer):
 
		return self._env.get_template(template_name).render(params)
 

	
 
	def save(self, filename, template="templ.svg", bgcolor=""):
 
		"""Render the template and save it with the filename.
 

	
 
		:param str filename: a path where to save the diagram. SVG and TXT suffixes will be appended
 
		:param str template: a template file name in the templ directory
 
		:param bgcolor: a background color
 
		:type bgcolor: an SVG color, which is the same as a CSS color"""
 
		file = open(filename+".svg", 'w')
 
		file.write(self.render(template, bgcolor))
 
		file.close()
src/diana/go.py
Show inline comments
 
@@ -12,6 +12,12 @@ class Go:
 
		self.temp = [[]]
 
	
 
	def move(self, color, y, x):
 
		"""Update the board with the specified move.
 

	
 
		:param int color: BLACK or WHITE
 
		:param int y: the row number
 
		:param int x: the column number
 
		:return: True on success, False on an invalid move"""
 
		if self.board[x][y] != EMPTY:
 
			return False
 

	
 
@@ -39,10 +45,10 @@ class Go:
 
			return False
 
		self.temp[x][y] = True
 

	
 
		return self._flood_fill(color, x - 1, y) or \
 
			self._flood_fill(color, x + 1, y) or \
 
			self._flood_fill(color, x, y - 1) or \
 
			self._flood_fill(color, x, y + 1)
 
		return self._flood_fill(color, x-1, y) or \
 
			self._flood_fill(color, x+1, y) or \
 
			self._flood_fill(color, x, y-1) or \
 
			self._flood_fill(color, x, y+1)
 
	
 
	def _remove(self):
 
		for i in range(19):
src/diana/sgfparser/__init__.py
Show inline comments
 
def skip_whitespace(s, start):
 
	"""Find the first non-whitespace character in a string.
 

	
 
	:param str s: an input string
 
	:param int start: an index where the search starts
 
	:return: index of the first non-whitespace character or len(s)"""
 
	i = start
 
	while i < len(s) and s[i].isspace():
 
		i += 1
 
@@ -7,6 +12,12 @@ def skip_whitespace(s, start):
 

	
 

	
 
def str_row_col(s, i):
 
	"""Translate a string index i to a row and col number.
 

	
 
	:param str s: an input string
 
	:param int i: an index pointing into s
 
	:return: a string position as (row, col)
 
	:rtype: (int, int)"""
 
	k = 0
 
	(r, c) = (0, 0)
 
	for (r, line) in enumerate(s.splitlines(True)):
src/diana/sgfparser/collection.py
Show inline comments
 
@@ -4,6 +4,8 @@ from .game_record import GameRecord
 

	
 

	
 
class Collection:
 
	"""Game collection type, a list of game trees."""
 

	
 
	def __init__(self, s):
 
		self.game_trees = []
 
		i = skip_whitespace(s, 0)
 
@@ -18,6 +20,7 @@ class Collection:
 
			raise ParserError("expected EOF", s, i)
 

	
 
	def list_games(self):
 
		""":rtype: Iterator[GameRecord]"""
 
		for tree in self.game_trees:
 
			for game in tree.list_games():
 
				yield game
 
@@ -30,10 +33,21 @@ class GameTree:
 

	
 
	@staticmethod
 
	def fits(s, i):
 
		"""Decide if a GameTree fits at the suggested string location.
 

	
 
		:param str s: an SGF string
 
		:param int i: a string location
 
		:return: True if there might be a GameTree at the location, False if not"""
 
		return i < len(s) and s[i] == "("
 

	
 
	@staticmethod
 
	def create(s, start):
 
		"""Create a GameTree from the string and move the current position pointer.
 

	
 
		:param str s: an SGF string
 
		:param int start: a location in s
 
		:return: the resulting tree and a pointer to its end
 
		:rtype: (int, GameTree)"""
 
		assert GameTree.fits(s, start)
 
		res = GameTree()
 

	
 
@@ -65,8 +79,8 @@ class GameTree:
 
		i = skip_whitespace(s, i + 1)
 
		return (i, res)
 

	
 
	## Expand multiple games into distinct GameTrees and yield each.
 
	def list_games(self):
 
		"""Expand multiple games into distinct GameTrees and yield each."""
 
		if len(self.nodes) == 0:
 
			return None
 
		for node in self.nodes[0].list_gi_nodes():
 
@@ -77,10 +91,10 @@ class GameTree:
 
			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):
 
		"""Create and return a new game tree containing the provided Node.
 

	
 
		Ancestor nodes are copied, descendants are moved from the seed_node."""
 
		node = seed_node.copy()
 
		node.set_children(seed_node.children)
 
		seed_node.children = []
src/diana/sgfparser/game_record.py
Show inline comments
 
from .node import Node
 

	
 

	
 
## Wrapper around a Node tree.
 
class GameRecord:
 
	"""Wrapper around a Node tree."""
 

	
 
	def __init__(self, root=None):
 
		self.root = root or Node()
 
		self._game_info_node = next(root.list_gi_nodes())
src/diana/sgfparser/node.py
Show inline comments
 
@@ -86,8 +86,8 @@ class Node:
 
			return res
 
		return None
 

	
 
	## Create a copy of the Node, with the same parent and deep copied properties, no copied children.
 
	def copy(self):
 
		"""Create a copy of the Node, with the same parent and deep copied properties, no copied children."""
 
		res = Node()
 
		res.properties = {k: v.copy() for (k, v) in self.properties.items()}
 
		res.parent = self.parent
 
@@ -99,8 +99,8 @@ class Node:
 
		else:
 
			return default
 

	
 
	## Returns textual representation of the Node itself, but disregards its children.
 
	def __str__(self):
 
		"""Returns textual representation of the Node itself, but disregards its children."""
 
		return ";" + "".join(str(p) for p in self.properties.values())
 

	
 
	def export(self):
0 comments (0 inline, 0 general)