Exemplo n.º 1
0
    def quickEvaluate(self, history, whiteKing, whiteQueen, whiteBishop,
                      whiteKnight, whiteRook, whitePawn, blackKing, blackQueen,
                      blackBishop, blackKnight, blackRook, blackPawn,
                      whiteQueenCastle, whiteKingCastle, blackQueenCastle,
                      blackKingCastle, depth, playerIsWhite):
        Moves = self.Moves
        counter = 0

        self.currKing = whiteKing
        self.currQueen = whiteQueen
        self.currBishop = whiteBishop
        self.currKnight = whiteKnight
        self.currRook = whiteRook
        self.currPawn = whitePawn
        self.altKing = blackKing
        self.altQueen = blackQueen
        self.altBishop = blackBishop
        self.altKnight = blackKnight
        self.altRook = blackRook
        self.altPawn = blackPawn

        whitePossibleMoves = Moves.white_legalMoves(
            history, whiteKing, whiteQueen, whiteBishop, whiteKnight,
            whiteRook, whitePawn, blackKing, blackQueen, blackBishop,
            blackKnight, blackRook, blackPawn, whiteQueenCastle,
            whiteKingCastle, blackQueenCastle, blackKingCastle)
        blackPossibleMoves = Moves.black_legalMoves(
            history, whiteKing, whiteQueen, whiteBishop, whiteKnight,
            whiteRook, whitePawn, blackKing, blackQueen, blackBishop,
            blackKnight, blackRook, blackPawn, whiteQueenCastle,
            whiteKingCastle, blackQueenCastle, blackKingCastle)
        numOfWhitePossibleMoves = len(whitePossibleMoves.split())
        numOfBlackPossibleMoves = len(blackPossibleMoves.split())

        boardFlipped = False
        if (playerIsWhite):
            pass
        elif (not playerIsWhite):
            self.flipBoard()
            boardFlipped = True
        """
		-> Our internal board is always represented with black pieces on top, white pieces at the bottom. 
		-> Our method usually will just evaluate white pieces, add it to our counter; flip the board, evaluate white pieces again, 
			and deduct them from our counter. 
		-> If player is white and if it's white turn to move, there's no problem at all with this approach, 
			since we will add white pieces' score to our counter, and deduct black pieces' score from our counter.
		-> If player is white and if it's black turn to move, observe that there is still no problem with this approach. 
			In particular, we'll add white pieces' score to our counter, and deduct black pieces' score from our counter. This is okay, because
			we want our board evaluation to be based on white player's perspective. We want to see if when black makes a move, how does it affect white player.
		-> When player is black, we just need to flip board before computing. The rest of the procedure remains the same.

		"""

        #give each piece on the board a score, rate the board
        #Player's perspective
        material = self.rateMaterial(self.currKing, self.currQueen,
                                     self.currBishop, self.currKnight,
                                     self.currRook, self.currPawn)
        counter = counter + material
        #score for white pieces (player is white)
        if (not boardFlipped):
            #rate Moveability
            counter = counter + self.rateMoveability(
                self.currKing, self.currQueen, self.currBishop,
                self.currKnight, self.currRook, self.currPawn, self.altKing,
                self.altQueen, self.altBishop, self.altKnight, self.altRook,
                self.altPawn, depth, material, numOfWhitePossibleMoves)
        #score for black pieces (player is black)
        elif (boardFlipped):
            #rate Moveability
            counter = counter + self.rateMoveability(
                self.currKing, self.currQueen, self.currBishop,
                self.currKnight, self.currRook, self.currPawn, self.altKing,
                self.altQueen, self.altBishop, self.altKnight, self.altRook,
                self.altPawn, depth, material, numOfBlackPossibleMoves)
        self.flipBoard()
        #we need to update our board flipped variable according to if our board is flipped now
        #if board is not flipped before, since we just do flipBoard(), our board is flipped now.
        if (boardFlipped == False):
            boardFlipped = True
        #if board is flipped before, since we just do flipBoard(), board is now back to its original state. So board is not flipped now.
        elif (boardFlipped == True):
            boardFlipped = False

        #Opponent's perspective
        material = self.rateMaterial(self.currKing, self.currQueen,
                                     self.currBishop, self.currKnight,
                                     self.currRook, self.currPawn)
        counter = counter - material
        #score for black pieces (player is white)
        if (boardFlipped):
            counter = counter - self.rateMoveability(
                self.currKing, self.currQueen, self.currBishop,
                self.currKnight, self.currRook, self.currPawn, self.altKing,
                self.altQueen, self.altBishop, self.altKnight, self.altRook,
                self.altPawn, depth, material, numOfBlackPossibleMoves)
        #score for white pieces (player is black)
        elif (not boardFlipped):
            counter = counter - self.rateMoveability(
                self.currKing, self.currQueen, self.currBishop,
                self.currKnight, self.currRook, self.currPawn, self.altKing,
                self.altQueen, self.altBishop, self.altKnight, self.altRook,
                self.altPawn, depth, material, numOfWhitePossibleMoves)
        self.flipBoard()
        #we need to update our board flipped variable according to if our board is flipped now
        #if board is not flipped before, since we just do flipBoard(), our board is flipped now.
        if (boardFlipped == False):
            boardFlipped = True
        #if board is flipped before, since we just do flipBoard(), board is now back to its original state. So board is not flipped now.
        elif (boardFlipped == True):
            boardFlipped = False

        #restore board to original state. black pieces on top, white pieces at bottom
        if (boardFlipped):
            self.flipBoard()
            boardFlipped = False

        return (counter + depth * 500)
