예제 #1
0
def generateKingMoves(pos):

    us = pos.color

    usKing = pos.board[us][KING]

    emptySquares = ~(pos.blocker) & BB_ALL_SQUARES

    notFriends = ~pos.us & BB_ALL_SQUARES

    for bits in iterBits(usKing):
        for m in iterBits(attacksFrom(KING, bits) & notFriends):
            yield createMove(bits, m, 0)

    if us == WHITE:
        if pos.castles & W_OO:
            wooStepOvers = betweenBB(4, 7)
            if (wooStepOvers & emptySquares) == wooStepOvers:
                yield createMove(4, 6, KING_CASTLE)
        if pos.castles & W_OOO:
            woooStepOvers = betweenBB(0, 4)
            if (woooStepOvers & emptySquares) == woooStepOvers:
                yield createMove(4, 2, QUEEN_CASTLE)
    elif us == BLACK:
        if pos.castles & B_OO:
            booStepOvers = betweenBB(60, 63)
            if (booStepOvers & emptySquares) == booStepOvers:
                yield createMove(60, 62, KING_CASTLE)
        if pos.castles & B_OOO:
            boooStepOvers = betweenBB(56, 60)
            if (boooStepOvers & emptySquares) == boooStepOvers:
                yield createMove(60, 58, QUEEN_CASTLE)
예제 #2
0
def generateLegalMoves(pos):

    moveList = generateEvasionMoves(
        pos) if pos.isInCheck() else generatePseudoLegalMoves(pos)

    absolutelyPinned = pos.pinned

    for move in moveList:

        orig = getOrig(move)
        des = getDes(move)
        flag = getFlag(move)

        if flag == ENPASSANT:
            newUsPieces = pos.us ^ BB_SQUARES[orig] ^ BB_SQUARES[des]
            direction = N if pos.color == WHITE else S
            newThemPieces = pos.them ^ BB_SQUARES[des - direction]
            newBoard = pos.board
            newBoard[pos.opColor][0] = newBoard[pos.opColor][0] ^ BB_SQUARES[
                des - direction]
            checkers = attackersTo(newBoard[pos.opColor],
                                   newUsPieces | newThemPieces, pos.king,
                                   pos.opColor)
            if checkers == 0:
                yield move
        elif flag == KING_CASTLE:
            stepOver = betweenBB(4, 7) if pos.color == WHITE else betweenBB(
                60, 63)
            squareAttacked = 0
            for sq in iterBits(stepOver):
                squareAttacked |= attackersTo(pos.board[pos.opColor],
                                              pos.blocker, sq, pos.opColor)
            if squareAttacked == 0:
                yield move
        elif flag == QUEEN_CASTLE:
            stepOver = betweenBB(0, 4) if pos.color == WHITE else betweenBB(
                56, 60)
            squareAttacked = 0
            for sq in iterBits(stepOver):
                squareAttacked |= attackersTo(pos.board[pos.opColor],
                                              pos.blocker, sq, pos.opColor)
            if squareAttacked == 0:
                yield move

        if pos.pieceBoard[orig] == KING:
            if flag == NORMAL:
                squareAttacked = attackersTo(pos.board[pos.opColor],
                                             pos.blocker, des, pos.opColor)
                if ~(squareAttacked > 0) & 1:
                    yield move
        elif ((~absolutelyPinned & BB_ALL_SQUARES) & BB_SQUARES[orig]) | inRay(
                orig, des, pos.king):
            if flag == NORMAL:
                yield move
예제 #3
0
def generateKnightMoves(pos):

    # get color
    us = pos.color

    usKnights = pos.board[us][KNIGHT]

    notFriends = ~pos.us & BB_ALL_SQUARES

    for bits in iterBits(usKnights):
        for m in iterBits(attacksFrom(KNIGHT, bits) & notFriends):
            yield createMove(bits, m, 0)
예제 #4
0
def generateQueenMoves(pos):

    us = pos.color

    blocker = pos.blocker

    usQueens = pos.board[us][QUEEN]

    notFriends = ~pos.us & BB_ALL_SQUARES

    for sq in iterBits(usQueens):
        attack = (attacksFrom(BISHOP, sq, blocker=blocker)
                  | attacksFrom(ROOK, sq, blocker=blocker)) & notFriends
        for m in iterBits(attack):
            yield createMove(sq, m, 0)
예제 #5
0
def generateRookMoves(pos):

    us = pos.color

    blocker = pos.blocker

    usRooks = pos.board[us][ROOK]

    notFriends = ~pos.us & BB_ALL_SQUARES

    for sq in iterBits(usRooks):

        attack = attacksFrom(ROOK, sq, blocker=blocker) & notFriends

        for m in iterBits(attack):
            yield createMove(sq, m, 0)
예제 #6
0
def generateBishopMoves(pos):

    us = pos.color

    blocker = pos.blocker

    usBishops = pos.board[us][BISHOP]

    notFriends = ~pos.us & BB_ALL_SQUARES

    for sq in iterBits(usBishops):

        attack = attacksFrom(BISHOP, sq, blocker=blocker) & notFriends

        for m in iterBits(attack):
            yield createMove(sq, m, 0)
