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)
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
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)
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)
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)
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)
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
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")
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
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)
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)