Exemplo n.º 2
0
    def principalVariationSearch(self, alpha, beta, history, whiteKing,
                                 whiteQueen, whiteBishop, whiteKnight,
                                 whiteRook, whitePawn, blackKing, blackQueen,
                                 blackBishop, blackKnight, blackRook,
                                 blackPawn, whiteQueenCastle, whiteKingCastle,
                                 blackQueenCastle, blackKingCastle, whiteTurn,
                                 depth):
        Moves = self.Moves
        Rating = self.Rating

        #if we reach our max search depth, return the best score for the board at that level
        if (depth == self.maxDepth):
            bestScore = Rating.evaluate(
                history, whiteKing, whiteQueen, whiteBishop, whiteKnight,
                whiteRook, whitePawn, blackKing, blackQueen, blackBishop,
                blackKnight, blackRook, blackPawn, whiteQueenCastle,
                whiteKingCastle, blackQueenCastle, blackKingCastle, depth,
                self.playerIsWhite)
            return bestScore, "No Move"

        if (whiteTurn):
            moves = Moves.white_legalMoves(
                history, whiteKing, whiteQueen, whiteBishop, whiteKnight,
                whiteRook, whitePawn, blackKing, blackQueen, blackBishop,
                blackKnight, blackRook, blackPawn, whiteQueenCastle,
                whiteKingCastle, blackQueenCastle, blackKingCastle)
        else:
            moves = Moves.black_legalMoves(
                history, whiteKing, whiteQueen, whiteBishop, whiteKnight,
                whiteRook, whitePawn, blackKing, blackQueen, blackBishop,
                blackKnight, blackRook, blackPawn, whiteQueenCastle,
                whiteKingCastle, blackQueenCastle, blackKingCastle)

        #get the first legal move for the current player. After the moves have been sorted, we assume that the first move is always the best move.
        moves = self.sanitizeMove(moves, history, whiteKing, whiteQueen,
                                  whiteBishop, whiteKnight, whiteRook,
                                  whitePawn, blackKing, blackQueen,
                                  blackBishop, blackKnight, blackRook,
                                  blackPawn, whiteQueenCastle, whiteKingCastle,
                                  blackQueenCastle, blackKingCastle, whiteTurn)

        #if no legal move for current player, then it must be checkmate or stalemate
        #if this is player's turn, this is really bad. return -5000
        #if this is opponent's turn, this is good. we want this. return 5000
        #TODO: Check this AND FIX THIS!
        if (len(moves) == 0):
            if (self.playerIsWhite == whiteTurn):
                return -5000, "No Move"
            else:
                return 5000, "No Move"

        moves = self.sortMoves(moves, history, whiteKing, whiteQueen,
                               whiteBishop, whiteKnight, whiteRook, whitePawn,
                               blackKing, blackQueen, blackBishop, blackKnight,
                               blackRook, blackPawn, whiteQueenCastle,
                               whiteKingCastle, blackQueenCastle,
                               blackKingCastle, whiteTurn, depth)

        firstLegalMoveIndex = 0
        b = beta
        bestScore = -math.inf

        ####################################### throughroughly search firstLegalMove
        firstLegalMove = moves[firstLegalMoveIndex]

        try:
            originalX = int(firstLegalMove[0])
            originalY = int(firstLegalMove[1])
            newX = int(firstLegalMove[2])
            newY = int(firstLegalMove[3])
        except (ValueError):
            raise ValueError(
                "Error in principalVariationSearch: the first four character of firstLegalMove string must be integer."
            )

        start = (originalX * 8) + originalY
        end = (newX * 8) + newY

        #white pieces
        tempWhiteKing = Moves.makeMove(whiteKing, firstLegalMove, "K")
        tempWhiteQueen = Moves.makeMove(whiteQueen, firstLegalMove, "Q")
        tempWhiteBishop = Moves.makeMove(whiteBishop, firstLegalMove, "B")
        tempWhiteKnight = Moves.makeMove(whiteKnight, firstLegalMove, "H")
        tempWhiteRook = Moves.makeMove(whiteRook, firstLegalMove, "R")
        tempWhitePawn = Moves.makeMove(whitePawn, firstLegalMove, "P")
        #if castling, make castling move
        if ("WL" in firstLegalMove or "WR" in firstLegalMove):
            tempWhiteKing, tempWhiteRook = Moves.makeCastlingMove(
                whiteKing, whiteRook, firstLegalMove)
        #black pieces
        tempBlackKing = Moves.makeMove(blackKing, firstLegalMove, "k")
        tempBlackQueen = Moves.makeMove(blackQueen, firstLegalMove, "q")
        tempBlackBishop = Moves.makeMove(blackBishop, firstLegalMove, "b")
        tempBlackKnight = Moves.makeMove(blackKnight, firstLegalMove, "h")
        tempBlackRook = Moves.makeMove(blackRook, firstLegalMove, "r")
        tempBlackPawn = Moves.makeMove(blackPawn, firstLegalMove, "p")
        if ("BL" in firstLegalMove or "BR" in firstLegalMove):
            tempBlackKing, tempBlackRook = Moves.makeCastlingMove(
                blackKing, blackRook, firstLegalMove)
        tempHistory = firstLegalMove

        ###update castling variables
        #copy castling variables from previous
        tempWhiteQueenCastle = whiteQueenCastle
        tempWhiteKingCastle = whiteKingCastle
        tempBlackQueenCastle = blackQueenCastle
        tempBlackKingCastle = blackKingCastle

        #update castling variable based on the firstLegalMove we made
        #if firstLegalMove is making white castling move, we can no longer castle again for white
        if ("WL" in firstLegalMove or "WR" in firstLegalMove):
            tempWhiteQueenCastle = False
            tempWhiteKingCastle = False
        #if firstLegalMove is making black castling move, we can no longer castle again for black
        elif ("BL" in firstLegalMove or "BR" in firstLegalMove):
            tempBlackQueenCastle = False
            tempBlackKingCastle = False
        else:
            #if firstLegalMove is moving whiteKing, white queen and king side castle become False
            if (((1 << start) & whiteKing) != 0):
                tempWhiteQueenCastle = False
                tempWhiteKingCastle = False
            #if firstLegalMove is moving blackKing, black queen and king side castle become False
            elif (((1 << start) & blackKing) != 0):
                tempBlackQueenCastle = False
                tempBlackKingCastle = False
            #if firstLegalMove is moving white left rook, white queenside castling become False
            elif (((1 << start) & whiteRook & (1 << 56)) != 0):
                tempWhiteQueenCastle = False
            #if firstLegalMove is moving white right rook, white kingside castling become False
            elif (((1 << start) & whiteRook & (1 << 63)) != 0):
                tempWhiteKingCastle = False
            elif (((1 << start) & blackRook & (1 << 0)) != 0):
                tempBlackQueenCastle = False
            elif (((1 << start) & blackRook & (1 << 7)) != 0):
                tempBlackKingCastle = False
        """
		# original algorithm
		score,bestMove=-self.principalVariationSearch(-b,-alpha,tempHistory,tempWhiteKing,tempWhiteQueen,tempWhiteBishop,tempWhiteKnight,tempWhiteRook,tempWhitePawn,tempBlackKing,tempBlackQueen,tempBlackBishop,tempBlackKnight,tempBlackRook,tempBlackPawn,tempWhiteQueenCastle,tempWhiteKingCastle,tempBlackQueenCastle,tempBlackKingCastle,not whiteTurn,depth+1)
		"""
        #Alternate way of writing to original algorithm
        score, bestMove = self.principalVariationSearch(
            -b, -alpha, tempHistory, tempWhiteKing, tempWhiteQueen,
            tempWhiteBishop, tempWhiteKnight, tempWhiteRook, tempWhitePawn,
            tempBlackKing, tempBlackQueen, tempBlackBishop, tempBlackKnight,
            tempBlackRook, tempBlackPawn, tempWhiteQueenCastle,
            tempWhiteKingCastle, tempBlackQueenCastle, tempBlackKingCastle,
            not whiteTurn, depth + 1)
        score = -score
        #In principal variation search, we assume that our first move is the best move, and thus yield the best score.
        bestScore = self.max(bestScore, score)  #can also write bestScore=score
        alpha = self.max(alpha, score)
        bestMoveIndex = firstLegalMoveIndex
        if (alpha >= beta):
            return alpha, moves[bestMoveIndex]

        b = alpha + 1

        ####################################### simply and quickly search through remaining move to confirm our assumption that firstLegalMove is the best move
        for i in range(len(moves)):
            #if current iteration is firstLegalMoveIndex, skip, since we already thoroughly searched this move.
            if (i == firstLegalMoveIndex):
                continue
            #if current iteration is not firstLegalMoveIndex, simply and quickly search through current move.
            currentMove = moves[i]
            try:
                originalX = int(currentMove[0])
                originalY = int(currentMove[1])
                newX = int(currentMove[2])
                newY = int(currentMove[3])
            except (ValueError):
                raise ValueError(
                    "Error in principalVariationSearch: the first four character of currentMove string must be integer."
                )

            start = (originalX * 8) + originalY
            end = (newX * 8) + newY

            #white pieces
            tempWhiteKing = Moves.makeMove(whiteKing, currentMove, "K")
            tempWhiteQueen = Moves.makeMove(whiteQueen, currentMove, "Q")
            tempWhiteBishop = Moves.makeMove(whiteBishop, currentMove, "B")
            tempWhiteKnight = Moves.makeMove(whiteKnight, currentMove, "H")
            tempWhiteRook = Moves.makeMove(whiteRook, currentMove, "R")
            tempWhitePawn = Moves.makeMove(whitePawn, currentMove, "P")
            #if castling, make castling move
            if ("WL" in currentMove or "WR" in currentMove):
                tempWhiteKing, tempWhiteRook = Moves.makeCastlingMove(
                    whiteKing, whiteRook, currentMove)
            #black pieces
            tempBlackKing = Moves.makeMove(blackKing, currentMove, "k")
            tempBlackQueen = Moves.makeMove(blackQueen, currentMove, "q")
            tempBlackBishop = Moves.makeMove(blackBishop, currentMove, "b")
            tempBlackKnight = Moves.makeMove(blackKnight, currentMove, "h")
            tempBlackRook = Moves.makeMove(blackRook, currentMove, "r")
            tempBlackPawn = Moves.makeMove(blackPawn, currentMove, "p")
            if ("BL" in currentMove or "BR" in currentMove):
                tempBlackKing, tempBlackRook = Moves.makeCastlingMove(
                    blackKing, blackRook, currentMove)
            tempHistory = currentMove

            ###update castling variables
            #copy castling variables from previous
            tempWhiteQueenCastle = whiteQueenCastle
            tempWhiteKingCastle = whiteKingCastle
            tempBlackQueenCastle = blackQueenCastle
            tempBlackKingCastle = blackKingCastle

            #update castling variable based on the currentMove we made
            #if currentMove is making white castling move, we can no longer castle again for white
            if ("WL" in currentMove or "WR" in currentMove):
                tempWhiteQueenCastle = False
                tempWhiteKingCastle = False
            #if currentMove is making black castling move, we can no longer castle again for black
            elif ("BL" in currentMove or "BR" in currentMove):
                tempBlackQueenCastle = False
                tempBlackKingCastle = False
            else:
                #if currentMove is moving whiteKing, white queen and king side castle become False
                if (((1 << start) & whiteKing) != 0):
                    tempWhiteQueenCastle = False
                    tempWhiteKingCastle = False
                #if currentMove is moving blackKing, black queen and king side castle become False
                elif (((1 << start) & blackKing) != 0):
                    tempBlackQueenCastle = False
                    tempBlackKingCastle = False
                #if currentMove is moving white left rook, white queenside castling become False
                elif (((1 << start) & whiteRook & (1 << 56)) != 0):
                    tempWhiteQueenCastle = False
                #if currentMove is moving white right rook, white kingside castling become False
                elif (((1 << start) & whiteRook & (1 << 63)) != 0):
                    tempWhiteKingCastle = False
                elif (((1 << start) & blackRook & (1 << 0)) != 0):
                    tempBlackQueenCastle = False
                elif (((1 << start) & blackRook & (1 << 7)) != 0):
                    tempBlackKingCastle = False

            #TODO: check this!
            """
			# original algorithm
			score,bestMove=-self.principalVariationSearch(-b,-alpha,tempHistory,tempWhiteKing,tempWhiteQueen,tempWhiteBishop,tempWhiteKnight,tempWhiteRook,tempWhitePawn,tempBlackKing,tempBlackQueen,tempBlackBishop,tempBlackKnight,tempBlackRook,tempBlackPawn,tempWhiteQueenCastle,tempWhiteKingCastle,tempBlackQueenCastle,tempBlackKingCastle,not whiteTurn,depth+1)
			"""
            #Alternate way of writing to original algorithm
            score, bestMove = self.principalVariationSearch(
                -b, -alpha, tempHistory, tempWhiteKing, tempWhiteQueen,
                tempWhiteBishop, tempWhiteKnight, tempWhiteRook, tempWhitePawn,
                tempBlackKing, tempBlackQueen, tempBlackBishop,
                tempBlackKnight, tempBlackRook, tempBlackPawn,
                tempWhiteQueenCastle, tempWhiteKingCastle,
                tempBlackQueenCastle, tempBlackKingCastle, not whiteTurn,
                depth + 1)
            score = -score
            if (score > alpha and score < beta):
                """
				# original algorithm
				score,bestMove=-self.principalVariationSearch(-beta,-score,tempHistory,tempWhiteKing,tempWhiteQueen,tempWhiteBishop,tempWhiteKnight,tempWhiteRook,tempWhitePawn,tempBlackKing,tempBlackQueen,tempBlackBishop,tempBlackKnight,tempBlackRook,tempBlackPawn,tempWhiteQueenCastle,tempWhiteKingCastle,tempBlackQueenCastle,tempBlackKingCastle,not whiteTurn,depth+1)
				"""
                #alternate way of writing to original algorithm
                score, bestMove = self.principalVariationSearch(
                    -beta, -score, tempHistory, tempWhiteKing, tempWhiteQueen,
                    tempWhiteBishop, tempWhiteKnight, tempWhiteRook,
                    tempWhitePawn, tempBlackKing, tempBlackQueen,
                    tempBlackBishop, tempBlackKnight, tempBlackRook,
                    tempBlackPawn, tempWhiteQueenCastle, tempWhiteKingCastle,
                    tempBlackQueenCastle, tempBlackKingCastle, not whiteTurn,
                    depth + 1)
                score = -score
                ##For debugging
                # print("researched")
            if (score > bestScore):
                bestMoveIndex = i
                bestScore = score
            alpha = self.max(alpha, score)
            if (alpha >= beta):
                return alpha, moves[bestMoveIndex]
            b = alpha + 1

        return bestScore, moves[bestMoveIndex]
