public static bool IsInCheck(int kingIndex, int colorToMove, long[] enemyPieces, long allPieces) { // put 'super-piece' in kings position return(((enemyPieces[Knight] & StaticMoves.KnightMoves[kingIndex]) | ((enemyPieces[Rook] | enemyPieces[Queen]) & MagicUtil.GetRookMoves(kingIndex, allPieces)) | ((enemyPieces[Bishop] | enemyPieces[Queen]) & MagicUtil.GetBishopMoves(kingIndex, allPieces)) | (enemyPieces[Pawn] & StaticMoves.PawnAttacks[colorToMove][kingIndex]) ) != 0); }
private static int Checks(ChessBoard cb, int kingColor) { var kingIndex = cb.KingIndex[kingColor]; var enemyColor = 1 - kingColor; var notDefended = ~cb.Attacks[kingColor][All]; var unOccupied = ~cb.Pieces[enemyColor][All]; var unsafeKingMoves = StaticMoves.KingMoves[kingIndex] & cb.DoubleAttacks[enemyColor] & ~cb.DoubleAttacks[kingColor]; var counter = 0; if (cb.Pieces[enemyColor][Knight] != 0) { counter += CheckMinor(notDefended, StaticMoves.KnightMoves[kingIndex] & unOccupied & cb.Attacks[enemyColor][Knight]); } long moves; long queenMoves = 0; if ((cb.Pieces[enemyColor][Queen] | cb.Pieces[enemyColor][Bishop]) != 0) { moves = MagicUtil.GetBishopMoves(kingIndex, cb.AllPieces ^ cb.Pieces[kingColor][Queen]) & unOccupied; queenMoves = moves; counter += CheckMinor(notDefended, moves & cb.Attacks[enemyColor][Bishop]); } if ((cb.Pieces[enemyColor][Queen] | cb.Pieces[enemyColor][Rook]) != 0) { moves = MagicUtil.GetRookMoves(kingIndex, cb.AllPieces ^ cb.Pieces[kingColor][Queen]) & unOccupied; queenMoves |= moves; counter += CheckRook(cb, kingColor, moves & cb.Attacks[enemyColor][Rook], unsafeKingMoves | notDefended); } queenMoves &= cb.Attacks[enemyColor][Queen]; if (queenMoves == 0) { return(counter); } // safe check queen if ((queenMoves & notDefended) != 0) { counter += EvalConstants.KsCheckQueen[BitOperations.PopCount((ulong)cb.Pieces[kingColor][All])]; } // safe check queen touch if ((queenMoves & unsafeKingMoves) != 0) { counter += EvalConstants.KsOther[0]; } return(counter); }
private static int GetSmallestAttackSeeMove(long[] pieces, int colorToMove, int toIndex, long allPieces, long slidingMask) { // TODO stop when bad-capture // put 'super-piece' in see position // pawn non-promotion attacks var attackMove = StaticMoves.PawnAttacks[1 - colorToMove][toIndex] & pieces[Pawn] & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } // knight attacks attackMove = pieces[Knight] & StaticMoves.KnightMoves[toIndex] & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } // bishop attacks if ((pieces[Bishop] & slidingMask) != 0) { attackMove = pieces[Bishop] & MagicUtil.GetBishopMoves(toIndex, allPieces) & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } } // rook attacks if ((pieces[Rook] & slidingMask) != 0) { attackMove = pieces[Rook] & MagicUtil.GetRookMoves(toIndex, allPieces) & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } } // queen attacks if ((pieces[Queen] & slidingMask) != 0) { attackMove = pieces[Queen] & MagicUtil.GetQueenMoves(toIndex, allPieces) & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } } // king attacks attackMove = pieces[King] & StaticMoves.KingMoves[toIndex]; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } return(-1); }
public static int CalculateMobilityScoresAndSetAttacks(ChessBoard cb) { cb.ClearEvalAttacks(); for (var color = White; color <= Black; color++) { var kingArea = KingArea[cb.KingIndex[1 - color]]; var piece = cb.Pieces[color][Pawn] & ~cb.PinnedPieces; while (piece != 0) { cb.UpdatePawnAttacks(StaticMoves.PawnAttacks[color][BitOperations.TrailingZeroCount(piece)], color); piece &= piece - 1; } cb.UpdatePawnAttacks(color, kingArea); piece = cb.Pieces[color][Pawn] & cb.PinnedPieces; while (piece != 0) { cb.UpdateAttacks(StaticMoves.PawnAttacks[color][BitOperations.TrailingZeroCount(piece)] & PinnedMovement[BitOperations.TrailingZeroCount(piece)][cb.KingIndex[color]], Pawn, color, kingArea); piece &= piece - 1; } } var score = 0; long moves; for (var color = White; color <= Black; color++) { var tempScore = 0; var kingArea = KingArea[cb.KingIndex[1 - color]]; var safeMoves = ~cb.Pieces[color][All] & ~cb.Attacks[1 - color][Pawn]; // knights var piece = cb.Pieces[color][Knight] & ~cb.PinnedPieces; while (piece != 0) { moves = StaticMoves.KnightMoves[BitOperations.TrailingZeroCount(piece)]; cb.UpdateAttacks(moves, Knight, color, kingArea); tempScore += EvalConstants.MobilityKnight[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } // bishops piece = cb.Pieces[color][Bishop]; while (piece != 0) { moves = MagicUtil.GetBishopMoves(BitOperations.TrailingZeroCount(piece), cb.AllPieces ^ cb.Pieces[color][Queen]); cb.UpdateAttacks(moves, Bishop, color, kingArea); tempScore += EvalConstants.MobilityBishop[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } // rooks piece = cb.Pieces[color][Rook]; while (piece != 0) { moves = MagicUtil.GetRookMoves(BitOperations.TrailingZeroCount(piece), cb.AllPieces ^ cb.Pieces[color][Rook] ^ cb.Pieces[color][Queen]); cb.UpdateAttacks(moves, Rook, color, kingArea); tempScore += EvalConstants.MobilityRook[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } // queens piece = cb.Pieces[color][Queen]; while (piece != 0) { moves = MagicUtil.GetQueenMoves(BitOperations.TrailingZeroCount(piece), cb.AllPieces); cb.UpdateAttacks(moves, Queen, color, kingArea); tempScore += EvalConstants.MobilityQueen[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } score += tempScore * ColorFactor[color]; } // TODO king-attacks with or without enemy attacks? // WHITE king moves = StaticMoves.KingMoves[cb.KingIndex[White]] & ~StaticMoves.KingMoves[cb.KingIndex[Black]]; cb.Attacks[White][King] = moves; cb.DoubleAttacks[White] |= cb.Attacks[White][All] & moves; cb.Attacks[White][All] |= moves; score += EvalConstants.MobilityKing[ BitOperations.PopCount((ulong)(moves & ~cb.Pieces[White][All] & ~cb.Attacks[Black][All]))]; // BLACK king moves = StaticMoves.KingMoves[cb.KingIndex[Black]] & ~StaticMoves.KingMoves[cb.KingIndex[White]]; cb.Attacks[Black][King] = moves; cb.DoubleAttacks[Black] |= cb.Attacks[Black][All] & moves; cb.Attacks[Black][All] |= moves; score -= EvalConstants.MobilityKing[ BitOperations.PopCount((ulong)(moves & ~cb.Pieces[Black][All] & ~cb.Attacks[White][All]))]; return(score); }