def __init__(self, depth: int, quiescenceFactor: int): self.evaluator = StandardBoardEvaluator() self.depth = depth self.quiescenceFactor = quiescenceFactor self.moveSorter = MoveSorter() self.boardsEvaluated = 0 self.quiesceCount = 0 self.cutOffsProduced = 0
def testSimpleEvaluation(self): board = createStandardBoard() t1 = board.currentPlayer.makeMove( MoveFactory.createMove(board, getCoordinateAtPosition("e2"), getCoordinateAtPosition("e4"))) self.assertTrue(t1.moveStatus.isDone()) t2 = t1.transitionBoard.currentPlayer.makeMove( MoveFactory.createMove(t1.transitionBoard, getCoordinateAtPosition("e7"), getCoordinateAtPosition("e5"))) self.assertTrue(t2.moveStatus.isDone()) standar = StandardBoardEvaluator() self.assertEqual(standar.evaluate(t2.transitionBoard, 0), 0)
def __init__(self, depth: int): self.boardEvaluator = StandardBoardEvaluator() self.depth: int = depth self._boardsEvaluated = 0 self.thread = 0
class ParallelMiniMax(MoveStrategy): def __init__(self, depth: int): self.boardEvaluator = StandardBoardEvaluator() self.depth: int = depth self._boardsEvaluated = 0 self.thread = 0 def __str__(self): return "MiniMax" @property def boardsEvaluated(self): return self._boardsEvaluated def execute(self, board: Board.Board) -> None: bestMove: Move.Move = Move.nullMove highestSeenValue = float('-inf') lowestSeenValue = float('inf') print(str(board.currentPlayer) + " Thinking with Depth = " + str(self.depth)) loop = asyncio.get_event_loop() tasks = [self.createAlg(board, move) for move in board.allLegalMoves] loop.run_until_complete(asyncio.wait(tasks)) loop.close() async def createAlg(self, board, move): print("Start ", move) moveTransition = board.currentPlayer.makeMove(move) if moveTransition.moveStatus.isDone(): if board.currentPlayer.alliance.isWhite(): #print("Depth is ", self.depth) queue = SimpleQueue() await self.min(moveTransition.transitionBoard, self.depth - 1, queue) else: #print("Depth is ", self.depth) queue = SimpleQueue() await self.max(moveTransition.transitionBoard, self.depth - 1, queue) print(queue.get()) async def min(self, board: Board.Board, depth: int, queue: SimpleQueue) -> None: if depth == 0 or self.isEndGameScenario(board): queue.put(self.boardEvaluator.evaluate(board, depth)) return lowestSeenValue: float = float('inf') await asyncio.sleep(0.00001) for move in board.currentPlayer.legalMoves: moveTransition: MoveTransition.MoveTransition = board.currentPlayer.makeMove(move) if moveTransition.moveStatus.isDone(): await self.max(moveTransition.transitionBoard, depth-1, queue) currentValue = queue.get() if currentValue <= lowestSeenValue: lowestSeenValue = currentValue queue.put(lowestSeenValue) return async def max(self, board: Board.Board, depth: int, queue: SimpleQueue) -> None: if depth == 0 or self.isEndGameScenario(board): queue.put(self.boardEvaluator.evaluate(board, depth)) return highestSeenValue: float = float('-inf') await asyncio.sleep(0.00001) for move in board.currentPlayer.legalMoves: moveTransition: MoveTransition.MoveTransition = board.currentPlayer.makeMove(move) if moveTransition.moveStatus.isDone(): await self.min(moveTransition.transitionBoard, depth-1, queue) currentValue = queue.get() if currentValue >= highestSeenValue: highestSeenValue = currentValue queue.put(highestSeenValue) return @staticmethod def isEndGameScenario(board: Board.Board): return board.currentPlayer.isInCheckMate or board.currentPlayer.isInStaleMate
class MinMax(MoveStrategy): def __init__(self, depth: int): self.boardEvaluator = StandardBoardEvaluator() self.depth: int = depth self._boardsEvaluated = 0 def __str__(self): return "MiniMax" @property def boardsEvaluated(self): return self._boardsEvaluated def execute(self, board: Board.Board) -> Move.Move: bestMove: Move.Move = Move.nullMove highestSeenValue = float('-inf') lowestSeenValue = float('inf') print(str(board.currentPlayer) + " Thinking with Depth = " + str(self.depth)) moveCounter = 1 numMoves = len(board.currentPlayer.legalMoves) for move in board.currentPlayer.legalMoves: moveTransition = board.currentPlayer.makeMove(move) if moveTransition.moveStatus.isDone(): if board.currentPlayer.alliance.isWhite(): currentValue = self.min(moveTransition.transitionBoard, self.depth-1) else: currentValue = self.max(moveTransition.transitionBoard, self.depth-1) print(str(self) + " analysing move (" + str(moveCounter) + "/" + str(numMoves) + ") " + str(move) + " scores " + str(currentValue) + " ") if board.currentPlayer.alliance.isWhite() and currentValue >= highestSeenValue: highestSeenValue = currentValue bestMove = move elif board.currentPlayer.alliance.isBlack() and currentValue <= lowestSeenValue: lowestSeenValue = currentValue bestMove = move moveCounter += 1 return bestMove def min(self, board: Board.Board, depth: int) -> Union[float, int]: if self.isEndGameScenario(board) or depth == 0: eval = self.boardEvaluator.evaluate(board, depth) return eval lowestSeenValue: float = float('inf') for move in board.currentPlayer.legalMoves: moveTransition: MoveTransition.MoveTransition = board.currentPlayer.makeMove(move) if moveTransition.moveStatus.isDone(): currentValue = self.max(moveTransition.transitionBoard, depth-1) if currentValue <= lowestSeenValue: lowestSeenValue = currentValue return lowestSeenValue def max(self, board: Board.Board, depth: int) -> Union[float, int]: if self.isEndGameScenario(board) or depth == 0: eval = self.boardEvaluator.evaluate(board, depth) return eval highestSeenValue: float = float('-inf') for move in board.currentPlayer.legalMoves: moveTransition: MoveTransition.MoveTransition = board.currentPlayer.makeMove(move) if moveTransition.moveStatus.isDone(): currentValue: int = self.min(moveTransition.transitionBoard, depth - 1) if currentValue >= highestSeenValue: highestSeenValue = currentValue return highestSeenValue @staticmethod def isEndGameScenario(board: Board.Board): return board.currentPlayer.isInCheckMate or board.currentPlayer.isInStaleMate
class AlphaBeta(MoveStrategy): def __init__(self, depth: int, quiescenceFactor: int): self.evaluator = StandardBoardEvaluator() self.depth = depth self.quiescenceFactor = quiescenceFactor self.moveSorter = MoveSorter() self.boardsEvaluated = 0 self.quiesceCount = 0 self.cutOffsProduced = 0 def __str__(self): return "AB+MO" @property def getNumBoardsEval(self): return self.boardsEvaluated def execute(self, board: Board.Board) -> Move.Move: currentPlayer = board.currentPlayer alliance = currentPlayer.alliance bestMove = nullMove highestSeenValue = -999999 lowestSeenValue = 999999 moveCounter = 1 print( str(board.currentPlayer) + " THINKING with depth = " + str(self.depth)) unsorted = board.currentPlayer.legalMoves for move in self.moveSorter.sort(unsorted): moveTransition = board.currentPlayer.makeMove(move) self.quiesceCount = 0 if moveTransition.moveStatus.isDone(): if board.currentPlayer.alliance.isWhite(): currentValue = self.min(moveTransition.transitionBoard, self.depth - 1, highestSeenValue, lowestSeenValue) else: currentValue = self.max(moveTransition.transitionBoard, self.depth - 1, highestSeenValue, lowestSeenValue) if alliance.isWhite() and currentValue > highestSeenValue: highestSeenValue = currentValue bestMove = move elif alliance.isBlack() and currentValue < lowestSeenValue: lowestSeenValue = currentValue bestMove = move moveCounter += 1 return bestMove def min(self, board: Board.Board, depth: int, highest: int, lowest: int) -> Union[float, int]: if depth == 0 or isEndGame(board): self.boardsEvaluated += 1 return self.evaluator.evaluate(board, depth) currentLowest = lowest sortedList = self.moveSorter.sort(board.currentPlayer.legalMoves) for move in sortedList: moveTransition: MoveTransition.MoveTransition = board.currentPlayer.makeMove( move) if moveTransition.moveStatus.isDone(): currentLowest = min([ currentLowest, self.max(moveTransition.transitionBoard, depth - 1, highest, currentLowest) ]) if currentLowest <= highest: self.cutOffsProduced += 1 break return currentLowest def max(self, board: Board.Board, depth: int, highest: int, lowest: int) -> Union[float, int]: if depth == 0 or isEndGame(board): self.boardsEvaluated += 1 return self.evaluator.evaluate(board, depth) currentHighest = highest unsorted = board.currentPlayer.legalMoves for move in self.moveSorter.sort(unsorted): moveTransition: MoveTransition.MoveTransition = board.currentPlayer.makeMove( move) if moveTransition.moveStatus.isDone(): currentHighest = max([ currentHighest, self.min(moveTransition.transitionBoard, depth - 1, currentHighest, lowest) ]) if lowest <= currentHighest: self.cutOffsProduced += 1 break return currentHighest