Exemplo n.º 3
0
    def getAllCurrentLegalMoves(self, whiteTurn):
        Moves = self.Moves

        if (whiteTurn):
            moves = Moves.white_legalMoves(
                self.history, self.whiteKing, self.whiteQueen,
                self.whiteBishop, self.whiteKnight, self.whiteRook,
                self.whitePawn, self.blackKing, self.blackQueen,
                self.blackBishop, self.blackKnight, self.blackRook,
                self.blackPawn, self.whiteQueenCastle, self.whiteKingCastle,
                self.blackQueenCastle, self.blackKingCastle)
        else:
            moves = Moves.black_legalMoves(
                self.history, self.whiteKing, self.whiteQueen,
                self.whiteBishop, self.whiteKnight, self.whiteRook,
                self.whitePawn, self.blackKing, self.blackQueen,
                self.blackBishop, self.blackKnight, self.blackRook,
                self.blackPawn, self.whiteQueenCastle, self.whiteKingCastle,
                self.blackQueenCastle, self.blackKingCastle)

        moves = moves.split()
        li = []
        for i in range(len(moves)):
            currentMove = moves[i]
            #white pieces
            tempWhiteKing = Moves.makeMove(self.whiteKing, currentMove, "K")
            tempWhiteQueen = Moves.makeMove(self.whiteQueen, currentMove, "Q")
            tempWhiteBishop = Moves.makeMove(self.whiteBishop, currentMove,
                                             "B")
            tempWhiteKnight = Moves.makeMove(self.whiteKnight, currentMove,
                                             "H")
            tempWhiteRook = Moves.makeMove(self.whiteRook, currentMove, "R")
            tempWhitePawn = Moves.makeMove(self.whitePawn, currentMove, "P")
            #if castling, make castling move
            if ("WL" in currentMove or "WR" in currentMove):
                tempWhiteKing, tempWhiteRook = Moves.makeCastlingMove(
                    self.whiteKing, self.whiteRook, currentMove)
            #black pieces
            tempBlackKing = Moves.makeMove(self.blackKing, currentMove, "k")
            tempBlackQueen = Moves.makeMove(self.blackQueen, currentMove, "q")
            tempBlackBishop = Moves.makeMove(self.blackBishop, currentMove,
                                             "b")
            tempBlackKnight = Moves.makeMove(self.blackKnight, currentMove,
                                             "h")
            tempBlackRook = Moves.makeMove(self.blackRook, currentMove, "r")
            tempBlackPawn = Moves.makeMove(self.blackPawn, currentMove, "p")
            if ("BL" in currentMove or "BR" in currentMove):
                tempBlackKing, tempBlackRook = Moves.makeCastlingMove(
                    self.blackKing, self.blackRook, currentMove)
            tempHistory = currentMove

            if (whiteTurn):
                if ((tempWhiteKing & Moves.whiteKing_illegalMoves(
                        tempWhiteKing, tempWhiteQueen, tempWhiteBishop,
                        tempWhiteKnight, tempWhiteRook, tempWhitePawn,
                        tempBlackKing, tempBlackQueen, tempBlackBishop,
                        tempBlackKnight, tempBlackRook, tempBlackPawn)) == 0):
                    li.append(currentMove)
            elif (not whiteTurn):
                if ((tempBlackKing & Moves.blackKing_illegalMoves(
                        tempWhiteKing, tempWhiteQueen, tempWhiteBishop,
                        tempWhiteKnight, tempWhiteRook, tempWhitePawn,
                        tempBlackKing, tempBlackQueen, tempBlackBishop,
                        tempBlackKnight, tempBlackRook, tempBlackPawn)) == 0):
                    li.append(currentMove)

        self.currentAllLegalMoves = li