예제 #7
0
    def moveToSAN(self,move):
        notation = ""
        orig = getOrig(move)
        des = getDes(move)
        flag = getFlag(move)
        mPiece = self.pieceBoard[orig]
        tPiece = self.pieceBoard[des]

        notation = notation + algPiece[mPiece]

        sameSquare = attackersTo(self.board[self.color],self.blocker,orig,self.color) & self.board[self.color][mPiece]

        sameFile = 0
        sameRank = 0
        for sq in iterBits(sameSquare):
            file = getFile(sq)
            rank = getRank(sq)
            if file == getFile(orig):
                sameFile = 1
            if rank == getRank(orig):
                sameRank = 1
        if sameFile & sameRank:
            notation = notation + algebraic[orig]
        elif sameFile:
            notation = notation + algebraic[orig][1]
        elif sameRank:
            notation = notation + algebraic[orig][0]

        if tPiece != 6:
            if mPiece == PAWN:
                notation = notation + algebraic[orig][0]
            notation = notation + "x"

        notation = notation + algebraic[des]

        if flag == KING_CASTLE:
            notation = notation = "O-O"
        elif flag == QUEEN_CASTLE:
            notation = notation = "O-O-O"
        elif flag == KNIGHT_PROMO:
            notation = notation + "=" + algPiece[KNIGHT]
        elif flag == BISHOP_PROMO:
            notation = notation + "=" + algPiece[BISHOP]
        elif flag == ROOK_PROMO:
            notation = notation + "=" + algPiece[ROOK]
        elif flag == QUEEN_PROMO:
            notation = notation + "=" + algPiece[QUEEN]
            
        return notation
예제 #8
0
    def printPosition(self):
        tempBoard = [6]*64
        for bits in iterBits(self.us):
            tempBoard[bits] = printPieces[self.color][self.pieceBoard[bits]]

        for bits in iterBits(self.them):
            tempBoard[bits] = printPieces[self.opColor][self.pieceBoard[bits]]

        tempBoard = [x if x != EMPTY else printPieces[self.color][EMPTY] for x in tempBoard]

        prettyBoard = []
        prettyBoard.append(tempBoard[56:64])
        prettyBoard.append(tempBoard[48:56])
        prettyBoard.append(tempBoard[40:48])
        prettyBoard.append(tempBoard[32:40])
        prettyBoard.append(tempBoard[24:32])
        prettyBoard.append(tempBoard[16:24])
        prettyBoard.append(tempBoard[8:16])
        prettyBoard.append(tempBoard[0:8])


        for row in prettyBoard:
            print(' '.join(row))
        print("\n")
예제 #9
0
def blockers(pboard, pieces, square):

    bishopAttacksTo = attacksFrom(BISHOP, square,
                                  blocker=0) & (pboard[BISHOP] | pboard[QUEEN])
    rookAttacksTo = attacksFrom(ROOK, square,
                                blocker=0) & (pboard[ROOK] | pboard[QUEEN])
    attackers = (bishopAttacksTo | rookAttacksTo)

    occ = pieces ^ attackers
    blocker = 0
    for bits in iterBits(attackers):
        b = betweenBB(bits, square)
        inAttack = b & occ
        if pop_count(inAttack) == 1:
            blocker |= inAttack

    return blocker
