mirror of
https://github.com/OMGeeky/hcsalmon1-Chess-Engine-Test.git
synced 2026-01-06 10:49:32 +01:00
Create GenMoves.cs
This commit is contained in:
693
C#/Cleaner and slower version/GenMoves.cs
Normal file
693
C#/Cleaner and slower version/GenMoves.cs
Normal file
@@ -0,0 +1,693 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static CEngineCopy.Constants;
|
||||
using static CEngineCopy.Board;
|
||||
using static CEngineCopy.MoveUtils;
|
||||
|
||||
|
||||
namespace CEngineCopy
|
||||
{
|
||||
internal class GenMoves
|
||||
{
|
||||
|
||||
|
||||
static int[] pinArrayPiece = new int[8];
|
||||
static int[] pinArraySquare = new int[8];
|
||||
|
||||
|
||||
public static int GetMoves(ref Span<int> startingSquares, ref Span<int> targetSquares, ref Span<int> tags, ref Span<int> pieces)
|
||||
{
|
||||
int moveCount = 0;
|
||||
|
||||
//Move generating variables
|
||||
ulong WHITE_OCCUPANCIES_LOCAL = Board.bitboard_array_global[0] | Board.bitboard_array_global[1] | Board.bitboard_array_global[2] | Board.bitboard_array_global[3] | Board.bitboard_array_global[4] | Board.bitboard_array_global[5];
|
||||
ulong BLACK_OCCUPANCIES_LOCAL = Board.bitboard_array_global[6] | Board.bitboard_array_global[7] | Board.bitboard_array_global[8] | Board.bitboard_array_global[9] | Board.bitboard_array_global[10] | Board.bitboard_array_global[11];
|
||||
ulong COMBINED_OCCUPANCIES_LOCAL = WHITE_OCCUPANCIES_LOCAL | BLACK_OCCUPANCIES_LOCAL;
|
||||
ulong EMPTY_OCCUPANCIES = ~COMBINED_OCCUPANCIES_LOCAL;
|
||||
ulong tempBitboard, checkBitboard = 0UL, tempPinBitboard, tempAttack, tempEmpty, tempCaptures;
|
||||
int startingSquare = NO_SQUARE, targetSquare = NO_SQUARE;
|
||||
|
||||
ulong enemyOccupancies;
|
||||
int knightIndex, bishopIndex, queenIndex, rookIndex;
|
||||
int kingPosition, checkCount = 0;
|
||||
|
||||
int pinNumber = 0;
|
||||
|
||||
#region Generate Moves
|
||||
|
||||
if (Board.is_white_global == true)
|
||||
{
|
||||
kingPosition = BitScanForward(Board.bitboard_array_global[WK]);
|
||||
enemyOccupancies = BLACK_OCCUPANCIES_LOCAL;
|
||||
knightIndex = WN;
|
||||
rookIndex = WR;
|
||||
bishopIndex = WB;
|
||||
queenIndex = WQ;
|
||||
|
||||
GetWhitePinsAndCheck(ref checkBitboard, ref checkCount, kingPosition, BLACK_OCCUPANCIES_LOCAL, WHITE_OCCUPANCIES_LOCAL, ref pinNumber);
|
||||
|
||||
#region White king
|
||||
|
||||
ulong occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES_LOCAL & (~Board.bitboard_array_global[WK]);
|
||||
tempAttack = Constants.KING_ATTACKS[kingPosition];
|
||||
tempEmpty = tempAttack & EMPTY_OCCUPANCIES;
|
||||
while (tempEmpty != 0)
|
||||
{
|
||||
targetSquare = BitScanForward(tempEmpty);
|
||||
tempEmpty &= tempEmpty - 1;
|
||||
|
||||
if (Is_Square_Attacked_By_Black_Global(targetSquare, occupanciesWithoutWhiteKing) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, kingPosition, targetSquare, WK, TAG_NONE);
|
||||
}
|
||||
|
||||
//captures
|
||||
tempCaptures = tempAttack & BLACK_OCCUPANCIES_LOCAL;
|
||||
while (tempCaptures != 0)
|
||||
{
|
||||
targetSquare = BitScanForward(tempCaptures);
|
||||
tempCaptures &= tempCaptures - 1;
|
||||
|
||||
if (Is_Square_Attacked_By_Black_Global(targetSquare, occupanciesWithoutWhiteKing) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, kingPosition, targetSquare, WK, TAG_CAPTURE);
|
||||
}
|
||||
|
||||
#endregion end white king
|
||||
|
||||
if (checkCount < 2)
|
||||
{
|
||||
if (checkCount == 0)
|
||||
{
|
||||
checkBitboard = ulong.MaxValue;
|
||||
|
||||
if (kingPosition == E1) //king on e1
|
||||
{
|
||||
if (CanWhiteCastleKingside(COMBINED_OCCUPANCIES_LOCAL) == true)
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, E1, G1, WK, TAG_W_CASTLE_KS);
|
||||
}
|
||||
if (CanWhiteCastleQueenside(COMBINED_OCCUPANCIES_LOCAL) == true)
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, E1, C1, WK, TAG_W_CASTLE_QS);
|
||||
}
|
||||
}
|
||||
}
|
||||
GetWhitePawnMoves(pinNumber, kingPosition, COMBINED_OCCUPANCIES_LOCAL, BLACK_OCCUPANCIES_LOCAL, checkBitboard, ref startingSquares, ref targetSquares, ref tags, ref pieces, ref moveCount);
|
||||
}
|
||||
}
|
||||
else //black move
|
||||
{
|
||||
kingPosition = BitScanForward(Board.bitboard_array_global[BK]);
|
||||
enemyOccupancies = WHITE_OCCUPANCIES_LOCAL;
|
||||
knightIndex = BN;
|
||||
rookIndex = BR;
|
||||
bishopIndex = BB;
|
||||
queenIndex = BQ;
|
||||
|
||||
GetBlackPinsAndCheck(ref checkBitboard, ref checkCount, kingPosition, BLACK_OCCUPANCIES_LOCAL, WHITE_OCCUPANCIES_LOCAL, ref pinNumber);
|
||||
|
||||
#region Black king
|
||||
ulong occupancyWithoutBlackKing = COMBINED_OCCUPANCIES_LOCAL & (~Board.bitboard_array_global[BK]);
|
||||
|
||||
tempAttack = Constants.KING_ATTACKS[kingPosition] & WHITE_OCCUPANCIES_LOCAL;
|
||||
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58];
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
if (MoveUtils.Is_Square_Attacked_By_White_Global(targetSquare, occupancyWithoutBlackKing) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, kingPosition, targetSquare, BK, Constants.TAG_CAPTURE);
|
||||
}
|
||||
|
||||
tempAttack = Constants.KING_ATTACKS[kingPosition] & ~COMBINED_OCCUPANCIES_LOCAL;
|
||||
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58];
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
if (MoveUtils.Is_Square_Attacked_By_White_Global(targetSquare, occupancyWithoutBlackKing) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, kingPosition, targetSquare, BK, TAG_NONE);
|
||||
}
|
||||
#endregion
|
||||
|
||||
if (checkCount < 2)
|
||||
{
|
||||
if (checkCount == 0)
|
||||
{
|
||||
checkBitboard = ulong.MaxValue;
|
||||
|
||||
if (kingPosition == E8) //king on e1
|
||||
{
|
||||
if (CanBlackCastleKingside(COMBINED_OCCUPANCIES_LOCAL) == true)
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, E8, G8, BK, TAG_B_CASTLE_KS);
|
||||
}
|
||||
if (CanBlackCastleQueenside(COMBINED_OCCUPANCIES_LOCAL) == true)
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, E8, C8, BK, TAG_B_CASTLE_QS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetBlackPawnMoves(pinNumber, kingPosition, COMBINED_OCCUPANCIES_LOCAL, WHITE_OCCUPANCIES_LOCAL, checkBitboard, ref startingSquares, ref targetSquares, ref tags, ref pieces, ref moveCount);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#region knight
|
||||
|
||||
tempBitboard = Board.bitboard_array_global[knightIndex];
|
||||
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
startingSquare = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
tempBitboard &= tempBitboard - 1; //removes the knight from that square to not infinitely loop
|
||||
|
||||
tempPinBitboard = GetPinBitboard(pinNumber, startingSquare, kingPosition);
|
||||
|
||||
tempAttack = ((Constants.KNIGHT_ATTACKS[startingSquare] & enemyOccupancies) & checkBitboard) & tempPinBitboard; //gets knight captures
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = (DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58]);
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
|
||||
startingSquares[moveCount] = startingSquare;
|
||||
targetSquares[moveCount] = targetSquare;
|
||||
tags[moveCount] = TAG_CAPTURE;
|
||||
pieces[moveCount] = knightIndex;
|
||||
moveCount++;
|
||||
|
||||
}
|
||||
|
||||
tempAttack = ((Constants.KNIGHT_ATTACKS[startingSquare] & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard;
|
||||
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58];
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
startingSquares[moveCount] = startingSquare;
|
||||
targetSquares[moveCount] = targetSquare;
|
||||
tags[moveCount] = TAG_NONE;
|
||||
pieces[moveCount] = knightIndex;
|
||||
moveCount++;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Rook
|
||||
|
||||
tempBitboard = Board.bitboard_array_global[rookIndex];
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
startingSquare = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
|
||||
tempPinBitboard = GetPinBitboard(pinNumber, startingSquare, kingPosition);
|
||||
|
||||
ulong rookAttacks = Constants.GetRookAttacksFast(startingSquare, COMBINED_OCCUPANCIES_LOCAL);
|
||||
|
||||
tempAttack = ((rookAttacks & enemyOccupancies) & checkBitboard) & tempPinBitboard;
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = (DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58]);
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
startingSquares[moveCount] = startingSquare;
|
||||
targetSquares[moveCount] = targetSquare;
|
||||
tags[moveCount] = TAG_CAPTURE;
|
||||
pieces[moveCount] = rookIndex;
|
||||
moveCount++;
|
||||
}
|
||||
|
||||
tempAttack = ((rookAttacks & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard;
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = (DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58]);
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
startingSquares[moveCount] = startingSquare;
|
||||
targetSquares[moveCount] = targetSquare;
|
||||
tags[moveCount] = TAG_NONE;
|
||||
pieces[moveCount] = rookIndex;
|
||||
moveCount++;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Bishop
|
||||
|
||||
tempBitboard = Board.bitboard_array_global[bishopIndex];
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
startingSquare = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
|
||||
tempPinBitboard = GetPinBitboard(pinNumber, startingSquare, kingPosition);
|
||||
|
||||
ulong bishopAttacks = Constants.GetBishopAttacksFast(startingSquare, COMBINED_OCCUPANCIES_LOCAL);
|
||||
|
||||
tempAttack = ((bishopAttacks & enemyOccupancies) & checkBitboard) & tempPinBitboard;
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58];
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, bishopIndex, TAG_CAPTURE);
|
||||
}
|
||||
|
||||
tempAttack = ((bishopAttacks & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard;
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58];
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, bishopIndex, TAG_NONE);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Queen
|
||||
|
||||
tempBitboard = Board.bitboard_array_global[queenIndex];
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
startingSquare = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
|
||||
tempPinBitboard = GetPinBitboard(pinNumber, startingSquare, kingPosition);
|
||||
|
||||
ulong queenAttacks = Constants.GetRookAttacksFast(startingSquare, COMBINED_OCCUPANCIES_LOCAL);
|
||||
queenAttacks |= Constants.GetBishopAttacksFast(startingSquare, COMBINED_OCCUPANCIES_LOCAL);
|
||||
|
||||
tempAttack = ((queenAttacks & enemyOccupancies) & checkBitboard) & tempPinBitboard;
|
||||
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58];
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, queenIndex, TAG_CAPTURE);
|
||||
}
|
||||
|
||||
tempAttack = ((queenAttacks & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard;
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
targetSquare = DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58];
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, queenIndex, TAG_NONE);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
return moveCount;
|
||||
|
||||
}
|
||||
|
||||
public static void GetWhitePawnMoves(int pinNumber, int kingPosition, ulong COMBINED_OCCUPANCIES_LOCAL, ulong BLACK_OCCUPANCIES_LOCAL, ulong checkBitboard, ref Span<int> startingSquares, ref Span<int> targetSquares, ref Span<int> tags, ref Span<int> pieces, ref int moveCount)
|
||||
{
|
||||
ulong tempBitboard = bitboard_array_global[WP];
|
||||
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
int startingSquare = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
|
||||
ulong tempPinBitboard = GetPinBitboard(pinNumber, startingSquare, kingPosition);
|
||||
|
||||
#region Pawn forward
|
||||
|
||||
if ((SQUARE_BBS[startingSquare - 8] & COMBINED_OCCUPANCIES_LOCAL) == 0) //if up one square is empty
|
||||
{
|
||||
if (((SQUARE_BBS[startingSquare - 8] & checkBitboard) & tempPinBitboard) != 0)
|
||||
{
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_7_BITBOARD) != 0) //if promotion
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare - 8, WP, TAG_W_Q_PROMOTION);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare - 8, WP, TAG_W_R_PROMOTION);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare - 8, WP, TAG_W_N_PROMOTION);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare - 8, WP, TAG_W_B_PROMOTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare - 8, WP, TAG_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_2_BITBOARD) != 0) //if on rank 2
|
||||
{
|
||||
if (((SQUARE_BBS[startingSquare - 16] & checkBitboard) & tempPinBitboard) != 0) //if not pinned or
|
||||
{
|
||||
if (((SQUARE_BBS[startingSquare - 16]) & COMBINED_OCCUPANCIES_LOCAL) == 0) //if up two squares and one square are empty
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare - 16, WP, TAG_W_P_DOUBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Pawn captures
|
||||
|
||||
ulong tempAttack = ((WHITE_PAWN_ATTACKS[startingSquare] & BLACK_OCCUPANCIES_LOCAL) & checkBitboard) & tempPinBitboard; //if black piece diagonal to pawn
|
||||
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
int targetSquare = (DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58]);
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_7_BITBOARD) != 0) //if promotion
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, WP, TAG_W_Q_PROMOTION_CAP);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, WP, TAG_W_R_PROMOTION_CAP);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, WP, TAG_W_N_PROMOTION_CAP);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, WP, TAG_W_B_PROMOTION_CAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, WP, TAG_CAPTURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_5_BITBOARD) == 0) //check rank for ep
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (ep_global == NO_SQUARE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((((WHITE_PAWN_ATTACKS[startingSquare] & SQUARE_BBS[ep_global]) & checkBitboard) & tempPinBitboard) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((bitboard_array_global[WK] & RANK_5_BITBOARD) == 0) //if no king on rank 5
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, ep_global, WP, TAG_WHITE_EP);
|
||||
continue;
|
||||
}
|
||||
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
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, ep_global, WP, TAG_WHITE_EP);
|
||||
continue;
|
||||
}
|
||||
|
||||
ulong occupancyWithoutEPPawns = COMBINED_OCCUPANCIES_LOCAL & ~SQUARE_BBS[startingSquare];
|
||||
occupancyWithoutEPPawns &= ~SQUARE_BBS[ep_global + 8];
|
||||
|
||||
ulong rookAttacksFromKing = GetRookAttacksFast(kingPosition, occupancyWithoutEPPawns);
|
||||
|
||||
if ((rookAttacksFromKing & bitboard_array_global[BR]) == 0)
|
||||
{
|
||||
if ((rookAttacksFromKing & bitboard_array_global[BQ]) == 0)
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, ep_global, WP, TAG_WHITE_EP);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetWhitePinsAndCheck(ref ulong checkBitboard, ref int checkCount, int kingPosition, ulong BLACK_OCCUPANCIES_LOCAL, ulong WHITE_OCCUPANCIES_LOCAL, ref int pinNumber)
|
||||
{
|
||||
//pawns
|
||||
ulong tempBitboard = bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[kingPosition];
|
||||
if (tempBitboard != 0)
|
||||
{
|
||||
int pawn_square = (DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58]);
|
||||
checkBitboard = SQUARE_BBS[pawn_square];
|
||||
checkCount++;
|
||||
}
|
||||
|
||||
//knights
|
||||
tempBitboard = bitboard_array_global[BN] & KNIGHT_ATTACKS[kingPosition];
|
||||
if (tempBitboard != 0)
|
||||
{
|
||||
int knight_square = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
checkBitboard = SQUARE_BBS[knight_square];
|
||||
checkCount++;
|
||||
}
|
||||
|
||||
//bishops
|
||||
ulong bishopAttacksChecks = GetBishopAttacksFast(kingPosition, BLACK_OCCUPANCIES_LOCAL);
|
||||
tempBitboard = bitboard_array_global[BB] & bishopAttacksChecks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, WHITE_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
|
||||
//queen bishop moves
|
||||
tempBitboard = bitboard_array_global[BQ] & bishopAttacksChecks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, WHITE_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
|
||||
//rook
|
||||
ulong rook_attacks = GetRookAttacksFast(kingPosition, BLACK_OCCUPANCIES_LOCAL);
|
||||
tempBitboard = bitboard_array_global[BR] & rook_attacks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, WHITE_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
|
||||
//queen rook moves
|
||||
tempBitboard = bitboard_array_global[BQ] & rook_attacks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, WHITE_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void GetBlackPawnMoves(int pinNumber, int kingPosition, ulong COMBINED_OCCUPANCIES_LOCAL, ulong WHITE_OCCUPANCIES_LOCAL, ulong checkBitboard, ref Span<int> startingSquares, ref Span<int> targetSquares, ref Span<int> tags, ref Span<int> pieces, ref int moveCount)
|
||||
{
|
||||
ulong tempBitboard = bitboard_array_global[BP];
|
||||
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
int startingSquare = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
|
||||
ulong tempPinBitboard = GetPinBitboard(pinNumber, startingSquare, kingPosition);
|
||||
|
||||
#region Pawn forward
|
||||
|
||||
if ((SQUARE_BBS[startingSquare + 8] & COMBINED_OCCUPANCIES_LOCAL) == 0) //if up one square is empty
|
||||
{
|
||||
if (((SQUARE_BBS[startingSquare + 8] & checkBitboard) & tempPinBitboard) != 0)
|
||||
{
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_2_BITBOARD) != 0) //if promotion
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare + 8, BP, TAG_B_Q_PROMOTION);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare + 8, BP, TAG_B_R_PROMOTION);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare + 8, BP, TAG_B_N_PROMOTION);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare + 8, BP, TAG_B_B_PROMOTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare + 8, BP, TAG_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_7_BITBOARD) != 0) //if on rank 2
|
||||
{
|
||||
if (((SQUARE_BBS[startingSquare + 16] & checkBitboard) & tempPinBitboard) != 0) //if not pinned or
|
||||
{
|
||||
if (((SQUARE_BBS[startingSquare + 16]) & COMBINED_OCCUPANCIES_LOCAL) == 0) //if up two squares and one square are empty
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, startingSquare + 16, BP, TAG_B_P_DOUBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Pawn captures
|
||||
|
||||
ulong tempAttack = ((BLACK_PAWN_ATTACKS[startingSquare] & WHITE_OCCUPANCIES_LOCAL) & checkBitboard) & tempPinBitboard; //if black piece diagonal to pawn
|
||||
|
||||
while (tempAttack != 0)
|
||||
{
|
||||
int targetSquare = (DEBRUIJN64[MAGIC * (tempAttack ^ (tempAttack - 1)) >> 58]);
|
||||
tempAttack &= tempAttack - 1;
|
||||
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_2_BITBOARD) != 0) //if promotion
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, BP, TAG_B_Q_PROMOTION_CAP);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, BP, TAG_B_R_PROMOTION_CAP);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, BP, TAG_B_N_PROMOTION_CAP);
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, BP, TAG_B_B_PROMOTION_CAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, targetSquare, BP, TAG_CAPTURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((SQUARE_BBS[startingSquare] & RANK_4_BITBOARD) == 0) //check rank for ep
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (ep_global == NO_SQUARE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((((BLACK_PAWN_ATTACKS[startingSquare] & SQUARE_BBS[ep_global]) & checkBitboard) & tempPinBitboard) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((bitboard_array_global[BK] & RANK_4_BITBOARD) == 0) //if no king on rank 5
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, ep_global, BP, TAG_BLACK_EP);
|
||||
continue;
|
||||
}
|
||||
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
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, ep_global, BP, TAG_BLACK_EP);
|
||||
continue;
|
||||
}
|
||||
//wk and br or bq on rank 5
|
||||
|
||||
ulong occupancyWithoutEPPawns = COMBINED_OCCUPANCIES_LOCAL & ~SQUARE_BBS[startingSquare];
|
||||
occupancyWithoutEPPawns &= ~SQUARE_BBS[ep_global - 8];
|
||||
|
||||
ulong rookAttacksFromKing = GetRookAttacksFast(kingPosition, occupancyWithoutEPPawns);
|
||||
|
||||
if ((rookAttacksFromKing & bitboard_array_global[WR]) == 0)
|
||||
{
|
||||
if ((rookAttacksFromKing & bitboard_array_global[WQ]) == 0)
|
||||
{
|
||||
AddMove(ref moveCount, ref startingSquares, ref targetSquares, ref tags, ref pieces, startingSquare, ep_global, BP, TAG_BLACK_EP);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetBlackPinsAndCheck(ref ulong checkBitboard, ref int checkCount, int kingPosition, ulong BLACK_OCCUPANCIES_LOCAL, ulong WHITE_OCCUPANCIES_LOCAL, ref int pinNumber)
|
||||
{
|
||||
//pawns
|
||||
ulong tempBitboard = bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[kingPosition];
|
||||
if (tempBitboard != 0)
|
||||
{
|
||||
int pawn_square = (DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58]);
|
||||
checkBitboard = SQUARE_BBS[pawn_square];
|
||||
checkCount++;
|
||||
}
|
||||
|
||||
//knights
|
||||
tempBitboard = bitboard_array_global[WN] & KNIGHT_ATTACKS[kingPosition];
|
||||
if (tempBitboard != 0)
|
||||
{
|
||||
int knight_square = DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58];
|
||||
checkBitboard = SQUARE_BBS[knight_square];
|
||||
checkCount++;
|
||||
}
|
||||
|
||||
//bishops
|
||||
ulong bishopAttacksChecks = GetBishopAttacksFast(kingPosition, WHITE_OCCUPANCIES_LOCAL);
|
||||
tempBitboard = bitboard_array_global[WB] & bishopAttacksChecks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, BLACK_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
|
||||
//queen bishop moves
|
||||
tempBitboard = bitboard_array_global[WQ] & bishopAttacksChecks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, BLACK_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
|
||||
//rook
|
||||
ulong rook_attacks = GetRookAttacksFast(kingPosition, WHITE_OCCUPANCIES_LOCAL);
|
||||
tempBitboard = bitboard_array_global[WR] & rook_attacks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, BLACK_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
|
||||
//queen rook moves
|
||||
tempBitboard = bitboard_array_global[WQ] & rook_attacks;
|
||||
while (tempBitboard != 0)
|
||||
{
|
||||
CheckPinOrCheck(ref checkBitboard, ref checkCount, kingPosition, BLACK_OCCUPANCIES_LOCAL, ref pinNumber, tempBitboard);
|
||||
tempBitboard &= tempBitboard - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ulong GetPinBitboard(int pinNumber, int startingSquare, int kingPosition)
|
||||
{
|
||||
ulong pinBitboard = ulong.MaxValue;
|
||||
if (pinNumber != 0)
|
||||
{
|
||||
for (int i = 0; i < pinNumber; i++)
|
||||
{
|
||||
if (pinArraySquare[i] == startingSquare)
|
||||
{
|
||||
pinBitboard = INBETWEEN_BITBOARDS[kingPosition, pinArrayPiece[i]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pinBitboard;
|
||||
}
|
||||
|
||||
public static void CheckPinOrCheck(ref ulong checkBitboard, ref int checkCount, int kingPosition, ulong OCCUPANCIES, ref int pinNumber, ulong tempBitboard)
|
||||
{
|
||||
ulong tempPinBitboard;
|
||||
int piece_square = (DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58]);
|
||||
|
||||
tempPinBitboard = Constants.INBETWEEN_BITBOARDS[kingPosition, piece_square] & OCCUPANCIES;
|
||||
|
||||
if (tempPinBitboard == 0)
|
||||
{
|
||||
checkBitboard = Constants.INBETWEEN_BITBOARDS[kingPosition, piece_square];
|
||||
checkCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
int pinned_square = (DEBRUIJN64[MAGIC * (tempPinBitboard ^ (tempPinBitboard - 1)) >> 58]);
|
||||
tempPinBitboard &= tempPinBitboard - 1;
|
||||
|
||||
if (tempPinBitboard == 0)
|
||||
{
|
||||
pinArraySquare[pinNumber] = pinned_square;
|
||||
pinArrayPiece[pinNumber] = piece_square;
|
||||
pinNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user