예제 #1
0
 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
예제 #2
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)
예제 #3
0
 def __init__(self, depth: int):
     self.boardEvaluator = StandardBoardEvaluator()
     self.depth: int = depth
     self._boardsEvaluated = 0
     self.thread = 0
예제 #4
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
예제 #5
0
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
예제 #6
0
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