import random from copy import deepcopy from math import inf from utilities.constants import GREEN, WHITE class MiniMax(): def AI(self, board, depth, maxPlayer, gameManager): if depth == 0 or board.winner() is not None: return board.scoreOfTheBoard(), board if maxPlayer: maxEval = -inf bestMove = None for move in self.getAllMoves(board, maxPlayer): evaluation = self.AI(move, depth - 1, False, gameManager)[0] maxEval = max(maxEval, evaluation) if maxEval > evaluation: bestMove = move if maxEval == evaluation: bestMove = bestMove if random.choice([True, False]) else move return maxEval, bestMove else: minEval = inf bestMove = None colour = WHITE if gameManager.turn == GREEN else GREEN for move in self.getAllMoves(board, colour): evaluation = self.AI(move, depth - 1, True, gameManager)[0] minEval = min(minEval, evaluation) if minEval < evaluation: bestMove = move if minEval == evaluation: bestMove = bestMove if random.choice([True, False]) else move return minEval, bestMove def _simulateMove(self, piece, move, board, skip): board.move(piece, move[0], move[1]) if skip: board.remove(skip) return board def getAllMoves(self, board, colour): moves = [] for piece in board.getAllPieces(colour): validMoves = board.getValidMoves(piece) for move, skip in validMoves.items(): tempBoard = deepcopy(board) tempPiece = tempBoard.getPiece(piece.row, piece.col) newBoard = self._simulateMove(tempPiece, move, tempBoard, skip) moves.append(newBoard) return moves