aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorInigoGutierrez <inigogf.95@gmail.com>2021-02-10 19:25:34 +0100
committerInigoGutierrez <inigogf.95@gmail.com>2021-02-10 19:25:34 +0100
commit3c8124e26898e58ea835194a255da0c04b2ecfac (patch)
tree929978e7e2d5db7df610e2d58ddc6dc47669429d
parent5cf270c29aec83bd81121e6b72f24e2c35340e38 (diff)
downloadimago-3c8124e26898e58ea835194a255da0c04b2ecfac.tar.gz
imago-3c8124e26898e58ea835194a255da0c04b2ecfac.zip
logic: Reorganized move evaluation.
GameBoard able to know if a move is valid, given the previous boards. GameMove no longer stores player, it gets it from board's last move.
-rw-r--r--imago/gameLogic/gameBoard.py19
-rw-r--r--imago/gameLogic/gameMove.py19
-rw-r--r--imago/gameLogic/gameState.py36
3 files changed, 43 insertions, 31 deletions
diff --git a/imago/gameLogic/gameBoard.py b/imago/gameLogic/gameBoard.py
index 327728b..c6a6007 100644
--- a/imago/gameLogic/gameBoard.py
+++ b/imago/gameLogic/gameBoard.py
@@ -31,6 +31,12 @@ class GameBoard:
be the same for all the rows."""
return len(self.board[0])
+ def getLastPlayer(self):
+ """Returns the player who placed the last stone."""
+ if self.lastStone is None:
+ return Player.EMPTY
+ return self.board[self.lastStone[0]][self.lastStone[1]]
+
def getDeepCopy(self):
"""Returns a copy GameBoard."""
newBoard = GameBoard(self.getBoardHeight(), self.getBoardWidth())
@@ -124,6 +130,7 @@ class GameBoard:
"""
self.board[row][col] = player
+ self.lastStone = [row, col]
captured = set()
@@ -219,6 +226,18 @@ class GameBoard:
self.board[row][col] = Player.EMPTY
return illegal
+ def isPlayable(self, row, col, player, prevBoards):
+ """Determines if a move is playable."""
+ if not self.isMoveInBoardBounds(row, col):
+ return False, "Move outside board bounds."
+ if not self.isCellEmpty(row, col):
+ return False, "Vertex is not empty."
+ if self.isMoveSuicidal(row, col, player):
+ return False, "Move is suicidal."
+ if self.isMoveKoIllegal(row, col, player, prevBoards):
+ return False, "Illegal by ko rule."
+ return True, ""
+
def equals(self, otherBoard):
"""Returns true if this board is equal to another board. Only takes into account
dimensions and placed stones.
diff --git a/imago/gameLogic/gameMove.py b/imago/gameLogic/gameMove.py
index b2db34f..90ec4bf 100644
--- a/imago/gameLogic/gameMove.py
+++ b/imago/gameLogic/gameMove.py
@@ -8,7 +8,6 @@ class GameMove:
removed stones."""
def __init__(self, player, board):
- self.player = player
self.board = board
self.nextMoves = []
self.previousMove = None
@@ -21,6 +20,10 @@ class GameMove:
"""Returns the column of the vertex the move was played on."""
return self.board.lastStone[1]
+ def getLastPlayer(self):
+ """Returns the player who placed the last stone."""
+ return self.board.getLastPlayer()
+
def getThisAndPrevBoards(self):
"""Returns an array with all the boards of this and previous moves."""
prevBoards = []
@@ -30,14 +33,24 @@ class GameMove:
checkedMove = checkedMove.previousMove
return prevBoards
+ def getPlayableVertices(self):
+ """Returns a set with the playable vertices."""
+ playables = set()
+ player = Player.otherPlayer(self.getLastPlayer())
+ prevBoards = self.getThisAndPrevBoards()
+ for row in range(self.board.getBoardHeight()):
+ for col in range(self.board.getBoardWidth()):
+ if self.board.isPlayable(row, col, player, prevBoards):
+ playables.add((row, col))
+
def addMove(self, row, col):
"""Adds a move to the next moves list creating its board from this move's board
plus a new stone at the specified row and column.
"""
- if self.player == Player.EMPTY:
+ if self.getLastPlayer() == Player.EMPTY:
player = Player.BLACK
else:
- player = Player.otherPlayer(self.player)
+ player = Player.otherPlayer(self.getLastPlayer())
return self.addMoveForPlayer(row, col, player)
def addMoveForPlayer(self, row, col, player):
diff --git a/imago/gameLogic/gameState.py b/imago/gameLogic/gameState.py
index cc65c75..e4dd629 100644
--- a/imago/gameLogic/gameState.py
+++ b/imago/gameLogic/gameState.py
@@ -19,9 +19,9 @@ class GameState:
"""Gets the player who should make the next move."""
if self.lastMove is None:
return Player.BLACK
- if self.lastMove.player is Player.EMPTY:
+ if self.lastMove.getLastPlayer() is Player.EMPTY:
return Player.BLACK
- return Player.otherPlayer(self.lastMove.player)
+ return Player.otherPlayer(self.lastMove.getLastPlayer())
def getPlayerCode(self):
"""Gets a string representation of the current player."""
@@ -40,38 +40,18 @@ class GameState:
def playMoveForPlayer(self, row, col, player):
"""Execute a move on the board for the given player."""
- # Check valid move
- if not self.prevalidateMove(row, col):
- print("Invalid move!")
- return False
-
- # Check suicide
- if self.getBoard().isMoveSuicidal(row, col, player):
- print("Invalid move! (Suicide)")
- return False
-
- # Check ko
prevBoards = self.lastMove.getThisAndPrevBoards()
- if self.getBoard().isMoveKoIllegal(row, col, player, prevBoards):
- print("Invalid move! (Ko)")
- return False
-
- # Move is legal
- self.__addMove(player, row, col)
- return True
+ playable, message = self.lastMove.board.isPlayable(row, col, player, prevBoards)
+ if playable:
+ self.__addMove(player, row, col)
+ return True
+ print("Invalid Move! %s" % message)
+ return False
def undo(self):
"""Sets the move before the last move as the new last move."""
self.lastMove = self.lastMove.previousMove
- def prevalidateMove(self, row, col):
- """Returns True if move is inside bounds and cell is empty, False if not."""
- if not self.getBoard().isMoveInBoardBounds(row, col):
- return False
- if not self.getBoard().isCellEmpty(row, col):
- return False
- return True
-
def __addMove(self, player, row, col):
# Check a last move already exists