From faea06ac8d0dc92edb9ca0f2b6aacf79f640ace7 Mon Sep 17 00:00:00 2001 From: InigoGutierrez Date: Wed, 15 Jun 2022 20:58:07 +0200 Subject: SGF module working and mapping SGF files to GameMove tree. --- imago/sgfParser/astNode.py | 50 +++++++++++++++++++++++++++++----------------- imago/sgfParser/sgf.py | 9 ++++++--- imago/sgfParser/sgfyacc.py | 5 ++++- testSGF.py | 19 ++++++++++++++++++ 4 files changed, 61 insertions(+), 22 deletions(-) create mode 100755 testSGF.py diff --git a/imago/sgfParser/astNode.py b/imago/sgfParser/astNode.py index e2b74a2..f87d9c1 100644 --- a/imago/sgfParser/astNode.py +++ b/imago/sgfParser/astNode.py @@ -1,6 +1,6 @@ from imago.gameLogic.gameData import GameData from imago.gameLogic.gameMove import GameMove -from imago.gameLogic.gameState import Player +from imago.gameLogic.gameBoard import GameBoard class ASTNode: """Abstract Syntax Tree Node of SGF parser""" @@ -12,7 +12,7 @@ class ASTNode: if props: self.props = props else: - self.props = {} + self.props = [] self.leaf = leaf def addToSequence(self, move): @@ -76,27 +76,41 @@ class ASTNode: firstMoves = [] for child in self.children: - firstMoves.append(child.toGameMoveTree) + firstMoves.append(child.toGameMoveTree(size)) return GameTree(firstMoves, gameData) - def toGameMoveTree(self): - player = 0 - coords = [] - for prop in self.props: - if prop.name == "B": # White move - player = Player.BLACK - coords = textToCoords(prop.value) - if prop.name == "W": # White move - player = Player.WHITE - coords = textToCoords(prop.value) - gameMove = GameMove(player, coords[0], coords[1]) + def toGameMoveTree(self, previousMove=None): + coords = None + if previousMove is None: + # Game root node + size = int(self.getPropertyValue("SZ")) + board = GameBoard(size, size) + gameMove = GameMove(board) + else: + for prop in self.props: + if prop.name == "B" or prop.name == "W": + coords = textToCoords(prop.value) + gameMove = previousMove.addMoveByCoords(coords) for child in self.children: - newMove = child.toGameMoveTree() - gameMove.nextMoves.append(newMove) + newMove = child.toGameMoveTree(gameMove) newMove.previousMove = gameMove return gameMove + def hasProperty(self, propertyName): + """Returns True if the node contains a property with the given name.""" + for prop in self.props: + if prop.name == propertyName: + return True + return False + + def getPropertyValue(self, propertyName): + """Returns the value of the given property for this node.""" + for prop in self.props: + if prop.name == propertyName: + return prop.value + raise RuntimeError("ASTNode has no property %s" % propertyName) + def toString(self, debug=False): """Returns a depth-first representation of the tree.""" out = '(' + str(self.props) + ')' @@ -107,8 +121,8 @@ class ASTNode: return out def textToCoords(text): # Poner en PropertyMove, subclase de Property - col = ord(text[1]) - ord('a') - row = ord(text[0]) - ord('a') + col = ord(text[0]) - ord('a') + row = ord(text[1]) - ord('a') return [row, col] diff --git a/imago/sgfParser/sgf.py b/imago/sgfParser/sgf.py index 56135de..4b11cfb 100644 --- a/imago/sgfParser/sgf.py +++ b/imago/sgfParser/sgf.py @@ -1,11 +1,14 @@ """Module for reading and writing of SGF files.""" -from imago.gameLogic.gameMove import GameMove from imago.sgfParser.sgfyacc import parser def loadGameTree(filename): # PLY? """Parses a GameTree instance from a source SGF file.""" - sgf = open(filename, "r") + file = open(filename, "r") - return parser.parse(sgf).toGameMoveTree() + text = file.read() + + file.close() + + return parser.parse(text).toGameMoveTree() diff --git a/imago/sgfParser/sgfyacc.py b/imago/sgfParser/sgfyacc.py index a07d179..d18f2a8 100755 --- a/imago/sgfParser/sgfyacc.py +++ b/imago/sgfParser/sgfyacc.py @@ -31,7 +31,10 @@ def p_node(p): def p_node_prop(p): 'node : node property' - p[1].props[p[2].name] = p[2].value + if p[1].hasProperty(p[2].name): + print("Syntax error: node already contains a property named - %s" % p[2].name) + raise SyntaxError + p[1].props.append(p[2]) p[0] = p[1] def p_property(p): diff --git a/testSGF.py b/testSGF.py new file mode 100755 index 0000000..6291033 --- /dev/null +++ b/testSGF.py @@ -0,0 +1,19 @@ +#!/usr/bin/python + +import sys +from imago.sgfParser.sgf import loadGameTree + +"""Gets a game from an SGF file.""" + +def main(): + filename = sys.argv[1] + move = loadGameTree(filename) + while move is not None: + move.printBoard() + if len(move.nextMoves) > 0: + move = move.nextMoves[0] + else: + move = None + +if __name__ == '__main__': + main() -- cgit v1.2.1