예제 #10
0
def generateEvasionMoves(pos):

    us = pos.color
    notFriends = ~pos.us & BB_ALL_SQUARES

    #double check
    if pop_count(pos.checkers) > 1:
        #king moves out of check
        usKing = pos.board[us][KING]
        checkerAttacks = 0
        for cord in iterBits(pos.checkers):
            checkerAttacks |= attacksFrom(pos.pieceBoard[cord],
                                          cord,
                                          blocker=0)

        notCheckAttacks = ~checkerAttacks & BB_ALL_SQUARES

        for bits in iterBits(usKing):
            for m in iterBits(
                    attacksFrom(KING, bits) & notFriends & notCheckAttacks):
                yield createMove(bits, m, 0)
    #single check
    else:
        #king move out of check
        usKing = pos.board[us][KING]
        checkerAttacks = 0
        cord = pop_lsb(pos.checkers)
        checkerAttacks = attacksFrom(pos.pieceBoard[cord], cord, blocker=0)

        notCheckAttacks = ~checkerAttacks & BB_ALL_SQUARES

        kingSq = pop_lsb(usKing)
        for m in iterBits(
                attacksFrom(KING, kingSq) & notFriends & notCheckAttacks):
            yield createMove(kingSq, m, 0)

        #capture checker
        checkerAttackers = attackersTo(pos.board[pos.color], pos.blocker, cord,
                                       pos.color)

        promoteRank = BB_RANK_7 if us == WHITE else BB_RANK_2
        for bits in iterBits(checkerAttackers):
            if pos.pieceBoard[bits] == PAWN:
                if BB_SQUARES[bits] & promoteRank:
                    for p in moveFlag[4:]:
                        yield createMove(bits, cord, p)
                else:
                    yield createMove(bits, cord, 0)
            else:
                yield createMove(bits, cord, 0)

        #check if en-passant capture will remove checker
        direction = N if us == WHITE else S
        if (pos.enpassant == cord + direction) & (pos.pieceBoard[cord]
                                                  == PAWN):
            pawnsAtEp = attackersTo(pos.board[us], pos.blocker, pos.enpassant,
                                    us)
            for bits in iterBits(pawnsAtEp):
                yield createMove(bits, pos.enpassant, ENPASSANT)

        #block check
        between = betweenBB(cord, kingSq)
        for bb in pos.board[us][KNIGHT:]:
            for sq in iterBits(bb):
                piece = pos.pieceBoard[sq]
                if piece != KING:
                    attack = attacksFrom(piece,
                                         sq,
                                         color=us,
                                         blocker=pos.blocker)
                    for m in iterBits(attack & between):
                        yield createMove(sq, m, 0)

        #pawns set-wise
        usPawns = pos.board[us][PAWN]

        emptySquares = ~(pos.blocker) & BB_ALL_SQUARES

        pawnsToPromote = (usPawns
                          & BB_RANK_7) if us == WHITE else (usPawns
                                                            & BB_RANK_2)

        pawnsNotMoved = (usPawns & BB_RANK_2) if us == WHITE else (usPawns
                                                                   & BB_RANK_7)

        pawnsNotPromote = usPawns & (~pawnsToPromote & BB_ALL_SQUARES)

        pawnNormalMoves = shiftBitBoard(pawnsNotPromote,
                                        direction) & emptySquares & between

        for bits in iterBits(pawnNormalMoves):
            yield createMove(bits - direction, bits, NORMAL)

        pawnNotMovedShift = shiftBitBoard(pawnsNotMoved,
                                          direction) & emptySquares
        pawnDoubleMoves = shiftBitBoard(pawnNotMovedShift,
                                        direction) & emptySquares & between

        for bits in iterBits(pawnDoubleMoves):
            yield createMove(bits - 2 * direction, bits, NORMAL)

        #quiet pawn promotions bb
        pawnPromotions = shiftBitBoard(pawnsToPromote,
                                       direction) & emptySquares & between

        for bits in iterBits(pawnPromotions):
            for p in moveFlag[4:]:
                yield createMove(bits - direction, bits, p)
예제 #11
0
def generatePawnMoves(pos):

    #get pawns
    us = pos.color

    direction = N if us == WHITE else S

    enemies = pos.them

    usPawns = pos.board[us][PAWN]

    emptySquares = ~(pos.blocker) & BB_ALL_SQUARES

    pawnsToPromote = (usPawns & BB_RANK_7) if us == WHITE else (usPawns
                                                                & BB_RANK_2)

    pawnsNotMoved = (usPawns & BB_RANK_2) if us == WHITE else (usPawns
                                                               & BB_RANK_7)

    pawnsNotPromote = usPawns & (~pawnsToPromote & BB_ALL_SQUARES)

    pawnNormalMoves = shiftBitBoard(pawnsNotPromote, direction) & emptySquares

    for bits in iterBits(pawnNormalMoves):
        yield createMove(bits - direction, bits, NORMAL)

    pawnNotMovedShift = shiftBitBoard(pawnsNotMoved, direction) & emptySquares
    pawnDoubleMoves = shiftBitBoard(pawnNotMovedShift,
                                    direction) & emptySquares

    for bits in iterBits(pawnDoubleMoves):
        yield createMove(bits - 2 * direction, bits, NORMAL)

    #quiet pawn promotions bb
    pawnPromotions = shiftBitBoard(pawnsToPromote, direction) & emptySquares

    for bits in iterBits(pawnPromotions):
        for p in moveFlag[4:]:
            yield createMove(bits - direction, bits, p)

    #capture pawn moves
    pawnCapturesNE = shiftBitBoard(pawnsNotPromote & BB_NOT_H_FILE,
                                   direction + E) & enemies
    for bits in iterBits(pawnCapturesNE):
        yield createMove(bits - (direction + E), bits, NORMAL)

    pawnCapturesNW = shiftBitBoard(pawnsNotPromote & BB_NOT_A_FILE,
                                   direction + W) & enemies
    for bits in iterBits(pawnCapturesNW):
        yield createMove(bits - (direction + W), bits, NORMAL)

    #capture pawn promotions
    pawnCapturePromoNE = shiftBitBoard(pawnsToPromote & BB_NOT_H_FILE,
                                       direction + E) & enemies
    for bits in iterBits(pawnCapturePromoNE):
        for p in moveFlag[4:]:
            yield createMove(bits - (direction + E), bits, p)

    pawnCapturePromoNW = shiftBitBoard(pawnsToPromote & BB_NOT_A_FILE,
                                       direction + W) & enemies
    for bits in iterBits(pawnCapturePromoNW):
        for p in moveFlag[4:]:
            yield createMove(bits - (direction + W), bits, p)

    if (pos.enpassant != -1):
        pawnsAtEp = attackersTo(pos.board[us], pos.blocker, pos.enpassant,
                                us) & usPawns
        for bits in iterBits(pawnsAtEp):
            yield createMove(bits, pos.enpassant, ENPASSANT)