mirror of
https://github.com/OMGeeky/hcsalmon1-Chess-Engine-Test.git
synced 2025-12-27 14:49:04 +01:00
2707 lines
106 KiB
C++
2707 lines
106 KiB
C++
|
|
#include <iostream>
|
|
#include "constants.h"
|
|
|
|
#pragma region General constants
|
|
|
|
const int MOVE_STARTING = 0;
|
|
const int MOVE_TARGET = 1;
|
|
const int MOVE_PIECE = 2;
|
|
const int MOVE_TAG = 3;
|
|
|
|
const char* FEN_STARTING_POSITION = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
|
|
|
const unsigned long long WKS_EMPTY_BITBOARD = 6917529027641081856;
|
|
const unsigned long long WQS_EMPTY_BITBOARD = 1008806316530991104;
|
|
const unsigned long long BKS_EMPTY_BITBOARD = 96;
|
|
const unsigned long long BQS_EMPTY_BITBOARD = 14;
|
|
|
|
const unsigned long long MAX_ULONG = 18446744073709551615;
|
|
|
|
const char SQ_CHAR_Y[65] =
|
|
{
|
|
'8','8','8','8','8','8','8','8',
|
|
'7','7','7','7','7','7','7','7',
|
|
'6','6','6','6','6','6','6','6',
|
|
'5','5','5','5','5','5','5','5',
|
|
'4','4','4','4','4','4','4','4',
|
|
'3','3','3','3','3','3','3','3',
|
|
'2','2','2','2','2','2','2','2',
|
|
'1','1','1','1','1','1','1','1','A'
|
|
};
|
|
|
|
const char SQ_CHAR_X[65] =
|
|
{
|
|
'a','b','c','d','e','f','g','h',
|
|
'a','b','c','d','e','f','g','h',
|
|
'a','b','c','d','e','f','g','h',
|
|
'a','b','c','d','e','f','g','h',
|
|
'a','b','c','d','e','f','g','h',
|
|
'a','b','c','d','e','f','g','h',
|
|
'a','b','c','d','e','f','g','h',
|
|
'a','b','c','d','e','f','g','h','N'
|
|
};
|
|
|
|
const int WKS_CASTLE_RIGHTS = 0, WQS_CASTLE_RIGHTS = 1, BKS_CASTLE_RIGHTS = 2, BQS_CASTLE_RIGHTS = 3;
|
|
const int WP = 0, WN = 1, WB = 2, WR = 3, WQ = 4, WK = 5,
|
|
BP = 6, BN = 7, BB = 8, BR = 9, BQ = 10, BK = 11;
|
|
|
|
const int A8 = 0, B8 = 1, C8 = 2, D8 = 3, E8 = 4, F8 = 5, G8 = 6, H8 = 7,
|
|
A7 = 8, B7 = 9, C7 = 10, D7 = 11, E7 = 12, F7 = 13, G7 = 14, H7 = 15,
|
|
A6 = 16, B6 = 17, C6 = 18, D6 = 19, E6 = 20, F6 = 21, G6 = 22, H6 = 23,
|
|
A5 = 24, B5 = 25, C5 = 26, D5 = 27, E5 = 28, F5 = 29, G5 = 30, H5 = 31,
|
|
A4 = 32, B4 = 33, C4 = 34, D4 = 35, E4 = 36, F4 = 37, G4 = 38, H4 = 39,
|
|
A3 = 40, B3 = 41, C3 = 42, D3 = 43, E3 = 44, F3 = 45, G3 = 46, H3 = 47,
|
|
A2 = 48, B2 = 49, C2 = 50, D2 = 51, E2 = 52, F2 = 53, G2 = 54, H2 = 55,
|
|
A1 = 56, B1 = 57, C1 = 58, D1 = 59, E1 = 60, F1 = 61, G1 = 62, H1 = 63, NO_SQUARE = 64;
|
|
|
|
const unsigned long long RANK_1_BITBOARD = 18374686479671623680;
|
|
const unsigned long long RANK_2_BITBOARD = 71776119061217280;
|
|
const unsigned long long RANK_3_BITBOARD = 280375465082880;
|
|
const unsigned long long RANK_4_BITBOARD = 1095216660480;
|
|
const unsigned long long RANK_5_BITBOARD = 4278190080;
|
|
const unsigned long long RANK_6_BITBOARD = 16711680;
|
|
const unsigned long long RANK_7_BITBOARD = 65280;
|
|
const unsigned long long RANK_8_BITBOARD = 255;
|
|
|
|
const int WHITE_START_INDEX = WP;
|
|
const int WHITE_END_INDEX = WK;
|
|
const int BLACK_START_INDEX = BP;
|
|
const int BLACK_END_INDEX = BK;
|
|
|
|
const int PINNED_SQUARE_INDEX = 0;
|
|
const int PINNING_PIECE_INDEX = 1;
|
|
|
|
const int TAG_NONE = 0, TAG_CAPTURE = 1, TAG_WHITEEP = 2, TAG_BLACKEP = 3, TAG_WCASTLEKS = 4, TAG_WCASTLEQS = 5, TAG_BCASTLEKS = 6, TAG_BCASTLEQS = 7,
|
|
TAG_BKnightPromotion = 8, TAG_BBishopPromotion = 9, TAG_BQueenPromotion = 10, TAG_BRookPromotion = 11,
|
|
TAG_WKnightPromotion = 12, TAG_WBishopPromotion = 13, TAG_WQueenPromotion = 14, TAG_WRookPromotion = 15,
|
|
TAG_BCaptureKnightPromotion = 16, TAG_BCaptureBishopPromotion = 17, TAG_BCaptureQueenPromotion = 18, TAG_BCaptureRookPromotion = 19,
|
|
TAG_WCaptureKnightPromotion = 20, TAG_WCaptureBishopPromotion = 21, TAG_WCaptureQueenPromotion = 22, TAG_WCaptureRookPromotion = 23,
|
|
TAG_DoublePawnWhite = 24, TAG_DoublePawnBlack = 25, TAG_CHECK = 26, TAG_CHECK_CAPTURE = 27;
|
|
|
|
const unsigned long long MAGIC = 285870213051386505;
|
|
|
|
const int DEBRUIJN64[64] =
|
|
{
|
|
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
|
|
};
|
|
|
|
#pragma endregion
|
|
|
|
//equation: startingSquare = (DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58]);
|
|
|
|
inline bool PieceIsWhite(const int piece)
|
|
{
|
|
if (piece >= WP)
|
|
{
|
|
if (piece <= WK)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline int BitscanForward(const unsigned long long tempBitboard)
|
|
{
|
|
return (DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58]);
|
|
}
|
|
|
|
inline unsigned long long GetRookAttacksFast(const int startingSquare, unsigned long long occupancy)
|
|
{
|
|
occupancy &= ROOK_MASKS[startingSquare];
|
|
occupancy *= ROOK_MAGIC_NUMBERS[startingSquare];
|
|
occupancy >>= 64 - ROOK_REL_BITS[startingSquare];
|
|
return ROOK_ATTACKS[startingSquare][occupancy];
|
|
}
|
|
|
|
inline unsigned long long GetBishopAttacksFast(const int startingSquare, unsigned long long occupancy)
|
|
{
|
|
occupancy &= BISHOP_MASKS[startingSquare];
|
|
occupancy *= BISHOP_MAGIC_NUMBERS[startingSquare];
|
|
occupancy >>= 64 - BISHOP_REL_BITS[startingSquare];
|
|
return BISHOP_ATTACKS[startingSquare][occupancy];
|
|
}
|
|
|
|
|
|
unsigned long long* bitboardArray[12];
|
|
int* ep;
|
|
bool* castleRights[4];
|
|
bool* isWhite;
|
|
|
|
unsigned long long bitboard_array_global[12];
|
|
int ep_global;
|
|
bool castle_rights_global[4];
|
|
bool is_white_global;
|
|
|
|
|
|
inline bool Is_Square_Attacked_By_Black_Global(const int square, const unsigned long long occupancy)
|
|
{
|
|
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[square]) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[square]) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[BK] & KING_ATTACKS[square]) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(square, occupancy);
|
|
if ((bitboard_array_global[BB] & bishopAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[BQ] & bishopAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
unsigned long long rookAttacks = GetRookAttacksFast(square, occupancy);
|
|
if ((bitboard_array_global[BR] & rookAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[BQ] & rookAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline bool Is_Square_Attacked_By_White_Global(const int square, const unsigned long long occupancy)
|
|
{
|
|
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[square]) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[square]) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[WK] & KING_ATTACKS[square]) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(square, occupancy);
|
|
if ((bitboard_array_global[WB] & bishopAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[WQ] & bishopAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
unsigned long long rookAttacks = GetRookAttacksFast(square, occupancy);
|
|
if ((bitboard_array_global[WR] & rookAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
if ((bitboard_array_global[WQ] & rookAttacks) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void CreateBoard()
|
|
{
|
|
for (size_t i = 0; i < 12; ++i)
|
|
{
|
|
bitboardArray[i] = new unsigned long long;
|
|
}
|
|
ep = new int;
|
|
isWhite = new bool;
|
|
for (size_t i = 0; i < 4; ++i)
|
|
{
|
|
castleRights[i] = new bool;
|
|
}
|
|
}
|
|
|
|
|
|
void CopyGlobalBoardGlobal()
|
|
{
|
|
for (size_t i = 0; i < 12; ++i)
|
|
{
|
|
bitboard_array_global[i] = *bitboardArray[i];
|
|
}
|
|
for (size_t i = 0; i < 4; ++i)
|
|
{
|
|
castle_rights_global[i] = *castleRights[i];
|
|
}
|
|
ep_global = *ep;
|
|
is_white_global = *isWhite;
|
|
}
|
|
|
|
|
|
void ResetBoardGlobal()
|
|
{
|
|
*castleRights[0] = false;
|
|
*castleRights[1] = false;
|
|
*castleRights[2] = false;
|
|
*castleRights[3] = false;
|
|
|
|
for (size_t i = 0; i < 12; i++)
|
|
{
|
|
*bitboardArray[i] = 0;
|
|
}
|
|
*isWhite = true;
|
|
*ep = NO_SQUARE;
|
|
}
|
|
|
|
const int PIECE_PHASE = 0; const int SIDE_PHASE = 1; const int CASTLE_PHASE = 2; const int EP_PHASE = 3; const int FIFTY_MOVE_PHASE = 4; const int MOVE_COUNT_PHASE = 5;
|
|
|
|
void ParseFenGlobal(const char input[], const size_t startingIndex)
|
|
{
|
|
ResetBoardGlobal();
|
|
|
|
const size_t inputLength = strlen(input);
|
|
if (startingIndex >= inputLength)
|
|
{
|
|
return;
|
|
}
|
|
if (startingIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int currentPhase = PIECE_PHASE;
|
|
int bracketCount = 0;
|
|
int squareCount = 0;
|
|
int epX = -1;
|
|
int epY = -1;
|
|
|
|
for (size_t characterIndex = startingIndex; characterIndex < inputLength; characterIndex++)
|
|
{
|
|
const char characterInFen = input[characterIndex];
|
|
//printf("index: %d ", characterIndex);
|
|
//printf("currentPhase: %d", currentPhase);
|
|
//printf(" char: %c\n", characterInFen);
|
|
//printf(" bracketcount %d", bracketCount);
|
|
//printf(" squarecount: %d\n", squareCount);
|
|
switch (currentPhase)
|
|
{
|
|
case 0:
|
|
|
|
if (bracketCount == 7 && characterInFen == ' ')
|
|
{
|
|
//printf(" next phase brackcount = 7, char is empty\n");
|
|
currentPhase++;
|
|
}
|
|
else
|
|
{
|
|
if (bracketCount > 7)
|
|
{
|
|
bracketCount = 0;
|
|
}
|
|
|
|
if (squareCount > 7)
|
|
{
|
|
squareCount = 0;
|
|
}
|
|
|
|
int square = (bracketCount * 8) + squareCount;
|
|
|
|
switch (characterInFen)
|
|
{
|
|
|
|
case 'B':
|
|
//printf(" W bishop found %d\n", square);
|
|
*bitboardArray[WB] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'R':
|
|
//printf(" WR found\n");
|
|
*bitboardArray[WR] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'P':
|
|
//printf(" add white pawn %d\n", square);
|
|
*bitboardArray[WP] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'Q':
|
|
//printf(" WQ found\n");
|
|
*bitboardArray[WQ] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'K':
|
|
//printf(" WK\n");
|
|
*bitboardArray[WK] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'N':
|
|
//printf(" WN found\n");
|
|
*bitboardArray[WN] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'b':
|
|
//printf(" BB found\n");
|
|
*bitboardArray[BB] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
|
|
case 'p':
|
|
//printf(" BP sq: %d\n", square);
|
|
*bitboardArray[BP] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'q':
|
|
//printf(" BQ sq: %d\n", square);
|
|
*bitboardArray[BQ] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'r':
|
|
//printf(" BR sq: %d\n", square);
|
|
*bitboardArray[BR] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'n':
|
|
//printf(" BN sq: %d\n", square);
|
|
*bitboardArray[BN] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
case 'k':
|
|
//printf(" BK sq: %d\n", square);
|
|
*bitboardArray[BK] |= SQUARE_BBS[square];
|
|
squareCount++;
|
|
break;
|
|
|
|
case '/':
|
|
//printf(" forward bracket slash\n", square);
|
|
squareCount = 0;
|
|
bracketCount++;
|
|
break;
|
|
case '1':
|
|
//printf(" 1 found\n");
|
|
squareCount += 1;
|
|
break;
|
|
case '2':
|
|
//printf(" 2 found\n");
|
|
squareCount += 2;
|
|
break;
|
|
case '3':
|
|
//printf(" 3 found\n");
|
|
squareCount += 3;
|
|
break;
|
|
case '4':
|
|
//printf(" 4 found\n");
|
|
squareCount += 4;
|
|
break;
|
|
case '5':
|
|
//printf(" 5 found\n");
|
|
squareCount += 5;
|
|
break;
|
|
case '6':
|
|
//printf(" 6 found\n");
|
|
squareCount += 6;
|
|
break;
|
|
case '7':
|
|
//printf(" 7 found\n");
|
|
squareCount += 7;
|
|
break;
|
|
case '8':
|
|
//printf(" 8 found\n");
|
|
squareCount += 8;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
if (characterInFen == 'w')
|
|
{
|
|
*isWhite = true;
|
|
}
|
|
else if (characterInFen == 'b')
|
|
{
|
|
*isWhite = false;
|
|
}
|
|
else if (characterInFen == ' ')
|
|
{
|
|
currentPhase++;
|
|
}
|
|
break;
|
|
case 2:
|
|
switch (characterInFen)
|
|
{
|
|
case 'K':
|
|
*castleRights[0] = true;
|
|
break;
|
|
case 'Q':
|
|
*castleRights[1] = true;
|
|
break;
|
|
case 'k':
|
|
*castleRights[2] = true;
|
|
break;
|
|
case 'q':
|
|
*castleRights[3] = true;
|
|
break;
|
|
case '-':
|
|
|
|
break;
|
|
case ' ':
|
|
currentPhase++;
|
|
break;
|
|
}
|
|
break;
|
|
case 3:
|
|
if (characterInFen == ' ')
|
|
{
|
|
if (epX != -1)
|
|
{
|
|
if (epY != -1)
|
|
{
|
|
*ep = (epY * 8) + epX;
|
|
}
|
|
}
|
|
currentPhase++;
|
|
}
|
|
else
|
|
{
|
|
switch (characterInFen)
|
|
{
|
|
case 'a':
|
|
epX = 0;
|
|
break;
|
|
case 'b':
|
|
epX = 1;
|
|
break;
|
|
case 'c':
|
|
epX = 2;
|
|
break;
|
|
case 'd':
|
|
epX = 3;
|
|
break;
|
|
case 'e':
|
|
epX = 4;
|
|
break;
|
|
case 'f':
|
|
epX = 5;
|
|
break;
|
|
case 'g':
|
|
epX = 6;
|
|
break;
|
|
case 'h':
|
|
epX = 7;
|
|
break;
|
|
case '1':
|
|
epY = 7;
|
|
break;
|
|
case '2':
|
|
epY = 6;
|
|
break;
|
|
case '3':
|
|
epY = 5;
|
|
break;
|
|
case '4':
|
|
epY = 4;
|
|
break;
|
|
case '5':
|
|
epY = 3;
|
|
break;
|
|
case '6':
|
|
epY = 2;
|
|
break;
|
|
case '7':
|
|
epY = 1;
|
|
break;
|
|
case '8':
|
|
epY = 0;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case 4:
|
|
break;
|
|
case 5:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
unsigned long long PerftInlineGlobal(const int depth, const int ply)
|
|
{
|
|
//if (depth == 0)
|
|
//{
|
|
// return 1;
|
|
//}
|
|
|
|
int move_list[250][4];
|
|
int move_count = 0;
|
|
|
|
//Move generating variables
|
|
const unsigned long long WHITE_OCCUPANCIES_LOCAL = bitboard_array_global[0] | bitboard_array_global[1] | bitboard_array_global[2] | bitboard_array_global[3] | bitboard_array_global[4] | bitboard_array_global[5];
|
|
const unsigned long long BLACK_OCCUPANCIES_LOCAL = bitboard_array_global[6] | bitboard_array_global[7] | bitboard_array_global[8] | bitboard_array_global[9] | bitboard_array_global[10] | bitboard_array_global[11];
|
|
const unsigned long long COMBINED_OCCUPANCIES_LOCAL = WHITE_OCCUPANCIES_LOCAL | BLACK_OCCUPANCIES_LOCAL;
|
|
const unsigned long long EMPTY_OCCUPANCIES = ~COMBINED_OCCUPANCIES_LOCAL;
|
|
unsigned long long temp_bitboard, check_bitboard = 0ULL, temp_pin_bitboard, temp_attack, temp_empty, temp_captures;
|
|
int starting_square = NO_SQUARE, target_square = NO_SQUARE;
|
|
|
|
int pinArray[8][2] =
|
|
{
|
|
{ -1, -1 },
|
|
{ -1, -1 },
|
|
{ -1, -1 },
|
|
{ -1, -1 },
|
|
{ -1, -1 },
|
|
{ -1, -1 },
|
|
{ -1, -1 },
|
|
{ -1, -1 },
|
|
};
|
|
|
|
int pinNumber = 0;
|
|
|
|
#pragma region Generate Moves
|
|
|
|
if (is_white_global == true)
|
|
{
|
|
int whiteKingCheckCount = 0;
|
|
const int whiteKingPosition = BitscanForward(bitboard_array_global[WK]);
|
|
|
|
#pragma region pins and check
|
|
|
|
//pawns
|
|
temp_bitboard = bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[whiteKingPosition];
|
|
if (temp_bitboard != 0)
|
|
{
|
|
const int pawn_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = 1ULL << pawn_square;
|
|
}
|
|
|
|
whiteKingCheckCount++;
|
|
}
|
|
|
|
//knights
|
|
temp_bitboard = bitboard_array_global[BN] & KNIGHT_ATTACKS[whiteKingPosition];
|
|
if (temp_bitboard != 0)
|
|
{
|
|
const int knight_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = SQUARE_BBS[knight_square];
|
|
}
|
|
|
|
whiteKingCheckCount++;
|
|
}
|
|
|
|
//bishops
|
|
const unsigned long long bishopAttacksChecks = GetBishopAttacksFast(whiteKingPosition, BLACK_OCCUPANCIES_LOCAL);
|
|
temp_bitboard = bitboard_array_global[BB] & bishopAttacksChecks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
const int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
|
|
}
|
|
whiteKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
const int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
//queen
|
|
temp_bitboard = bitboard_array_global[BQ] & bishopAttacksChecks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
const int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
|
|
}
|
|
whiteKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
const int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
//rook
|
|
const unsigned long long rook_attacks = GetRookAttacksFast(whiteKingPosition, BLACK_OCCUPANCIES_LOCAL);
|
|
temp_bitboard = bitboard_array_global[BR] & rook_attacks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
const int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
|
|
}
|
|
whiteKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
const int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
//queen
|
|
temp_bitboard = bitboard_array_global[BQ] & rook_attacks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
const int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
|
|
}
|
|
whiteKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
const int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
if (whiteKingCheckCount > 1)
|
|
{
|
|
#pragma region White king
|
|
const unsigned long long occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[WK]);
|
|
temp_attack = KING_ATTACKS[whiteKingPosition];
|
|
temp_empty = temp_attack & EMPTY_OCCUPANCIES;
|
|
while (temp_empty != 0)
|
|
{
|
|
target_square = BitscanForward(temp_empty);
|
|
temp_empty &= temp_empty - 1;
|
|
|
|
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = WK;
|
|
move_count++;
|
|
}
|
|
|
|
//captures
|
|
temp_captures = temp_attack & BLACK_OCCUPANCIES_LOCAL;
|
|
while (temp_captures != 0)
|
|
{
|
|
target_square = BitscanForward(temp_captures);
|
|
temp_captures &= temp_captures - 1;
|
|
|
|
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
const unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
const unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = WK;
|
|
move_count++;
|
|
}
|
|
|
|
#pragma endregion
|
|
}
|
|
else
|
|
{
|
|
|
|
if (whiteKingCheckCount == 0)
|
|
{
|
|
check_bitboard = MAX_ULONG;
|
|
}
|
|
|
|
#pragma region White king
|
|
const unsigned long long occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[WK]);
|
|
temp_attack = KING_ATTACKS[whiteKingPosition];
|
|
temp_empty = temp_attack & EMPTY_OCCUPANCIES;
|
|
while (temp_empty != 0)
|
|
{
|
|
target_square = BitscanForward(temp_empty);
|
|
temp_empty &= temp_empty - 1;
|
|
|
|
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = WK;
|
|
move_count++;
|
|
}
|
|
|
|
//captures
|
|
temp_captures = temp_attack & BLACK_OCCUPANCIES_LOCAL;
|
|
while (temp_captures != 0)
|
|
{
|
|
target_square = BitscanForward(temp_captures);
|
|
temp_captures &= temp_captures - 1;
|
|
|
|
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
|
|
if ((bitboard_array_global[BR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[BQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = WK;
|
|
move_count++;
|
|
}
|
|
|
|
if (whiteKingCheckCount == 0)
|
|
{
|
|
if (castle_rights_global[WKS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if (whiteKingPosition == E1) //king on e1
|
|
{
|
|
if ((WKS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) //f1 and g1 empty
|
|
{
|
|
if ((bitboard_array_global[WR] & SQUARE_BBS[H1]) != 0) //rook on h1
|
|
{
|
|
if (Is_Square_Attacked_By_Black_Global(F1, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
if (Is_Square_Attacked_By_Black_Global(G1, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = E1;
|
|
move_list[move_count][MOVE_TARGET] = G1;
|
|
move_list[move_count][MOVE_TAG] = TAG_WCASTLEKS;
|
|
move_list[move_count][MOVE_PIECE] = WK;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (castle_rights_global[WQS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if (whiteKingPosition == E1) //king on e1
|
|
{
|
|
if ((WQS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) //f1 and g1 empty
|
|
{
|
|
if ((bitboard_array_global[WR] & SQUARE_BBS[A1]) != 0) //rook on h1
|
|
{
|
|
if (Is_Square_Attacked_By_Black_Global(C1, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
if (Is_Square_Attacked_By_Black_Global(D1, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = E1;
|
|
move_list[move_count][MOVE_TARGET] = C1;
|
|
move_list[move_count][MOVE_TAG] = TAG_WCASTLEQS;
|
|
move_list[move_count][MOVE_PIECE] = WK;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region White knight
|
|
|
|
temp_bitboard = bitboard_array_global[WN];
|
|
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1; //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 = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
temp_attack = ((KNIGHT_ATTACKS[starting_square] & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //gets knight captures
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = WN;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((KNIGHT_ATTACKS[starting_square] & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = WN;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region White pawn
|
|
|
|
temp_bitboard = bitboard_array_global[WP];
|
|
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma region Pawn forward
|
|
|
|
if ((SQUARE_BBS[starting_square - 8] & COMBINED_OCCUPANCIES_LOCAL) == 0) //if up one square is empty
|
|
{
|
|
if (((SQUARE_BBS[starting_square - 8] & check_bitboard) & temp_pin_bitboard) != 0)
|
|
{
|
|
if ((SQUARE_BBS[starting_square] & RANK_7_BITBOARD) != 0) //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] = TAG_WQueenPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_WRookPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_WBishopPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_WKnightPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = WP;
|
|
move_count++;
|
|
}
|
|
}
|
|
|
|
if ((SQUARE_BBS[starting_square] & RANK_2_BITBOARD) != 0) //if on rank 2
|
|
{
|
|
if (((SQUARE_BBS[starting_square - 16] & check_bitboard) & temp_pin_bitboard) != 0) //if not pinned or
|
|
{
|
|
if (((SQUARE_BBS[starting_square - 16]) & COMBINED_OCCUPANCIES_LOCAL) == 0) //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] = TAG_DoublePawnWhite;
|
|
move_list[move_count][MOVE_PIECE] = WP;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Pawn captures
|
|
|
|
temp_attack = ((WHITE_PAWN_ATTACKS[starting_square] & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //if black piece diagonal to pawn
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
if ((SQUARE_BBS[starting_square] & RANK_7_BITBOARD) != 0) //if promotion
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_WCaptureQueenPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_WCaptureRookPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_WCaptureBishopPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_WCaptureKnightPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = WP;
|
|
move_count++;
|
|
}
|
|
}
|
|
|
|
if ((SQUARE_BBS[starting_square] & RANK_5_BITBOARD) != 0) //check rank for ep
|
|
{
|
|
if (ep_global != NO_SQUARE)
|
|
{
|
|
if ((((WHITE_PAWN_ATTACKS[starting_square] & SQUARE_BBS[ep_global]) & check_bitboard) & temp_pin_bitboard) != 0)
|
|
{
|
|
if ((bitboard_array_global[WK] & RANK_5_BITBOARD) == 0) //if no king on rank 5
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = ep_global;
|
|
move_list[move_count][MOVE_TAG] = TAG_WHITEEP;
|
|
move_list[move_count][MOVE_PIECE] = WP;
|
|
move_count++;
|
|
}
|
|
else if ((bitboard_array_global[BR] & RANK_5_BITBOARD) == 0 && (bitboard_array_global[BQ] & RANK_5_BITBOARD) == 0) // if no b rook or queen on rank 5
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = ep_global;
|
|
move_list[move_count][MOVE_TAG] = TAG_WHITEEP;
|
|
move_list[move_count][MOVE_PIECE] = WP;
|
|
move_count++;
|
|
}
|
|
else //wk and br or bq on rank 5
|
|
{
|
|
unsigned long long occupancyWithoutEPPawns = COMBINED_OCCUPANCIES_LOCAL & ~SQUARE_BBS[starting_square];
|
|
occupancyWithoutEPPawns &= ~SQUARE_BBS[ep_global + 8];
|
|
|
|
const unsigned long long rookAttacksFromKing = GetRookAttacksFast(whiteKingPosition, occupancyWithoutEPPawns);
|
|
|
|
if ((rookAttacksFromKing & bitboard_array_global[BR]) == 0)
|
|
{
|
|
if ((rookAttacksFromKing & bitboard_array_global[BQ]) == 0)
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = ep_global;
|
|
move_list[move_count][MOVE_TAG] = TAG_WHITEEP;
|
|
move_list[move_count][MOVE_PIECE] = WP;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region White Rook
|
|
temp_bitboard = bitboard_array_global[WR];
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
const unsigned long long rookAttacks = GetRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
|
|
temp_attack = ((rookAttacks & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = WR;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((rookAttacks & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = WR;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region White bishop
|
|
temp_bitboard = bitboard_array_global[WB];
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
|
|
temp_attack = ((bishopAttacks & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = WB;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((bishopAttacks & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = WB;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region White Queen
|
|
temp_bitboard = bitboard_array_global[WQ];
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned long long queenAttacks = GetRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
queenAttacks |= GetBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
|
|
temp_attack = ((queenAttacks & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = WQ;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((queenAttacks & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = WQ;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
}
|
|
}
|
|
else //black move
|
|
{
|
|
int blackKingCheckCount = 0;
|
|
int blackKingPosition = (DEBRUIJN64[MAGIC * (bitboard_array_global[BK] ^ (bitboard_array_global[BK] - 1)) >> 58]);
|
|
|
|
#pragma region pins and check
|
|
|
|
//pawns
|
|
temp_bitboard = bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[blackKingPosition];
|
|
if (temp_bitboard != 0)
|
|
{
|
|
const int pawn_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = SQUARE_BBS[pawn_square];
|
|
}
|
|
|
|
blackKingCheckCount++;
|
|
}
|
|
|
|
//knights
|
|
temp_bitboard = bitboard_array_global[WN] & KNIGHT_ATTACKS[blackKingPosition];
|
|
if (temp_bitboard != 0)
|
|
{
|
|
int knight_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = SQUARE_BBS[knight_square];
|
|
}
|
|
|
|
blackKingCheckCount++;
|
|
}
|
|
|
|
//bishops
|
|
const unsigned long long bishopAttacksChecks = GetBishopAttacksFast(blackKingPosition, WHITE_OCCUPANCIES_LOCAL);
|
|
temp_bitboard = bitboard_array_global[WB] & bishopAttacksChecks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
|
|
}
|
|
blackKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
//queen
|
|
temp_bitboard = bitboard_array_global[WQ] & bishopAttacksChecks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
|
|
}
|
|
blackKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
//rook
|
|
unsigned long long rook_attacks = GetRookAttacksFast(blackKingPosition, WHITE_OCCUPANCIES_LOCAL);
|
|
temp_bitboard = bitboard_array_global[WR] & rook_attacks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
|
|
}
|
|
blackKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
//queen
|
|
temp_bitboard = bitboard_array_global[WQ] & rook_attacks;
|
|
while (temp_bitboard != 0)
|
|
{
|
|
int piece_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
if (check_bitboard == 0)
|
|
{
|
|
check_bitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
|
|
}
|
|
blackKingCheckCount++;
|
|
}
|
|
else
|
|
{
|
|
int pinned_square = (DEBRUIJN64[MAGIC * (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58]);
|
|
temp_pin_bitboard &= temp_pin_bitboard - 1;
|
|
|
|
if (temp_pin_bitboard == 0)
|
|
{
|
|
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
|
|
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
|
|
pinNumber++;
|
|
}
|
|
}
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
if (blackKingCheckCount > 1)
|
|
{
|
|
#pragma region Black king
|
|
const unsigned long long occupancyWithoutBlackKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[BK]);
|
|
temp_attack = KING_ATTACKS[blackKingPosition] & WHITE_OCCUPANCIES_LOCAL;
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = BK;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = KING_ATTACKS[blackKingPosition] & ~COMBINED_OCCUPANCIES_LOCAL;
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
if ((bitboard_array_global[WP] & WHITE_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = BK;
|
|
move_count++;
|
|
}
|
|
#pragma endregion
|
|
}
|
|
else
|
|
{
|
|
if (blackKingCheckCount == 0)
|
|
{
|
|
check_bitboard = MAX_ULONG;
|
|
}
|
|
|
|
#pragma region Black pawns
|
|
|
|
temp_bitboard = bitboard_array_global[BP];
|
|
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma region Pawn forward
|
|
|
|
if ((SQUARE_BBS[starting_square + 8] & COMBINED_OCCUPANCIES_LOCAL) == 0) //if up one square is empty
|
|
{
|
|
if (((SQUARE_BBS[starting_square + 8] & check_bitboard) & temp_pin_bitboard) != 0)
|
|
{
|
|
if ((SQUARE_BBS[starting_square] & RANK_2_BITBOARD) != 0) //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] = TAG_BBishopPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_BKnightPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_BRookPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_BQueenPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = BP;
|
|
move_count++;
|
|
}
|
|
}
|
|
|
|
if ((SQUARE_BBS[starting_square] & RANK_7_BITBOARD) != 0) //if on rank 2
|
|
{
|
|
if (((SQUARE_BBS[starting_square + 16] & check_bitboard) & temp_pin_bitboard) != 0)
|
|
{
|
|
if (((SQUARE_BBS[starting_square + 16]) & COMBINED_OCCUPANCIES_LOCAL) == 0) //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] = TAG_DoublePawnBlack;
|
|
move_list[move_count][MOVE_PIECE] = BP;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region region Pawn captures
|
|
|
|
temp_attack = ((BLACK_PAWN_ATTACKS[starting_square] & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //if black piece diagonal to pawn
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]); //find the bit
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
if ((SQUARE_BBS[starting_square] & RANK_2_BITBOARD) != 0) //if promotion
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_BCaptureQueenPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_BCaptureRookPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_BCaptureKnightPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_BCaptureBishopPromotion;
|
|
move_list[move_count][MOVE_PIECE] = 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] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = BP;
|
|
move_count++;
|
|
}
|
|
}
|
|
|
|
if ((SQUARE_BBS[starting_square] & RANK_4_BITBOARD) != 0) //check rank for ep
|
|
{
|
|
if (ep_global != NO_SQUARE)
|
|
{
|
|
if ((((BLACK_PAWN_ATTACKS[starting_square] & SQUARE_BBS[ep_global]) & check_bitboard) & temp_pin_bitboard) != 0)
|
|
{
|
|
if ((bitboard_array_global[BK] & RANK_4_BITBOARD) == 0) //if no king on rank 5
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = ep_global;
|
|
move_list[move_count][MOVE_TAG] = TAG_BLACKEP;
|
|
move_list[move_count][MOVE_PIECE] = BP;
|
|
move_count++;
|
|
}
|
|
else if ((bitboard_array_global[WR] & RANK_4_BITBOARD) == 0 && (bitboard_array_global[WQ] & RANK_4_BITBOARD) == 0) // if no b rook or queen on rank 5
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = ep_global;
|
|
move_list[move_count][MOVE_TAG] = TAG_BLACKEP;
|
|
move_list[move_count][MOVE_PIECE] = BP;
|
|
move_count++;
|
|
}
|
|
else //wk and br or bq on rank 5
|
|
{
|
|
unsigned long long occupancyWithoutEPPawns = COMBINED_OCCUPANCIES_LOCAL & ~SQUARE_BBS[starting_square];
|
|
occupancyWithoutEPPawns &= ~SQUARE_BBS[ep_global - 8];
|
|
|
|
unsigned long long rookAttacksFromKing = GetRookAttacksFast(blackKingPosition, occupancyWithoutEPPawns);
|
|
|
|
if ((rookAttacksFromKing & bitboard_array_global[WR]) == 0)
|
|
{
|
|
if ((rookAttacksFromKing & bitboard_array_global[WQ]) == 0)
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = ep_global;
|
|
move_list[move_count][MOVE_TAG] = TAG_BLACKEP;
|
|
move_list[move_count][MOVE_PIECE] = BP;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region black Knight
|
|
temp_bitboard = bitboard_array_global[BN];
|
|
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]); //looks for the startingSquare
|
|
temp_bitboard &= temp_bitboard - 1; //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 = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
temp_attack = ((KNIGHT_ATTACKS[starting_square] & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //gets knight captures
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = BN;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((KNIGHT_ATTACKS[starting_square] & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = BN;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region Black bishop
|
|
temp_bitboard = bitboard_array_global[BB];
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
const unsigned long long bishopAttacks = GetBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
|
|
temp_attack = ((bishopAttacks & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = BB;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((bishopAttacks & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = BB;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region Black Rook
|
|
temp_bitboard = bitboard_array_global[BR];
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned long long rookAttacks = GetRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
|
|
temp_attack = ((rookAttacks & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = BR;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((rookAttacks & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = BR;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region Black queen
|
|
|
|
temp_bitboard = bitboard_array_global[BQ];
|
|
while (temp_bitboard != 0)
|
|
{
|
|
starting_square = (DEBRUIJN64[MAGIC * (temp_bitboard ^ (temp_bitboard - 1)) >> 58]);
|
|
temp_bitboard &= temp_bitboard - 1;
|
|
|
|
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 = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned long long queenAttacks = GetRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
queenAttacks |= GetBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
|
|
|
|
temp_attack = ((queenAttacks & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = BQ;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = ((queenAttacks & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
move_list[move_count][MOVE_STARTING] = starting_square;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = BQ;
|
|
move_count++;
|
|
}
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region Black King
|
|
|
|
temp_attack = KING_ATTACKS[blackKingPosition] & WHITE_OCCUPANCIES_LOCAL; //gets knight captures
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
const unsigned long long occupancyWithoutBlackKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[BK]);
|
|
const unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
const unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = blackKingPosition;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
|
|
move_list[move_count][MOVE_PIECE] = BK;
|
|
move_count++;
|
|
}
|
|
|
|
temp_attack = KING_ATTACKS[blackKingPosition] & (~COMBINED_OCCUPANCIES_LOCAL); //get knight moves to emtpy squares
|
|
|
|
while (temp_attack != 0)
|
|
{
|
|
target_square = (DEBRUIJN64[MAGIC * (temp_attack ^ (temp_attack - 1)) >> 58]);
|
|
temp_attack &= temp_attack - 1;
|
|
|
|
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
const unsigned long long occupancyWithoutBlackKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[BK]);
|
|
const unsigned long long bishopAttacks = GetBishopAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WB] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & bishopAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
const unsigned long long rookAttacks = GetRookAttacksFast(target_square, occupancyWithoutBlackKing);
|
|
if ((bitboard_array_global[WR] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bitboard_array_global[WQ] & rookAttacks) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
move_list[move_count][MOVE_STARTING] = blackKingPosition;
|
|
move_list[move_count][MOVE_TARGET] = target_square;
|
|
move_list[move_count][MOVE_TAG] = TAG_NONE;
|
|
move_list[move_count][MOVE_PIECE] = BK;
|
|
move_count++;
|
|
}
|
|
}
|
|
if (blackKingCheckCount == 0)
|
|
{
|
|
if (castle_rights_global[BKS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if (blackKingPosition == E8) //king on e1
|
|
{
|
|
if ((BKS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) //f1 and g1 empty
|
|
{
|
|
if ((bitboard_array_global[BR] & SQUARE_BBS[H8]) != 0) //rook on h1
|
|
{
|
|
if (Is_Square_Attacked_By_White_Global(F8, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
if (Is_Square_Attacked_By_White_Global(G8, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = E8;
|
|
move_list[move_count][MOVE_TARGET] = G8;
|
|
move_list[move_count][MOVE_TAG] = TAG_BCASTLEKS;
|
|
move_list[move_count][MOVE_PIECE] = BK;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (castle_rights_global[BQS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if (blackKingPosition == E8) //king on e1
|
|
{
|
|
if ((BQS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) //f1 and g1 empty
|
|
{
|
|
if ((bitboard_array_global[BR] & SQUARE_BBS[A8]) != 0) //rook on h1
|
|
{
|
|
if (Is_Square_Attacked_By_White_Global(C8, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
if (Is_Square_Attacked_By_White_Global(D8, COMBINED_OCCUPANCIES_LOCAL) == false)
|
|
{
|
|
move_list[move_count][MOVE_STARTING] = E8;
|
|
move_list[move_count][MOVE_TARGET] = C8;
|
|
move_list[move_count][MOVE_TAG] = TAG_BCASTLEQS;
|
|
move_list[move_count][MOVE_PIECE] = BK;
|
|
move_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#pragma endregion
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
if (depth == 1)
|
|
{
|
|
return move_count;
|
|
}
|
|
|
|
unsigned long long nodes = 0;// , priorNodes;
|
|
int copyEp = ep_global;
|
|
bool copy_castle[4];
|
|
copy_castle[0] = castle_rights_global[0];
|
|
copy_castle[1] = castle_rights_global[1];
|
|
copy_castle[2] = castle_rights_global[2];
|
|
copy_castle[3] = castle_rights_global[3];
|
|
|
|
for (size_t move_index = 0; move_index < move_count; ++move_index)
|
|
{
|
|
const int startingSquare = move_list[move_index][MOVE_STARTING];
|
|
const int targetSquare = move_list[move_index][MOVE_TARGET];
|
|
const int piece = move_list[move_index][MOVE_PIECE];
|
|
const int tag = move_list[move_index][MOVE_TAG];
|
|
|
|
int captureIndex = -1;
|
|
|
|
#pragma region Makemove
|
|
|
|
is_white_global = !is_white_global;
|
|
switch (tag)
|
|
{
|
|
case TAG_NONE: //none
|
|
case TAG_CHECK: //check
|
|
bitboard_array_global[piece] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_CAPTURE: //capture
|
|
case TAG_CHECK_CAPTURE: //check cap
|
|
bitboard_array_global[piece] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
if (PieceIsWhite(piece) == true)
|
|
{
|
|
for (size_t i = BLACK_START_INDEX; i <= BLACK_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
}
|
|
else //is black
|
|
{
|
|
for (size_t i = WHITE_START_INDEX; i <= WHITE_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
}
|
|
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_WHITEEP: //white ep
|
|
//move piece
|
|
bitboard_array_global[WP] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[WP] &= ~SQUARE_BBS[startingSquare];
|
|
//remove
|
|
bitboard_array_global[BP] &= ~SQUARE_BBS[targetSquare + 8];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_BLACKEP: //black ep
|
|
//move piece
|
|
bitboard_array_global[BP] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[BP] &= ~SQUARE_BBS[startingSquare];
|
|
//remove white pawn square up
|
|
bitboard_array_global[WP] &= ~SQUARE_BBS[targetSquare - 8];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
|
|
#pragma region Castling
|
|
|
|
case TAG_WCASTLEKS: //WKS
|
|
//white king
|
|
bitboard_array_global[WK] |= SQUARE_BBS[G1];
|
|
bitboard_array_global[WK] &= ~SQUARE_BBS[E1];
|
|
//white rook
|
|
bitboard_array_global[WR] |= SQUARE_BBS[F1];
|
|
bitboard_array_global[WR] &= ~SQUARE_BBS[H1];
|
|
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
|
|
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_WCASTLEQS: //WQS
|
|
//white king
|
|
bitboard_array_global[WK] |= SQUARE_BBS[C1];
|
|
bitboard_array_global[WK] &= ~SQUARE_BBS[E1];
|
|
//white rook
|
|
bitboard_array_global[WR] |= SQUARE_BBS[D1];
|
|
bitboard_array_global[WR] &= ~SQUARE_BBS[A1];
|
|
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
|
|
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_BCASTLEKS: //BKS
|
|
//white king
|
|
bitboard_array_global[BK] |= SQUARE_BBS[G8];
|
|
bitboard_array_global[BK] &= ~SQUARE_BBS[E8];
|
|
//white rook
|
|
bitboard_array_global[BR] |= SQUARE_BBS[F8];
|
|
bitboard_array_global[BR] &= ~SQUARE_BBS[H8];
|
|
|
|
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
|
|
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_BCASTLEQS: //BQS
|
|
//white king
|
|
bitboard_array_global[BK] |= SQUARE_BBS[C8];
|
|
bitboard_array_global[BK] &= ~SQUARE_BBS[E8];
|
|
//white rook
|
|
bitboard_array_global[BR] |= SQUARE_BBS[D8];
|
|
bitboard_array_global[BR] &= ~SQUARE_BBS[A8];
|
|
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
|
|
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Promotion makemove
|
|
|
|
case TAG_BKnightPromotion: //BNPr
|
|
bitboard_array_global[BN] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_BBishopPromotion: //BBPr
|
|
bitboard_array_global[BB] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_BQueenPromotion: //BQPr
|
|
bitboard_array_global[BQ] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case TAG_BRookPromotion: //BRPr
|
|
bitboard_array_global[BR] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case 12: //WNPr
|
|
bitboard_array_global[WN] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case 13: //WBPr
|
|
bitboard_array_global[WB] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case 14: //WQPr
|
|
bitboard_array_global[WQ] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case 15: //WRPr
|
|
bitboard_array_global[WR] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
break;
|
|
case 16: //BNPrCAP
|
|
bitboard_array_global[BN] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = WHITE_START_INDEX; i <= WHITE_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case 17: //BBPrCAP
|
|
bitboard_array_global[BB] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = WHITE_START_INDEX; i <= WHITE_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case 18: //BQPrCAP
|
|
bitboard_array_global[BQ] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = WHITE_START_INDEX; i <= WHITE_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case 19: //BRPrCAP
|
|
bitboard_array_global[BR] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = WHITE_START_INDEX; i <= WHITE_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case 20: //WNPrCAP
|
|
bitboard_array_global[WN] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = BLACK_START_INDEX; i <= BLACK_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case 21: //WBPrCAP
|
|
bitboard_array_global[WB] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = BLACK_START_INDEX; i <= BLACK_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case 22: //WQPrCAP
|
|
bitboard_array_global[WQ] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = BLACK_START_INDEX; i <= BLACK_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case 23: //WRPrCAP
|
|
bitboard_array_global[WR] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
|
|
|
|
ep_global = NO_SQUARE;
|
|
for (size_t i = BLACK_START_INDEX; i <= BLACK_END_INDEX; ++i)
|
|
{
|
|
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0)
|
|
{
|
|
captureIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
|
|
#pragma endregion
|
|
|
|
case 24: //WDouble
|
|
bitboard_array_global[WP] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[WP] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = targetSquare + 8;
|
|
break;
|
|
case 25: //BDouble
|
|
bitboard_array_global[BP] |= SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[BP] &= ~SQUARE_BBS[startingSquare];
|
|
ep_global = targetSquare - 8;
|
|
break;
|
|
}
|
|
|
|
if (piece == WK)
|
|
{
|
|
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
|
|
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
|
|
}
|
|
else if (piece == BK)
|
|
{
|
|
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
|
|
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
|
|
}
|
|
else if (piece == WR)
|
|
{
|
|
if (castle_rights_global[WKS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if ((bitboard_array_global[WR] & SQUARE_BBS[H1]) == 0)
|
|
{
|
|
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
|
|
}
|
|
}
|
|
if (castle_rights_global[WQS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if ((bitboard_array_global[WR] & SQUARE_BBS[A1]) == 0)
|
|
{
|
|
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
|
|
}
|
|
}
|
|
}
|
|
else if (piece == BR)
|
|
{
|
|
if (castle_rights_global[BKS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if ((bitboard_array_global[BR] & SQUARE_BBS[H8]) == 0)
|
|
{
|
|
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
|
|
}
|
|
}
|
|
if (castle_rights_global[BQS_CASTLE_RIGHTS] == true)
|
|
{
|
|
if ((bitboard_array_global[BR] & SQUARE_BBS[A8]) == 0)
|
|
{
|
|
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
//priorNodes = nodes;
|
|
nodes += PerftInlineGlobal(depth - 1, ply + 1);
|
|
|
|
#pragma region Unmakemove
|
|
|
|
is_white_global = !is_white_global;
|
|
switch (tag)
|
|
{
|
|
case TAG_NONE: //none
|
|
case TAG_CHECK: //check
|
|
bitboard_array_global[piece] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case TAG_CAPTURE: //capture
|
|
case TAG_CHECK_CAPTURE: //check cap
|
|
bitboard_array_global[piece] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[piece] &= ~SQUARE_BBS[targetSquare];
|
|
if (PieceIsWhite(piece) == true)
|
|
{
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
}
|
|
else //is black
|
|
{
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
}
|
|
|
|
break;
|
|
case TAG_WHITEEP: //white ep
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WP] &= ~SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[BP] |= SQUARE_BBS[targetSquare + 8];
|
|
|
|
break;
|
|
case TAG_BLACKEP: //black ep
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BP] &= ~SQUARE_BBS[targetSquare];
|
|
bitboard_array_global[WP] |= SQUARE_BBS[targetSquare - 8];
|
|
|
|
break;
|
|
case TAG_WCASTLEKS: //WKS
|
|
//white king
|
|
bitboard_array_global[WK] |= SQUARE_BBS[E1];
|
|
bitboard_array_global[WK] &= ~SQUARE_BBS[G1];
|
|
//white rook
|
|
bitboard_array_global[WR] |= SQUARE_BBS[H1];
|
|
bitboard_array_global[WR] &= ~SQUARE_BBS[F1];
|
|
break;
|
|
case TAG_WCASTLEQS: //WQS
|
|
//white king
|
|
bitboard_array_global[WK] |= SQUARE_BBS[E1];
|
|
bitboard_array_global[WK] &= ~SQUARE_BBS[C1];
|
|
//white rook
|
|
bitboard_array_global[WR] |= SQUARE_BBS[A1];
|
|
bitboard_array_global[WR] &= ~SQUARE_BBS[D1];
|
|
break;
|
|
case TAG_BCASTLEKS: //BKS
|
|
//white king
|
|
bitboard_array_global[BK] |= SQUARE_BBS[E8];
|
|
bitboard_array_global[BK] &= ~SQUARE_BBS[G8];
|
|
//white rook
|
|
bitboard_array_global[BR] |= SQUARE_BBS[H8];
|
|
bitboard_array_global[BR] &= ~SQUARE_BBS[F8];
|
|
break;
|
|
case TAG_BCASTLEQS: //BQS
|
|
//white king
|
|
bitboard_array_global[BK] |= SQUARE_BBS[E8];
|
|
bitboard_array_global[BK] &= ~SQUARE_BBS[C8];
|
|
//white rook
|
|
bitboard_array_global[BR] |= SQUARE_BBS[A8];
|
|
bitboard_array_global[BR] &= ~SQUARE_BBS[D8];
|
|
|
|
break;
|
|
|
|
#pragma region Promotion Unmakemove
|
|
case TAG_BKnightPromotion: //BNPr
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BN] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_BBishopPromotion: //BBPr
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BB] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_BQueenPromotion: //BQPr
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BQ] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_BRookPromotion: //BRPr
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BR] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WKnightPromotion: //WNPr
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WN] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WBishopPromotion: //WBPr
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WB] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WQueenPromotion: //WQPr
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WQ] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WRookPromotion: //WRPr
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WR] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_BCaptureKnightPromotion: //BNPrCAP
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BN] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_BCaptureBishopPromotion: //BBPrCAP
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BB] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
|
|
break;
|
|
case TAG_BCaptureQueenPromotion: //BQPrCAP
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BQ] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_BCaptureRookPromotion: //BRPrCAP
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BR] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WCaptureKnightPromotion: //WNPrCAP
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WN] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WCaptureBishopPromotion: //WBPrCAP
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WB] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WCaptureQueenPromotion: //WQPrCAP
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WQ] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_WCaptureRookPromotion: //WRPrCAP
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WR] &= ~SQUARE_BBS[targetSquare];
|
|
|
|
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
|
|
break;
|
|
|
|
#pragma endregion
|
|
|
|
case TAG_DoublePawnWhite: //WDouble
|
|
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[WP] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
case TAG_DoublePawnBlack: //BDouble
|
|
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
|
|
bitboard_array_global[BP] &= ~SQUARE_BBS[targetSquare];
|
|
break;
|
|
}
|
|
|
|
castle_rights_global[0] = copy_castle[0];
|
|
castle_rights_global[1] = copy_castle[1];
|
|
castle_rights_global[2] = copy_castle[2];
|
|
castle_rights_global[3] = copy_castle[3];
|
|
ep_global = copyEp;
|
|
|
|
//if (epGlobal != NO_SQUARE)
|
|
//{
|
|
// std::cout << " ep: " << SQ_CHAR_X[epGlobal] << SQ_CHAR_Y[epGlobal] << '\n';
|
|
//}
|
|
|
|
#pragma endregion
|
|
|
|
//if (ply == 0)
|
|
//{
|
|
// PrintMoveNoNL(move_list[move_index]);
|
|
// printf(": %llu\n", nodes - priorNodes);
|
|
//}
|
|
}
|
|
|
|
return nodes;
|
|
}
|
|
|
|
|
|
void RunPerftInlineGlobal(const int depth)
|
|
{
|
|
CopyGlobalBoardGlobal();
|
|
|
|
clock_t start_time = clock(); // Get the initial time
|
|
|
|
unsigned long long nodes = PerftInlineGlobal(depth, 0);
|
|
|
|
clock_t end_time = clock();
|
|
double elapsed_milliseconds = (double)(end_time - start_time) * 1000.0 / CLOCKS_PER_SEC;
|
|
printf("Nodes: %llu\n", nodes);
|
|
printf("Elapsed time: %.2f milliseconds\n", elapsed_milliseconds);
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
CreateBoard();
|
|
|
|
//std::cin.get();
|
|
ParseFenGlobal(FEN_STARTING_POSITION, 0);
|
|
RunPerftInlineGlobal(6);
|
|
|
|
return 0;
|
|
}
|