示例#1
0
    def minimax(self, board: str):
        """
        Does a minimax search.
        :param board:
        :return: (move, (val, game_length)): the move to achieve the best val with 
                                             the longest game for current player.
        """
        """ Your Code Here """

        # ----------------------------BEGIN CODE----------------------------
        # disclaimer: I did only minimax (as said on the homework description https://drive.google.com/file/d/1JXBi_5JB8fwTWX34j0ZwN5YwjoIexh-Z/view)
        # my minimax does NOT try to prolong the game. It always goes for the best move!

        # initializing default values
        moveToMake = validMoves(board)[0]
        bestValue = -100

        # this will find the best move to go to, since value only returns the best score
        # util's setMove creates a copy, so we can use that as the successor
        for validmove in validMoves(board):
            currentValue = self.value(
                setMove(board, validmove, whoseMove(board)), 0)
            if currentValue > bestValue:
                bestValue = currentValue
                moveToMake = validmove

        # currently the val and game_length tuple is arbitrary because i have not implemented depth!
        return (moveToMake)
示例#2
0
 def minvalue(self, board: str, score):
     # set v to positive infinity
     v = 9999
     # min of value(successor)
     for validmove in validMoves(board):
         v = min(
             v,
             self.value(setMove(board, validmove, whoseMove(board)), score))
     return v
示例#3
0
 def maxvalue(self, board: str, score):
     # set v to negative infinity
     v = -9999
     # max of value(successor)
     for validmove in validMoves(board):
         v = max(
             v,
             self.value(setMove(board, validmove, whoseMove(board)), score))
     return v
示例#4
0
 def reverseTransformMove(self, move: int, r: int, f: int) -> int:
     """
     Unflip and then unrotate the move position.
     :param move:
     :param r:
     :param f:
     :return:
     """
     board = NEWBOARD
     # board[move] = 'M'
     updatedBoard = setMove(board, move, 'M')
     restoredBoard = self.restore(updatedBoard, r, f)
     nOrig = restoredBoard.index('M')
     return nOrig
示例#5
0
    def step(self, board: str, move: int) -> (Optional[PlayerDict], str):
        """
        Make the move and return (winnerDict, updatedBoard).
        If no winner, winnerDict will be None.
        :param board:
        :param move:
        :return: (winnerDict, updatedBoard)
        """
        currentPlayerDict: PlayerDict = self.XDict if whoseMove(
            board) is XMARK else self.ODict
        otherPlayerDict: PlayerDict = self.otherDict(currentPlayerDict)

        # The following are all game-ending cases.
        if not isAvailable(board, move):
            # Illegal move. currentPlayerDict loses.
            # Illegal moves should be blocked and should not occur.
            currentPlayerDict['cachedReward'] = -100
            otherPlayerDict['cachedReward'] = 100
            print(f'\n\nInvalid move by {currentPlayerDict["mark"]}: {move}.',
                  end='')
            return (otherPlayerDict, board)

        updatedBoard = setMove(board, move, currentPlayerDict['mark'])
        if theWinner(updatedBoard):
            # The current player just won the game with its current move.
            currentPlayerDict['cachedReward'] = 100
            otherPlayerDict['cachedReward'] = -100
            return (currentPlayerDict, updatedBoard)

        if emptyCellsCount(updatedBoard) == 0:
            # The game is over. It's a tie.
            currentPlayerDict['cachedReward'] = 0
            otherPlayerDict['cachedReward'] = 0
            return (None, updatedBoard)

        # The game is not over.
        # Get a reward for extending the game.
        currentPlayerDict['cachedReward'] = 1
        return (None, updatedBoard)
示例#6
0
 def makeAndEvaluateMove(self, board: str, move: int, mark: str,
                         count: int) -> Tuple[int, int, int]:
     """
     Make the move and evaluate the board.
     :param board:
     :param move:
     :param mark:
     :param count: A longer game is better.
     :return: 'X' is maximizer; 'O' is minimizer
     """
     boardCopy = setMove(board, move, mark)
     winner = theWinner(boardCopy)
     (val, nextCount) = (
         (1, count) if winner == XMARK else
         (-1, count) if winner == OMARK else
         # winner == None. Is the game a tie because board is full?
         (0, count) if emptyCellsCount(boardCopy) == 0 else
         # The game is not over.  Minimax is is called as the argument to this lambda function.
         # Minimax returns (val, move, count). Select and return val and count.
         # move is the next player's best move, which we don't return.
         (lambda mmResult:
          (mmResult[0], mmResult[2]))(self.minimax(boardCopy, count)))
     return (val, move, nextCount)
示例#7
0
 def getQMove(self, board: str, move: int) -> int:
     (_, r, f) = self.getQBoardWithRF(board)
     tempBoard = setMove(NEWBOARD, move, 'M')
     qTempBoard = self.transform(tempBoard, r, f)
     qMove = qTempBoard.index('M')
     return qMove