import java.math.BigInteger; public class Perft { static Boolean OutOfBounds(int move) { if (move < 0) { return true; } if (move > 63) { return true; } return false; } static void PrintMoveNoNL(int starting, int target_square, int tag) { //starting // Print starting if (OutOfBounds(starting)) { System.out.printf("%d", starting); } else { System.out.printf("%c%c", GenConst.SQ_CHAR_X[starting], GenConst.SQ_CHAR_Y[starting]); } // Print target if (OutOfBounds(target_square)) { System.out.printf("%d", target_square); } else { System.out.printf("%c%c", GenConst.SQ_CHAR_X[target_square], GenConst.SQ_CHAR_Y[target_square]); } // Print promotion tag switch (tag) { case GenConst.TAG_BCaptureKnightPromotion: case GenConst.TAG_BKnightPromotion: case GenConst.TAG_WKnightPromotion: case GenConst.TAG_WCaptureKnightPromotion: System.out.printf("n"); break; case GenConst.TAG_BCaptureRookPromotion: case GenConst.TAG_BRookPromotion: case GenConst.TAG_WRookPromotion: case GenConst.TAG_WCaptureRookPromotion: System.out.printf("r"); break; case GenConst.TAG_BCaptureBishopPromotion: case GenConst.TAG_BBishopPromotion: case GenConst.TAG_WBishopPromotion: case GenConst.TAG_WCaptureBishopPromotion: System.out.printf("b"); break; case GenConst.TAG_BCaptureQueenPromotion: case GenConst.TAG_BQueenPromotion: case GenConst.TAG_WQueenPromotion: case GenConst.TAG_WCaptureQueenPromotion: System.out.printf("q"); break; default: break; } } static final int MOVE_STARTING = 0; static final int MOVE_TARGET = 1; static final int MOVE_PIECE = 2; static final int MOVE_TAG = 3; static final int NO_SQUARE = 64; static final int WKS_CASTLE_RIGHTS = 0; static final int WQS_CASTLE_RIGHTS = 1; static final int BKS_CASTLE_RIGHTS = 2; static final int BQS_CASTLE_RIGHTS = 3; static final int PINNED_SQUARE_INDEX = 0; static final int PINNING_PIECE_INDEX = 1; static final BigInteger WKS_EMPTY_BITBOARD = new BigInteger("6917529027641081856"); static final BigInteger WQS_EMPTY_BITBOARD = new BigInteger("1008806316530991104"); static final BigInteger BKS_EMPTY_BITBOARD = new BigInteger("96"); static final BigInteger BQS_EMPTY_BITBOARD = new BigInteger("14"); static final BigInteger RANK_1_BITBOARD = new BigInteger( "18374686479671623680"); static final BigInteger RANK_2_BITBOARD =new BigInteger( "71776119061217280"); static final BigInteger RANK_3_BITBOARD =new BigInteger( "280375465082880"); static final BigInteger RANK_4_BITBOARD =new BigInteger( "1095216660480"); static final BigInteger RANK_5_BITBOARD =new BigInteger( "4278190080"); static final BigInteger RANK_6_BITBOARD =new BigInteger( "16711680"); static final BigInteger RANK_7_BITBOARD =new BigInteger( "65280"); static final BigInteger RANK_8_BITBOARD =new BigInteger( "255"); static final BigInteger MAX_ULONG = new BigInteger("18446744073709551615"); static final BigInteger MAGIC = new BigInteger("285870213051386505"); static final int[] DEBRUIJN64 = { 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, 38, 32, 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43, 31, 22, 10, 45, 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63 }; static int BitScanForward(BigInteger bitboard) { for (int i = 0; i < 64; i++) { if (bitboard.testBit(i)) { return i; } } throw new AssertionError("Bitscanforward: bit not found"); //BigInteger xorResult = bitboard.xor(bitboard.subtract(BigInteger.ONE)); //BigInteger multiplied = xorResult.multiply(MAGIC); //int index = multiplied.shiftRight(58).intValue(); //return DEBRUIJN64[index]; } static boolean isNotZero(BigInteger bitboard) { return bitboard.signum() != 0; } static boolean isZero(BigInteger bitboard) { return bitboard.signum() == 0; } static BigInteger removeBit(BigInteger bitboard) { return bitboard.and(bitboard.subtract(BigInteger.ONE)); } static void printMoveInfo(int startingSquare, int targetSquare, int tag, int piece) { Pr.println("\n Move Info:"); Pr.print(" Starting Square: "); Pr.printInt(startingSquare); Pr.print(" "); Pr.printSquareLn(startingSquare); Pr.print(" Target Square: "); Pr.printInt(targetSquare); Pr.print(" "); Pr.printSquareLn(targetSquare); Pr.print(" Tag: "); Pr.printIntLn(tag); Pr.print(" Piece: "); Pr.printIntLn(piece); } static int makeMove(int piece, int tag, int startingSquare, int targetSquare) { Pr.println("___make move____ piece: " + piece + " tag: " + tag + " startingSquare: " + startingSquare + " targetSquare: " + targetSquare); assert piece >= GenConst.WP && piece <= GenConst.BK : "invalid piece: " + piece; assert startingSquare >= 0 && startingSquare < 64 : "invalid starting square: " + startingSquare; assert targetSquare >= 0 && targetSquare < 64 : "invalid target square: " + targetSquare; // printMoveInfo(startingSquare, targetSquare, tag, piece); int captureIndex = -1; Board.is_white_global = !Board.is_white_global; switch (tag) { case GenConst.TAG_NONE: //none case GenConst.TAG_CHECK: //check Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_CAPTURE: //capture case GenConst.TAG_CHECK_CAPTURE: //check cap Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); if (piece >= GenConst.WP && piece <= GenConst.WK) { for (int i = GenConst.BP; i <= GenConst.BK; ++i) { if (targetSquare == 47) { Pr.println(" board array: " + Board.bitboard_array_global[i]); } if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } assert captureIndex >= 0 && captureIndex <= 11 : "invalid capture index, capture"; if (captureIndex < 0 || captureIndex > 11) { Pr.println("Invalid capture index: " + captureIndex); } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); } else //is black { for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } assert captureIndex >= 0 && captureIndex <= 11 : "invalid capture index, capture"; Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); } Board.ep = NO_SQUARE; break; case GenConst.TAG_WHITEEP: //white ep //move piece Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[targetSquare + 8].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BLACKEP: //black ep Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[targetSquare - 8].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_WCASTLEKS: //WKS //white king Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.G1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.E1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.F1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.H1].not()); Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_WCASTLEQS: //WQS Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.C1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.E1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.D1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.A1].not()); Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_BCASTLEKS: //BKS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.G8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.E8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.F8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.H8].not()); Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_BCASTLEQS: //BQS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.C8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.E8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.D8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.A8].not()); Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_BKnightPromotion: //BNPr Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BBishopPromotion: //BBPr Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BQueenPromotion: //BQPr Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BRookPromotion: //BRPr Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 12: //WNPr Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 13: //WBPr Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 14: //WQPr Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 15: //WRPr Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 16: //BNPrCAP Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 17: //BBPrCAP Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 18: //BQPrCAP Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 19: //BRPrCAP Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 20: //WNPrCAP Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 21: //WBPrCAP Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 22: //WQPrCAP Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 23: //WRPrCAP Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; i++) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 24: //WDouble Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = targetSquare + 8; break; case 25: //BDouble Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = targetSquare - 8; break; } if (piece == GenConst.WK) { Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; } else if (piece == GenConst.BK) { Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; } else if (piece == GenConst.WR) { if (Board.castle_rights_global[WKS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.H1])))) { Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; } } if (Board.castle_rights_global[WQS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.A1])))) { Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; } } } else if (piece == GenConst.BR) { if (Board.castle_rights_global[BKS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.H8])))) { Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; } } if (Board.castle_rights_global[BQS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.A8])))) { Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; } } } return captureIndex; } static void unmakeMove(int piece, int tag, int startingSquare, int targetSquare, int captureIndex) { Pr.println("___unmake move____ piece: " + piece + " tag: " + tag + " startingSquare: " + startingSquare + " targetSquare: " + targetSquare + " captureIndex: " + captureIndex); Board.is_white_global = !Board.is_white_global; switch (tag) { case GenConst.TAG_NONE: //none case GenConst.TAG_CHECK: //check Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case GenConst.TAG_CAPTURE: //capture case GenConst.TAG_CHECK_CAPTURE: //check cap assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Pr.println("bp capture before: " + Board.bitboard_array_global[GenConst.BP]); Board.bitboard_array_global[captureIndex] = Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); Pr.println("bp capture after: " + Board.bitboard_array_global[GenConst.BP]); break; case GenConst.TAG_WHITEEP: //white ep //move piece Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[targetSquare + 8]); break; case GenConst.TAG_BLACKEP: //black ep Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[targetSquare - 8]); break; case GenConst.TAG_WCASTLEKS: //WKS //white king Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.E1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.G1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.H1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.F1].not()); break; case GenConst.TAG_WCASTLEQS: //WQS Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.E1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.C1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.A1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.D1].not()); break; case GenConst.TAG_BCASTLEKS: //BKS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.E8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.G8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.H8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.F8].not()); break; case GenConst.TAG_BCASTLEQS: //BQS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.E8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.C8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.A8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.D8].not()); break; case GenConst.TAG_BKnightPromotion: //BNPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case GenConst.TAG_BBishopPromotion: //BBPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case GenConst.TAG_BQueenPromotion: //BQPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case GenConst.TAG_BRookPromotion: //BRPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 12: //WNPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 13: //WBPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 14: //WQPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 15: //WRPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 16: //BNPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 17: //BBPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 18: //BQPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 19: //BRPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 20: //WNPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 21: //WBPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 22: //WQPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 23: //WRPrCAP assert captureIndex != -1 : "invalid capture index"; Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 24: //WDouble Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 25: //BDouble Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); break; } } static int getMoves(int[][] move_list) { Pr.println(" getMoves:"); int move_count = 0; //#region Moves //Move generating variables BigInteger WHITE_OCCUPANCIES = Board.bitboard_array_global[0] .or(Board.bitboard_array_global[1]) .or(Board.bitboard_array_global[2]) .or(Board.bitboard_array_global[3]) .or(Board.bitboard_array_global[4]) .or(Board.bitboard_array_global[5]); BigInteger BLACK_OCCUPANCIES = Board.bitboard_array_global[6] .or(Board.bitboard_array_global[7]) .or(Board.bitboard_array_global[8]) .or(Board.bitboard_array_global[9]) .or(Board.bitboard_array_global[10]) .or(Board.bitboard_array_global[11]); BigInteger COMBINED_OCCUPANCIES = WHITE_OCCUPANCIES.or(BLACK_OCCUPANCIES); BigInteger EMPTY_OCCUPANCIES = COMBINED_OCCUPANCIES.not(); BigInteger temp_bitboard, temp_pin_bitboard, temp_attack, temp_empty, temp_captures; BigInteger check_bitboard = new BigInteger("0"); int starting_square = NO_SQUARE, target_square = NO_SQUARE; int[][] pinArray = { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, }; int pinNumber = 0; Pr.println(" -variables declared"); if (Board.is_white_global == true) { Pr.println(" white to play"); int whiteKingCheckCount = 0; int whiteKingPosition = BitScanForward(Board.bitboard_array_global[GenConst.WK]); Pr.print(" white king position: "); Pr.printSquareLn(whiteKingPosition); //#region White checks and pins //pawns temp_bitboard = Board.bitboard_array_global[GenConst.BP].and(MoveConstants.WHITE_PAWN_ATTACKS[whiteKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int pawn_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[pawn_square]; } whiteKingCheckCount++; } //knights temp_bitboard = Board.bitboard_array_global[GenConst.BN].and(MoveConstants.KNIGHT_ATTACKS[whiteKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int knight_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[knight_square]; } whiteKingCheckCount++; } //bishops BigInteger bishopAttacksChecks = MoveUtils.GetBishopMovesSeparate(BLACK_OCCUPANCIES, whiteKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.BB].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.BQ].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //rook BigInteger rook_attacks = MoveUtils.GetRookMovesSeparate(BLACK_OCCUPANCIES, whiteKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.BR].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.BQ].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } Pr.println(" -pins and checks complete: "); Pr.print(" white king check count: "); Pr.printIntLn(whiteKingCheckCount); Pr.print(" pin count: "); Pr.printIntLn(pinNumber); Pr.println(" _____________"); //#endregion BigInteger occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES.and(Board.bitboard_array_global[GenConst.WK].not()); int wKingMoveCount = 0; temp_attack = MoveConstants.KING_ATTACKS[whiteKingPosition]; temp_empty = temp_attack.and(EMPTY_OCCUPANCIES); while (temp_empty.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_empty); temp_empty = temp_empty.and(temp_empty.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.BP].and(MoveConstants.WHITE_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = whiteKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; wKingMoveCount++; } //captures temp_captures = temp_attack.and(BLACK_OCCUPANCIES); while (temp_captures.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_captures); temp_captures = temp_captures.and(temp_captures.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.BP].and(MoveConstants.WHITE_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = whiteKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; wKingMoveCount++; } Pr.print(" white king move count: "); Pr.printIntLn(wKingMoveCount); Pr.println(" _____________"); if (whiteKingCheckCount < 2) { if (whiteKingCheckCount == 0) { check_bitboard = MAX_ULONG; } //#region White castling if (whiteKingCheckCount == 0) { if (Board.castle_rights_global[WKS_CASTLE_RIGHTS] == true) { if (whiteKingPosition == GenConst.E1) //king on e1 { if (isNotZero(WKS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if (isNotZero(Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.H1])) == false) //rook on h1 { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.F1, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.G1, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E1; move_list[move_count][MOVE_TARGET] = GenConst.G1; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCASTLEKS; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; } } } } } } if (Board.castle_rights_global[WQS_CASTLE_RIGHTS] == true) { if (whiteKingPosition == GenConst.E1) //king on e1 { if (isNotZero(WQS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if ((isNotZero(Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.A1]))) == true) //rook on h1 { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.C1, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.D1, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E1; move_list[move_count][MOVE_TARGET] = GenConst.C1; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCASTLEQS; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; } } } } } } } //#endregion //#region White knight moves Pr.println(" -white knight moves: "); temp_bitboard = Board.bitboard_array_global[GenConst.WN]; Pr.print(" white knight bitboard: "); Pr.printBigIntegerLn(temp_bitboard); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); //removes the knight from that square to not infinitely loop Pr.println("\n knight on square: " + starting_square); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //gets knight captures Pr.println(" knight captures: " + temp_attack); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WN; move_count++; } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); Pr.println(" knight regular moves: " + temp_attack); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WN; move_count++; } } //#endregion //#region White pawn moves Pr.println(" _____________"); Pr.println(" movecount: " + move_count); temp_bitboard = Board.bitboard_array_global[GenConst.WP]; Pr.println(" -white pawn moves: "); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); Pr.println("\n pawn on square: " + starting_square); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } //#region pawn forward if (isZero(MoveConstants.SQUARE_BBS[starting_square - 8].and(COMBINED_OCCUPANCIES)) == true) //if up one square is empty { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square - 8].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or check { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_7_BITBOARD))) //if promotion { Pr.println(" pawn promotion forward!"); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else { Pr.println(" pawn forward one"); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } if ((isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_2_BITBOARD))) == true) //if on rank 2 { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square - 16].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or { if (isZero(MoveConstants.SQUARE_BBS[starting_square - 16].and(COMBINED_OCCUPANCIES)) == true) //if up two squares and one square are empty { Pr.println(" pawn forward two"); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 16; move_list[move_count][MOVE_TAG] = GenConst.TAG_DoublePawnWhite; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } } } //#endregion //#region pawn attacks temp_attack = ((MoveConstants.WHITE_PAWN_ATTACKS[starting_square].and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //if black piece diagonal to pawn Pr.println(" pawn attacks: " + temp_attack); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_7_BITBOARD)) == true) //if promotion { Pr.println(" pawn promotion attack!"); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureKnightPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else { Pr.println(" add pawn attack move " + starting_square + " to " + target_square); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_5_BITBOARD))) { // check rank for ep if (Board.ep != NO_SQUARE) { if (isNotZero(MoveConstants.WHITE_PAWN_ATTACKS[starting_square] .and(MoveConstants.SQUARE_BBS[Board.ep]) .and(check_bitboard) .and(temp_pin_bitboard))) { if (isZero(Board.bitboard_array_global[GenConst.WK].and(RANK_5_BITBOARD))) { // if no king on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_WHITEEP; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else if (isZero(Board.bitboard_array_global[GenConst.BR].and(RANK_5_BITBOARD)) && isZero(Board.bitboard_array_global[GenConst.BQ].and(RANK_5_BITBOARD))) { // if no b rook or queen on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_WHITEEP; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else { // wk and br or bq on rank 5 BigInteger occupancyWithoutEPPawns = COMBINED_OCCUPANCIES.and(MoveConstants.SQUARE_BBS[starting_square].not()); occupancyWithoutEPPawns = occupancyWithoutEPPawns.and(MoveConstants.SQUARE_BBS[Board.ep + 8].not()); BigInteger rookAttacksFromKing = MoveUtils.GetRookMovesSeparate(occupancyWithoutEPPawns, whiteKingPosition); if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.BR]))) { if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.BQ]))) { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_WHITEEP; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } } } } } //#endregion } //#endregion Pr.println(" -after pawns"); //#region White rook moves temp_bitboard = Board.bitboard_array_global[GenConst.WR]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); temp_attack = ((rookAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WR; move_count++; } temp_attack = ((rookAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WR; move_count++; } } //#endregion Pr.println(" -after rooks"); //#region White bishop moves //Pr.println("\nwhite bishop"); temp_bitboard = Board.bitboard_array_global[GenConst.WB]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } //Pr.println("get bishop attacks"); BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square); //Pr.println("bishop attacks"); //Pr.printBigIntegerLn(bishopAttacks); temp_attack = ((bishopAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WB; move_count++; } temp_attack = ((bishopAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WB; move_count++; } } //#endregion Pr.println(" -after bishop"); //#region White queen moves Pr.println("______________"); Pr.println(" white queen:"); temp_bitboard = Board.bitboard_array_global[GenConst.WQ]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); Pr.println("\n queen on square: " + starting_square); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger queenAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); Pr.println("\n queen attacks rook: " + queenAttacks); queenAttacks = queenAttacks.or(MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square)); Pr.println("\n queen attacks combined: " + queenAttacks); temp_attack = ((queenAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); Pr.println("\n queen attacks captures: " + temp_attack); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WQ; move_count++; Pr.println(" add queen attack capture " + starting_square + " to " + target_square); } temp_attack = ((queenAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); Pr.println("\n queen regular moves: " + temp_attack); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WQ; move_count++; Pr.println(" add queen move " + starting_square + " to " + target_square); } } //#endregion Pr.println(" -after queen"); } } else //black move { int blackKingCheckCount = 0; int blackKingPosition = BitScanForward(Board.bitboard_array_global[GenConst.BK]); // Pr.print(" black king position: "); // Pr.printIntLn(blackKingPosition); //#region black checks and pins //pawns temp_bitboard = Board.bitboard_array_global[GenConst.WP].and(MoveConstants.BLACK_PAWN_ATTACKS[blackKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) //if there is pawn attacking king { int pawn_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[pawn_square]; } blackKingCheckCount++; } //knights temp_bitboard = Board.bitboard_array_global[GenConst.WN].and(MoveConstants.KNIGHT_ATTACKS[blackKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int knight_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[knight_square]; } blackKingCheckCount++; } //bishops BigInteger bishopAttacksChecks = MoveUtils.GetBishopMovesSeparate(WHITE_OCCUPANCIES, blackKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.WB].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(BLACK_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.WQ].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(BLACK_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //rook BigInteger rook_attacks = MoveUtils.GetRookMovesSeparate(WHITE_OCCUPANCIES, blackKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.WR].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(BLACK_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.WQ].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //#endregion BigInteger occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES.and(Board.bitboard_array_global[GenConst.WK].not()); temp_attack = MoveConstants.KING_ATTACKS[blackKingPosition]; temp_empty = temp_attack.and(EMPTY_OCCUPANCIES); while (temp_empty.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_empty); temp_empty = temp_empty.and(temp_empty.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.WP].and(MoveConstants.BLACK_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = blackKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } //captures temp_captures = temp_attack.and(WHITE_OCCUPANCIES); while (temp_captures.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_captures); temp_captures = temp_captures.and(temp_captures.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.WP].and(MoveConstants.BLACK_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = blackKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } if (blackKingCheckCount < 2) { if (blackKingCheckCount == 0) { check_bitboard = MAX_ULONG; } //#region Black castling if (blackKingCheckCount == 0) { if (Board.castle_rights_global[BKS_CASTLE_RIGHTS] == true) { if (blackKingPosition == GenConst.E8) //king on e1 { if (isNotZero(BKS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if (isNotZero(Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.H8])) == false) //rook on h8 { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.F8, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.G8, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E8; move_list[move_count][MOVE_TARGET] = GenConst.G8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCASTLEKS; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } } } } } } if (Board.castle_rights_global[BQS_CASTLE_RIGHTS] == true) { if (blackKingPosition == GenConst.E8) //king on e1 { if (isNotZero(BQS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if ((isNotZero(Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.A8]))) == true) //rook on h1 { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.C8, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.D8, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E8; move_list[move_count][MOVE_TARGET] = GenConst.C8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCASTLEQS; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } } } } } } } //#endregion //#region Black knight moves temp_bitboard = Board.bitboard_array_global[GenConst.BN]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); //removes the knight from that square to not infinitely loop temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(WHITE_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //gets knight captures while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BN; move_count++; } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BN; move_count++; } } //#endregion //#region Black pawn moves temp_bitboard = Board.bitboard_array_global[GenConst.BP]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } //#region pawn forward if (isZero(MoveConstants.SQUARE_BBS[starting_square + 8].and(COMBINED_OCCUPANCIES)) == true) //if up one square is empty { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square + 8].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or check { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_2_BITBOARD))) //if promotion { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } if ((isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_7_BITBOARD))) == true) //if on rank 7 { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square + 16].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or { if (isZero(MoveConstants.SQUARE_BBS[starting_square + 16].and(COMBINED_OCCUPANCIES)) == true) //if up two squares and one square are empty { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 16; move_list[move_count][MOVE_TAG] = GenConst.TAG_DoublePawnBlack; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } } } //#endregion //#region pawn attacks temp_attack = ((MoveConstants.BLACK_PAWN_ATTACKS[starting_square].and(WHITE_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //if black piece diagonal to pawn while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_2_BITBOARD)) == true) //if promotion { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureKnightPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_4_BITBOARD))) { // check rank for ep if (Board.ep != NO_SQUARE) { if (isNotZero(MoveConstants.BLACK_PAWN_ATTACKS[starting_square] .and(MoveConstants.SQUARE_BBS[Board.ep]) .and(check_bitboard) .and(temp_pin_bitboard))) { if (isZero(Board.bitboard_array_global[GenConst.WK].and(RANK_4_BITBOARD))) { // if no king on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_BLACKEP; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else if (isZero(Board.bitboard_array_global[GenConst.WR].and(RANK_4_BITBOARD)) && isZero(Board.bitboard_array_global[GenConst.WQ].and(RANK_4_BITBOARD))) { // if no b rook or queen on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_BLACKEP; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else { // wk and br or bq on rank 5 BigInteger occupancyWithoutEPPawns = COMBINED_OCCUPANCIES.and(MoveConstants.SQUARE_BBS[starting_square].not()); occupancyWithoutEPPawns = occupancyWithoutEPPawns.and(MoveConstants.SQUARE_BBS[Board.ep - 8].not()); BigInteger rookAttacksFromKing = MoveUtils.GetRookMovesSeparate(occupancyWithoutEPPawns, blackKingPosition); if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.WR]))) { if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.WQ]))) { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_BLACKEP; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } } } } } //#endregion } //#endregion //#region Black rook moves temp_bitboard = Board.bitboard_array_global[GenConst.BR]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); // Pr.print(" rook square: "); // Pr.printIntLn(starting_square); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); // Pr.print("rook attacks:"); // Pr.printBigIntegerLn(rookAttacks); temp_attack = ((rookAttacks.and(WHITE_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); // Pr.print("against white:"); // Pr.printBigIntegerLn(temp_attack); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BR; move_count++; } temp_attack = ((rookAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); // Pr.print("against empty:"); // Pr.printBigIntegerLn(temp_attack); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BR; move_count++; } } //#endregion //#region Black bishop moves temp_bitboard = Board.bitboard_array_global[GenConst.BB]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square); temp_attack = ((bishopAttacks.and(WHITE_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BB; move_count++; } temp_attack = ((bishopAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BB; move_count++; } } //#endregion //#region Black queen moves temp_bitboard = Board.bitboard_array_global[GenConst.BQ]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger queenAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); queenAttacks = queenAttacks.or(MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square)); temp_attack = ((queenAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BQ; move_count++; } temp_attack = ((queenAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BQ; move_count++; } } //#endregion } } //#endregion Pr.println("-generated moves, count: " + move_count); return move_count; } static int PerftInlineDebug(int depth, int ply) { if (depth == 0) { return 1; } BigInteger[] bitboard_array_copy = new BigInteger[12]; for (int i = 0; i < 12; i++) { bitboard_array_copy[i] = Board.bitboard_array_global[i]; } int[][] move_list = new int[250][4]; int move_count = getMoves(move_list); // Pr.print("Move count: "); // Pr.printIntLn(move_count); //if (depth == 1) //{ //return move_count; //} int nodes = 0; int priorNodes; int copyEp = Board.ep; boolean[] copy_castle = { Board.castle_rights_global[0], Board.castle_rights_global[1], Board.castle_rights_global[2], Board.castle_rights_global[3], }; Pr.println(" -Looping through moves"); for (int move_index = 0; move_index < move_count; move_index++) { int startingSquare = move_list[move_index][MOVE_STARTING]; int targetSquare = move_list[move_index][MOVE_TARGET]; int piece = move_list[move_index][MOVE_PIECE]; int tag = move_list[move_index][MOVE_TAG]; int captureIndex = makeMove(piece, tag, startingSquare, targetSquare); priorNodes = nodes; nodes += PerftInlineDebug(depth - 1, ply + 1); unmakeMove(piece, tag, startingSquare, targetSquare, captureIndex); Board.castle_rights_global[0] = copy_castle[0]; Board.castle_rights_global[1] = copy_castle[1]; Board.castle_rights_global[2] = copy_castle[2]; Board.castle_rights_global[3] = copy_castle[3]; Board.ep = copyEp; for (int i = 0; i < 12; i++) { Pr.println("i: " + i + " bitboard: " + Board.bitboard_array_global[i]); assert Board.bitboard_array_global[i] == bitboard_array_copy[i] : "Bitboards are not the same!"; } if (ply == 0) { //Pr.printInt(startingSquare); //Pr.printInt(targetSquare); //Pr.printInt(tag); PrintMoveNoNL(startingSquare, targetSquare, tag); System.out.printf(": %d\n", nodes - priorNodes); } } return nodes; } static int PerftInlineGlobal(int depth, int ply) { if (depth == 0) { return 1; } int[][] move_list = new int[250][4]; int move_count = 0; //Move generating variables BigInteger WHITE_OCCUPANCIES = Board.bitboard_array_global[0] .or(Board.bitboard_array_global[1]) .or(Board.bitboard_array_global[2]) .or(Board.bitboard_array_global[3]) .or(Board.bitboard_array_global[4]) .or(Board.bitboard_array_global[5]); BigInteger BLACK_OCCUPANCIES = Board.bitboard_array_global[6] .or(Board.bitboard_array_global[7]) .or(Board.bitboard_array_global[8]) .or(Board.bitboard_array_global[9]) .or(Board.bitboard_array_global[10]) .or(Board.bitboard_array_global[11]); BigInteger COMBINED_OCCUPANCIES = WHITE_OCCUPANCIES.or(BLACK_OCCUPANCIES); BigInteger EMPTY_OCCUPANCIES = COMBINED_OCCUPANCIES.not(); BigInteger temp_bitboard, temp_pin_bitboard, temp_attack, temp_empty, temp_captures; BigInteger check_bitboard = new BigInteger("0"); int starting_square = NO_SQUARE, target_square = NO_SQUARE; int[][] pinArray = { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, }; int pinNumber = 0; if (Board.is_white_global == true) { int whiteKingCheckCount = 0; int whiteKingPosition = BitScanForward(Board.bitboard_array_global[GenConst.WK]); //#region White checks and pins //pawns temp_bitboard = Board.bitboard_array_global[GenConst.BP].and(MoveConstants.WHITE_PAWN_ATTACKS[whiteKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int pawn_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[pawn_square]; } whiteKingCheckCount++; } //knights temp_bitboard = Board.bitboard_array_global[GenConst.BN].and(MoveConstants.KNIGHT_ATTACKS[whiteKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int knight_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[knight_square]; } whiteKingCheckCount++; } //bishops BigInteger bishopAttacksChecks = MoveUtils.GetBishopMovesSeparate(BLACK_OCCUPANCIES, whiteKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.BB].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.BQ].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //rook BigInteger rook_attacks = MoveUtils.GetRookMovesSeparate(BLACK_OCCUPANCIES, whiteKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.BR].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.BQ].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; } whiteKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //#endregion BigInteger occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES.and(Board.bitboard_array_global[GenConst.WK].not()); temp_attack = MoveConstants.KING_ATTACKS[whiteKingPosition]; temp_empty = temp_attack.and(EMPTY_OCCUPANCIES); while (temp_empty.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_empty); temp_empty = temp_empty.and(temp_empty.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.BP].and(MoveConstants.WHITE_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = whiteKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; } //captures temp_captures = temp_attack.and(BLACK_OCCUPANCIES); while (temp_captures.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_captures); temp_captures = temp_captures.and(temp_captures.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.BP].and(MoveConstants.WHITE_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.BR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.BQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = whiteKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; } if (whiteKingCheckCount < 2) { if (whiteKingCheckCount == 0) { check_bitboard = MAX_ULONG; } //#region White castling if (whiteKingCheckCount == 0) { if (Board.castle_rights_global[WKS_CASTLE_RIGHTS] == true) { if (whiteKingPosition == GenConst.E1) //king on e1 { if (isNotZero(WKS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if (isNotZero(Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.H1])) == false) //rook on h1 { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.F1, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.G1, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E1; move_list[move_count][MOVE_TARGET] = GenConst.G1; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCASTLEKS; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; } } } } } } if (Board.castle_rights_global[WQS_CASTLE_RIGHTS] == true) { if (whiteKingPosition == GenConst.E1) //king on e1 { if (isNotZero(WQS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if ((isNotZero(Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.A1]))) == true) //rook on h1 { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.C1, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_Black_Global(GenConst.D1, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E1; move_list[move_count][MOVE_TARGET] = GenConst.C1; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCASTLEQS; move_list[move_count][MOVE_PIECE] = GenConst.WK; move_count++; } } } } } } } //#endregion //#region White knight moves temp_bitboard = Board.bitboard_array_global[GenConst.WN]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); //removes the knight from that square to not infinitely loop temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //gets knight captures while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WN; move_count++; } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WN; move_count++; } } //#endregion //#region White pawn moves temp_bitboard = Board.bitboard_array_global[GenConst.WP]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } //#region pawn forward if (isZero(MoveConstants.SQUARE_BBS[starting_square - 8].and(COMBINED_OCCUPANCIES)) == true) //if up one square is empty { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square - 8].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or check { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_7_BITBOARD))) //if promotion { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_WBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } if ((isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_2_BITBOARD))) == true) //if on rank 2 { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square - 16].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or { if (isZero(MoveConstants.SQUARE_BBS[starting_square - 16].and(COMBINED_OCCUPANCIES)) == true) //if up two squares and one square are empty { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 16; move_list[move_count][MOVE_TAG] = GenConst.TAG_DoublePawnWhite; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } } } //#endregion //#region pawn attacks temp_attack = ((MoveConstants.WHITE_PAWN_ATTACKS[starting_square].and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //if black piece diagonal to pawn while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_7_BITBOARD)) == true) //if promotion { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_WCaptureKnightPromotion; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_5_BITBOARD))) { // check rank for ep if (Board.ep != NO_SQUARE) { if (isNotZero(MoveConstants.WHITE_PAWN_ATTACKS[starting_square] .and(MoveConstants.SQUARE_BBS[Board.ep]) .and(check_bitboard) .and(temp_pin_bitboard))) { if (isZero(Board.bitboard_array_global[GenConst.WK].and(RANK_5_BITBOARD))) { // if no king on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_WHITEEP; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else if (isZero(Board.bitboard_array_global[GenConst.BR].and(RANK_5_BITBOARD)) && isZero(Board.bitboard_array_global[GenConst.BQ].and(RANK_5_BITBOARD))) { // if no b rook or queen on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_WHITEEP; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } else { // wk and br or bq on rank 5 BigInteger occupancyWithoutEPPawns = COMBINED_OCCUPANCIES.and(MoveConstants.SQUARE_BBS[starting_square].not()); occupancyWithoutEPPawns = occupancyWithoutEPPawns.and(MoveConstants.SQUARE_BBS[Board.ep + 8].not()); BigInteger rookAttacksFromKing = MoveUtils.GetRookMovesSeparate(occupancyWithoutEPPawns, whiteKingPosition); if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.BR]))) { if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.BQ]))) { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_WHITEEP; move_list[move_count][MOVE_PIECE] = GenConst.WP; move_count++; } } } } } } //#endregion } //#endregion //#region White rook moves temp_bitboard = Board.bitboard_array_global[GenConst.WR]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); temp_attack = ((rookAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WR; move_count++; } temp_attack = ((rookAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WR; move_count++; } } //#endregion //#region White bishop moves //Pr.println("\nwhite bishop"); temp_bitboard = Board.bitboard_array_global[GenConst.WB]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } //Pr.println("get bishop attacks"); BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square); //Pr.println("bishop attacks"); //Pr.printBigIntegerLn(bishopAttacks); temp_attack = ((bishopAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WB; move_count++; } temp_attack = ((bishopAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WB; move_count++; } } //#endregion //#region White queen moves temp_bitboard = Board.bitboard_array_global[GenConst.WQ]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger queenAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); queenAttacks = queenAttacks.and(MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square)); temp_attack = ((queenAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.WQ; move_count++; } temp_attack = ((queenAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.WQ; move_count++; } } //#endregion } } else //black move { int blackKingCheckCount = 0; int blackKingPosition = BitScanForward(Board.bitboard_array_global[GenConst.BK]); //#region black checks and pins //pawns temp_bitboard = Board.bitboard_array_global[GenConst.WP].and(MoveConstants.BLACK_PAWN_ATTACKS[blackKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) //if there is pawn attacking king { int pawn_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[pawn_square]; } blackKingCheckCount++; } //knights temp_bitboard = Board.bitboard_array_global[GenConst.WN].and(MoveConstants.KNIGHT_ATTACKS[blackKingPosition]); if (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int knight_square = BitScanForward(temp_bitboard); if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = MoveConstants.SQUARE_BBS[knight_square]; } blackKingCheckCount++; } //bishops BigInteger bishopAttacksChecks = MoveUtils.GetBishopMovesSeparate(WHITE_OCCUPANCIES, blackKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.WB].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(BLACK_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.WQ].and(bishopAttacksChecks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(BLACK_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //rook BigInteger rook_attacks = MoveUtils.GetRookMovesSeparate(WHITE_OCCUPANCIES, blackKingPosition); temp_bitboard = Board.bitboard_array_global[GenConst.WR].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(BLACK_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //queen temp_bitboard = Board.bitboard_array_global[GenConst.WQ].and(rook_attacks); while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { int piece_square = BitScanForward(temp_bitboard); temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square].and(WHITE_OCCUPANCIES); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { if (check_bitboard.compareTo(BigInteger.ZERO) != 0) { check_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; } blackKingCheckCount++; } else { int pinned_square = BitScanForward(temp_pin_bitboard); temp_pin_bitboard = temp_pin_bitboard.and(temp_pin_bitboard.subtract(BigInteger.ONE)); if (temp_pin_bitboard.compareTo(BigInteger.ZERO) != 0) { pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber++; } } temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); } //#endregion BigInteger occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES.and(Board.bitboard_array_global[GenConst.WK].not()); temp_attack = MoveConstants.KING_ATTACKS[blackKingPosition]; temp_empty = temp_attack.and(EMPTY_OCCUPANCIES); while (temp_empty.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_empty); temp_empty = temp_empty.and(temp_empty.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.WP].and(MoveConstants.BLACK_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = blackKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } //captures temp_captures = temp_attack.and(BLACK_OCCUPANCIES); while (temp_captures.signum() != 0) // Using BigInteger's signum() to check if it's not 0 { target_square = BitScanForward(temp_captures); temp_captures = temp_captures.and(temp_captures.subtract(BigInteger.ONE)); // Using BigInteger's subtract and and if (Board.bitboard_array_global[GenConst.WP].and(MoveConstants.BLACK_PAWN_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WN].and(MoveConstants.KNIGHT_ATTACKS[target_square]).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WK].and(MoveConstants.KING_ATTACKS[target_square]).signum() != 0) { continue; } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WB].and(bishopAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(bishopAttacks).signum() != 0) { continue; } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(occupanciesWithoutWhiteKing, target_square); if (Board.bitboard_array_global[GenConst.WR].and(rookAttacks).signum() != 0) { continue; } if (Board.bitboard_array_global[GenConst.WQ].and(rookAttacks).signum() != 0) { continue; } move_list[move_count][MOVE_STARTING] = blackKingPosition; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } if (blackKingCheckCount < 2) { if (blackKingCheckCount == 0) { check_bitboard = MAX_ULONG; } //#region Black castling if (blackKingCheckCount == 0) { if (Board.castle_rights_global[BKS_CASTLE_RIGHTS] == true) { if (blackKingPosition == GenConst.E8) //king on e1 { if (isNotZero(BKS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if (isNotZero(Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.H8])) == false) //rook on h8 { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.F8, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.G8, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E8; move_list[move_count][MOVE_TARGET] = GenConst.G8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCASTLEKS; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } } } } } } if (Board.castle_rights_global[BQS_CASTLE_RIGHTS] == true) { if (blackKingPosition == GenConst.E8) //king on e1 { if (isNotZero(BQS_EMPTY_BITBOARD.and(COMBINED_OCCUPANCIES)) == false) //f1 and g1 empty { if ((isNotZero(Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.A8]))) == true) //rook on h1 { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.C8, COMBINED_OCCUPANCIES) == false) { if (MoveUtils.Is_Square_Attacked_By_White_Global(GenConst.D8, COMBINED_OCCUPANCIES) == false) { move_list[move_count][MOVE_STARTING] = GenConst.E8; move_list[move_count][MOVE_TARGET] = GenConst.C8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCASTLEQS; move_list[move_count][MOVE_PIECE] = GenConst.BK; move_count++; } } } } } } } //#endregion //#region Black knight moves temp_bitboard = Board.bitboard_array_global[GenConst.BN]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); //removes the knight from that square to not infinitely loop temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(WHITE_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //gets knight captures while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BN; move_count++; } temp_attack = ((MoveConstants.KNIGHT_ATTACKS[starting_square].and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BN; move_count++; } } //#endregion //#region Black pawn moves temp_bitboard = Board.bitboard_array_global[GenConst.BP]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } //#region pawn forward if (isZero(MoveConstants.SQUARE_BBS[starting_square + 8].and(COMBINED_OCCUPANCIES)) == true) //if up one square is empty { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square + 8].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or check { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_2_BITBOARD))) //if promotion { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_BBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square + 8; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } if ((isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_7_BITBOARD))) == true) //if on rank 7 { if (isNotZero(MoveConstants.SQUARE_BBS[starting_square + 16].and(check_bitboard).and(temp_pin_bitboard)) == true) //if not pinned or { if (isZero(MoveConstants.SQUARE_BBS[starting_square + 16].and(COMBINED_OCCUPANCIES)) == true) //if up two squares and one square are empty { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = starting_square - 16; move_list[move_count][MOVE_TAG] = GenConst.TAG_DoublePawnBlack; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } } } //#endregion //#region pawn attacks temp_attack = ((MoveConstants.BLACK_PAWN_ATTACKS[starting_square].and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); //if black piece diagonal to pawn while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_2_BITBOARD)) == true) //if promotion { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureQueenPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureRookPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureBishopPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_BCaptureKnightPromotion; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } if (isNotZero(MoveConstants.SQUARE_BBS[starting_square].and(RANK_4_BITBOARD))) { // check rank for ep if (Board.ep != NO_SQUARE) { if (isNotZero(MoveConstants.BLACK_PAWN_ATTACKS[starting_square] .and(MoveConstants.SQUARE_BBS[Board.ep]) .and(check_bitboard) .and(temp_pin_bitboard))) { if (isZero(Board.bitboard_array_global[GenConst.WK].and(RANK_5_BITBOARD))) { // if no king on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_BLACKEP; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else if (isZero(Board.bitboard_array_global[GenConst.WR].and(RANK_5_BITBOARD)) && isZero(Board.bitboard_array_global[GenConst.WQ].and(RANK_5_BITBOARD))) { // if no b rook or queen on rank 5 move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_BLACKEP; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } else { // wk and br or bq on rank 5 BigInteger occupancyWithoutEPPawns = COMBINED_OCCUPANCIES.and(MoveConstants.SQUARE_BBS[starting_square].not()); occupancyWithoutEPPawns = occupancyWithoutEPPawns.and(MoveConstants.SQUARE_BBS[Board.ep - 8].not()); BigInteger rookAttacksFromKing = MoveUtils.GetRookMovesSeparate(occupancyWithoutEPPawns, blackKingPosition); if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.WR]))) { if (isZero(rookAttacksFromKing.and(Board.bitboard_array_global[GenConst.WQ]))) { move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = Board.ep; move_list[move_count][MOVE_TAG] = GenConst.TAG_BLACKEP; move_list[move_count][MOVE_PIECE] = GenConst.BP; move_count++; } } } } } } //#endregion } //#endregion //#region Black rook moves temp_bitboard = Board.bitboard_array_global[GenConst.BR]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger rookAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); temp_attack = ((rookAttacks.and(WHITE_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BR; move_count++; } temp_attack = ((rookAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BR; move_count++; } } //#endregion //#region Black bishop moves temp_bitboard = Board.bitboard_array_global[GenConst.BB]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger bishopAttacks = MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square); temp_attack = ((bishopAttacks.and(WHITE_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BB; move_count++; } temp_attack = ((bishopAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BB; move_count++; } } //#endregion //#region Black queen moves temp_bitboard = Board.bitboard_array_global[GenConst.BQ]; while (temp_bitboard.compareTo(BigInteger.ZERO) != 0) { starting_square = BitScanForward(temp_bitboard); temp_bitboard = temp_bitboard.and(temp_bitboard.subtract(BigInteger.ONE)); temp_pin_bitboard = MAX_ULONG; if (pinNumber != 0) { for (int i = 0; i < pinNumber; i++) { if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) { temp_pin_bitboard = Inb.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; } } } BigInteger queenAttacks = MoveUtils.GetRookMovesSeparate(COMBINED_OCCUPANCIES, starting_square); queenAttacks = queenAttacks.and(MoveUtils.GetBishopMovesSeparate(COMBINED_OCCUPANCIES, starting_square)); temp_attack = ((queenAttacks.and(BLACK_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_CAPTURE; move_list[move_count][MOVE_PIECE] = GenConst.BQ; move_count++; } temp_attack = ((queenAttacks.and(EMPTY_OCCUPANCIES).and(check_bitboard).and(temp_pin_bitboard))); while (isNotZero(temp_attack)) { target_square = BitScanForward(temp_attack); temp_attack = removeBit(temp_attack); move_list[move_count][MOVE_STARTING] = starting_square; move_list[move_count][MOVE_TARGET] = target_square; move_list[move_count][MOVE_TAG] = GenConst.TAG_NONE; move_list[move_count][MOVE_PIECE] = GenConst.BQ; move_count++; } } //#endregion } } //if (depth == 1) //{ //return move_count; //} int nodes = 0; int priorNodes; int copyEp = Board.ep; boolean[] copy_castle = { Board.castle_rights_global[0], Board.castle_rights_global[1], Board.castle_rights_global[2], Board.castle_rights_global[3], }; for (int move_index = 0; move_index < move_count; move_index++) { int startingSquare = move_list[move_index][MOVE_STARTING]; int targetSquare = move_list[move_index][MOVE_TARGET]; int piece = move_list[move_index][MOVE_PIECE]; int tag = move_list[move_index][MOVE_TAG]; int captureIndex = -1; Board.is_white_global = !Board.is_white_global; switch (tag) { case GenConst.TAG_NONE: //none case GenConst.TAG_CHECK: //check Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_CAPTURE: //capture case GenConst.TAG_CHECK_CAPTURE: //check cap Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); if (piece >= GenConst.WP && piece <= GenConst.WK) { for (int i = GenConst.BP; i <= GenConst.WP; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); } else //is black { for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); } Board.ep = NO_SQUARE; break; case GenConst.TAG_WHITEEP: //white ep //move piece Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[targetSquare + 8].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BLACKEP: //black ep Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[targetSquare - 8].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_WCASTLEKS: //WKS //white king Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.G1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.E1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.F1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.H1].not()); Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_WCASTLEQS: //WQS Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.C1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.E1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.D1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.A1].not()); Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_BCASTLEKS: //BKS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.G8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.E8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.F8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.H8].not()); Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_BCASTLEQS: //BQS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.C8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.E8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.D8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.A8].not()); Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; Board.ep = NO_SQUARE; break; case GenConst.TAG_BKnightPromotion: //BNPr Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BBishopPromotion: //BBPr Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BQueenPromotion: //BQPr Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BRookPromotion: //BRPr Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 12: //WNPr Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 13: //WBPr Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 14: //WQPr Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 15: //WRPr Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; break; case 16: //BNPrCAP Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 17: //BBPrCAP Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 18: //BQPrCAP Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 19: //BRPrCAP Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.WP; i <= GenConst.WK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 20: //WNPrCAP Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 21: //WBPrCAP Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 22: //WQPrCAP Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; ++i) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 23: //WRPrCAP Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = NO_SQUARE; for (int i = GenConst.BP; i <= GenConst.BK; i++) { if (isNotZero((Board.bitboard_array_global[i].and(MoveConstants.SQUARE_BBS[targetSquare])))) { captureIndex = i; break; } } Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 24: //WDouble Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = targetSquare + 8; break; case 25: //BDouble Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); Board.ep = targetSquare - 8; break; } if (piece == GenConst.WK) { Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; } else if (piece == GenConst.BK) { Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; } else if (piece == GenConst.WR) { if (Board.castle_rights_global[WKS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.H1])))) { Board.castle_rights_global[WKS_CASTLE_RIGHTS] = false; } } if (Board.castle_rights_global[WQS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.A1])))) { Board.castle_rights_global[WQS_CASTLE_RIGHTS] = false; } } } else if (piece == GenConst.BR) { if (Board.castle_rights_global[BKS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.H8])))) { Board.castle_rights_global[BKS_CASTLE_RIGHTS] = false; } } if (Board.castle_rights_global[BQS_CASTLE_RIGHTS] == true) { if (isZero((Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.A8])))) { Board.castle_rights_global[BQS_CASTLE_RIGHTS] = false; } } } priorNodes = nodes; nodes += PerftInlineGlobal(depth - 1, ply + 1); Board.is_white_global = !Board.is_white_global; switch (tag) { case GenConst.TAG_NONE: //none case GenConst.TAG_CHECK: //check Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case GenConst.TAG_CAPTURE: //capture case GenConst.TAG_CHECK_CAPTURE: //check cap Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] = Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[startingSquare]); break; case GenConst.TAG_WHITEEP: //white ep //move piece Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[targetSquare + 8]); break; case GenConst.TAG_BLACKEP: //black ep Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[targetSquare - 8]); break; case GenConst.TAG_WCASTLEKS: //WKS //white king Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.E1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.G1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.H1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.F1].not()); break; case GenConst.TAG_WCASTLEQS: //WQS Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].or(MoveConstants.SQUARE_BBS[GenConst.E1]); Board.bitboard_array_global[GenConst.WK] =Board.bitboard_array_global[GenConst.WK].and(MoveConstants.SQUARE_BBS[GenConst.C1].not()); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].or(MoveConstants.SQUARE_BBS[GenConst.A1]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[GenConst.D1].not()); break; case GenConst.TAG_BCASTLEKS: //BKS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.E8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.G8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.H8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.F8].not()); break; case GenConst.TAG_BCASTLEQS: //BQS Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].or(MoveConstants.SQUARE_BBS[GenConst.E8]); Board.bitboard_array_global[GenConst.BK] =Board.bitboard_array_global[GenConst.BK].and(MoveConstants.SQUARE_BBS[GenConst.C8].not()); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].or(MoveConstants.SQUARE_BBS[GenConst.A8]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[GenConst.D8].not()); break; case GenConst.TAG_BKnightPromotion: //BNPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case GenConst.TAG_BBishopPromotion: //BBPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case GenConst.TAG_BQueenPromotion: //BQPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.ep = NO_SQUARE; break; case GenConst.TAG_BRookPromotion: //BRPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.ep = NO_SQUARE; break; case 12: //WNPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 13: //WBPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 14: //WQPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 15: //WRPr Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 16: //BNPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BN] =Board.bitboard_array_global[GenConst.BN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 17: //BBPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BB] =Board.bitboard_array_global[GenConst.BB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 18: //BQPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BQ] =Board.bitboard_array_global[GenConst.BQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 19: //BRPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.BR] =Board.bitboard_array_global[GenConst.BR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 20: //WNPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WN] =Board.bitboard_array_global[GenConst.WN].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 21: //WBPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WB] =Board.bitboard_array_global[GenConst.WB].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 22: //WQPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WQ] =Board.bitboard_array_global[GenConst.WQ].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 23: //WRPrCAP Board.bitboard_array_global[piece] =Board.bitboard_array_global[piece].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WR] =Board.bitboard_array_global[GenConst.WR].and(MoveConstants.SQUARE_BBS[targetSquare].not()); Board.bitboard_array_global[captureIndex] =Board.bitboard_array_global[captureIndex].or(MoveConstants.SQUARE_BBS[targetSquare]); break; case 24: //WDouble Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].or(MoveConstants.SQUARE_BBS[startingSquare]); Board.bitboard_array_global[GenConst.WP] =Board.bitboard_array_global[GenConst.WP].and(MoveConstants.SQUARE_BBS[targetSquare].not()); break; case 25: //BDouble Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].or(MoveConstants.SQUARE_BBS[targetSquare]); Board.bitboard_array_global[GenConst.BP] =Board.bitboard_array_global[GenConst.BP].and(MoveConstants.SQUARE_BBS[startingSquare].not()); break; } Board.castle_rights_global[0] = copy_castle[0]; Board.castle_rights_global[1] = copy_castle[1]; Board.castle_rights_global[2] = copy_castle[2]; Board.castle_rights_global[3] = copy_castle[3]; Board.ep = copyEp; //if (epGlobal != NO_SQUARE) //{ // std::cout << " ep: " << SQ_CHAR_X[epGlobal] << SQ_CHAR_Y[epGlobal] << '\n'; //} if (ply == 0) { //Pr.printInt(startingSquare); //Pr.printInt(targetSquare); //Pr.printInt(tag); PrintMoveNoNL(startingSquare, targetSquare, tag); System.out.printf(": %d\n", nodes - priorNodes); } } return nodes; } public static void RunPerftInlineGlobalOcc(int depth) { long startTime = System.currentTimeMillis(); int nodes = PerftInlineDebug(depth, 0); long endTime = System.currentTimeMillis(); long elapsedTime = endTime - startTime; String nodeString = String.format("Nodes: %d\n", nodes); String timeString = String.format("Time taken: %d ms\n", elapsedTime); Pr.print(nodeString); Pr.print(timeString); } }