From 08bd7d1bd0f9a564cff7ee7f616d62f234a54057 Mon Sep 17 00:00:00 2001 From: InigoGutierrez Date: Fri, 18 Jun 2021 20:37:16 +0200 Subject: imagocli.py works with the Sabaki GUI. --- imago/engine/core.py | 7 +++---- imago/engine/imagoIO.py | 24 +++++++++++++++++------- imago/engine/monteCarlo.py | 5 +++++ imago/gameLogic/gameBoard.py | 4 ++++ imago/gameLogic/gameState.py | 12 ++++++++---- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/imago/engine/core.py b/imago/engine/core.py index 3e52f8c..44da3b8 100644 --- a/imago/engine/core.py +++ b/imago/engine/core.py @@ -1,8 +1,5 @@ """Imago GTP engine""" -from random import randrange - -from imago.data.enums import Player from imago.engine.monteCarlo import MCTS from imago.gameLogic.gameState import GameState @@ -23,12 +20,14 @@ class GameEngine: It is wise to call clear_board after this command. """ self.gameState = GameState(newSize) + self.mcts = MCTS(self.gameState.lastMove) def clearBoard(self): """The board is cleared, the number of captured stones reset to zero and the move history reset to empty. """ self.gameState.clearBoard() + self.mcts.clearBoard() def setKomi(self, komi): """Sets a new value of komi.""" @@ -56,7 +55,7 @@ class GameEngine: coords = self.mcts.pickMove().coords #TODO: The move should NOT be played in its generation. This method is just for #suggesting a move. - self.gameState.playMoveForPlayer(coords[0], coords[1], color) + #self.gameState.playMoveForPlayer(coords[0], coords[1], color) return coords def undo(self): diff --git a/imago/engine/imagoIO.py b/imago/engine/imagoIO.py index f676b69..371c447 100644 --- a/imago/engine/imagoIO.py +++ b/imago/engine/imagoIO.py @@ -5,17 +5,21 @@ import sys from imago.engine import parseHelpers from imago.engine.core import GameEngine +def _response(text=""): + print("= %s" % text) + print() + def protocol_version(_): """Version of the GTP Protocol""" - print("2") + _response("2") def name(_): """Name of the engine""" - print("Imago") + _response("Imago") def version(_): """Version of the engine""" - print("0.0.0") + _response("0.0.0") def getCoordsText(row, col): """Returns a string representation of row and col. @@ -75,12 +79,14 @@ class ImagoIO: for c in self.commands_set: if c.__name__ == args[0]: out = "true" - print(out) + _response(out) def list_commands(self, _): """List of commands, one per row""" + output = "" for c in self.commands_set: - print("%s - %s" % (c.__name__, c.__doc__)) + output += ("%s - %s\n" % (c.__name__, c.__doc__)) + _response(output) def boardsize(self, args): """Changes the size of the board. @@ -92,12 +98,14 @@ class ImagoIO: sys.exit(1) size = int(args[0]) self.gameEngine.setBoardsize(size) + _response() def clear_board(self, _): """The board is cleared, the number of captured stones reset to zero and the move history reset to empty. """ self.gameEngine.clearBoard() + _response() def komi(self, args): """Sets a new value of komi.""" @@ -106,6 +114,7 @@ class ImagoIO: sys.exit(1) komi = float(args[0]) self.gameEngine.setKomi(komi) + _response() def fixed_handicap(self, args): """Handicap stones are placed on the board on standard vertices. @@ -119,7 +128,7 @@ class ImagoIO: out = getCoordsText(vertices[0][0], vertices[0][1]) for vertex in vertices[1:]: out += " " + getCoordsText(vertex[0], vertex[1]) - print(out) + _response(out) def place_free_handicap(self, args): """Handicap stones are placed on the board by the AI criteria.""" @@ -136,6 +145,7 @@ class ImagoIO: sys.exit(1) move = parseHelpers.parseMove(args, self.gameEngine.gameState.size) self.gameEngine.play(move.color, move.vertex) + _response() def genmove(self, args): """A stone of the requested color is played where the engine chooses.""" @@ -145,7 +155,7 @@ class ImagoIO: color = parseHelpers.parseColor(args[0]) output = parseHelpers.vertexToString(self.gameEngine.genmove(color), self.gameEngine.gameState.size) - print(output) + _response(output) self.gameEngine.gameState.getBoard().printBoard() def undo(self, _): diff --git a/imago/engine/monteCarlo.py b/imago/engine/monteCarlo.py index 2a531b6..4540cb8 100644 --- a/imago/engine/monteCarlo.py +++ b/imago/engine/monteCarlo.py @@ -45,6 +45,11 @@ class MCTS: return bestNode + def clearBoard(self): + """Empties move history.""" + while self.root.parent is not None: + self.root = self.root.parent + class MCTSNode: """Monte Carlo tree node.""" diff --git a/imago/gameLogic/gameBoard.py b/imago/gameLogic/gameBoard.py index 74098ed..b22dfd7 100644 --- a/imago/gameLogic/gameBoard.py +++ b/imago/gameLogic/gameBoard.py @@ -110,6 +110,10 @@ class GameBoard: containing the vertices where stones were captured. """ + if (row < 0 or row >= self.getBoardHeight() + or col < 0 or col >= self.getBoardWidth()): + print("[ERROR] Move and capture: out of bounds (%d, %d)" % (row, col)) + self.board[row][col] = player captured = set() diff --git a/imago/gameLogic/gameState.py b/imago/gameLogic/gameState.py index d596ba1..9aafd11 100644 --- a/imago/gameLogic/gameState.py +++ b/imago/gameLogic/gameState.py @@ -10,10 +10,7 @@ class GameState: def __init__(self, size): self.size = size - self.gameTree = GameTree() - newBoard = GameBoard(self.size, self.size) - self.lastMove = GameMove(newBoard) - self.gameTree.firstMoves.append(self.lastMove) + self.clearBoard() def getCurrentPlayer(self): """Gets the player who should make the next move.""" @@ -33,6 +30,13 @@ class GameState: return GameBoard(self.size, self.size) return self.lastMove.board + def clearBoard(self): + """Empties the board and moves tree.""" + self.gameTree = GameTree() + newBoard = GameBoard(self.size, self.size) + self.lastMove = GameMove(newBoard) + self.gameTree.firstMoves.append(self.lastMove) + def playMove(self, row, col): """Execute a move on the board for the current player and switches players.""" return self.playMoveForPlayer(row, col, self.getCurrentPlayer()) -- cgit v1.2.1