/// <summary> /// Calculates castling moves. /// </summary> /// <param name="generatorParameters">The generator parameters.</param> private void CalculateCastling(GeneratorParameters generatorParameters) { if ((generatorParameters.Mode & GeneratorMode.CalculateMoves) != 0) { KingMovesGenerator.CalculateCastling(generatorParameters); } }
public static int GetAvailableCaptureMoves(BoardState boardState, Span <Move> moves, int offset) { var color = boardState.ColorToMove; var enemyColor = ColorOperations.Invert(color); var piece = boardState.Pieces[color][Piece.King]; if (piece == 0) { return(offset); } var from = BitOperations.BitScan(piece); var availableMoves = KingMovesGenerator.GetMoves(from) & boardState.Occupancy[enemyColor]; while (availableMoves != 0) { var field = BitOperations.GetLsb(availableMoves); var fieldIndex = BitOperations.BitScan(field); availableMoves = BitOperations.PopLsb(availableMoves); moves[offset++] = new Move(from, fieldIndex, MoveFlags.Capture); } return(offset); }
public byte GetAttackingPiecesWithColor(int color, int fieldIndex) { byte result = 0; var jumpAttacks = KnightMovesGenerator.GetMoves(fieldIndex); var attackingKnights = jumpAttacks & Pieces[color][Piece.Knight]; var attackingKnightsCount = BitOperations.Count(attackingKnights); if (attackingKnightsCount != 0) { result |= (byte)((attackingKnightsCount == 1 ? 1 : 3) << SeePiece.Knight1); } var diagonalAttacks = BishopMovesGenerator.GetMoves(OccupancySummary, fieldIndex) & Occupancy[color]; var attackingBishops = diagonalAttacks & Pieces[color][Piece.Bishop]; if (attackingBishops != 0) { result |= 1 << SeePiece.Bishop; } var occupancyWithoutFileRankPieces = OccupancySummary & ~Pieces[color][Piece.Rook] & ~Pieces[color][Piece.Queen]; var fileRankAttacks = RookMovesGenerator.GetMoves(occupancyWithoutFileRankPieces, fieldIndex) & Occupancy[color]; var attackingRooks = fileRankAttacks & Pieces[color][Piece.Rook]; var attackingRooksCount = BitOperations.Count(attackingRooks); if (attackingRooksCount != 0) { result |= (byte)((attackingRooksCount == 1 ? 1 : 3) << SeePiece.Rook1); } var attackingQueens = (fileRankAttacks | diagonalAttacks) & Pieces[color][Piece.Queen]; if (attackingQueens != 0) { result |= 1 << SeePiece.Queen; } var boxAttacks = KingMovesGenerator.GetMoves(fieldIndex); var attackingKings = boxAttacks & Pieces[color][Piece.King]; if (attackingKings != 0) { result |= 1 << SeePiece.King; } var field = 1ul << fieldIndex; var potentialPawns = boxAttacks & Pieces[color][Piece.Pawn]; var attackingPawns = color == Color.White ? field & ((potentialPawns << 7) | (potentialPawns << 9)) : field & ((potentialPawns >> 7) | (potentialPawns >> 9)); if (attackingPawns != 0) { result |= 1 << SeePiece.Pawn; } return(result); }
/// <summary> /// Calculates available moves. /// </summary> /// <param name="generatorParameters">The generator parameters.</param> private void CalculateAvailableMoves(GeneratorParameters generatorParameters) { PawnMovesGenerator.Generate(generatorParameters); KnightMovesGenerator.Generate(generatorParameters); KingMovesGenerator.Generate(generatorParameters); RookMovesGenerator.Generate(PieceType.Rook, generatorParameters); BishopMovesGenerator.Generate(PieceType.Bishop, generatorParameters); RookMovesGenerator.Generate(PieceType.Queen, generatorParameters); BishopMovesGenerator.Generate(PieceType.Queen, generatorParameters); }
public static int GetLoudMoves(BoardState boardState, Span <Move> moves, int offset) { var color = boardState.ColorToMove; var enemyColor = ColorOperations.Invert(color); var piece = boardState.Pieces[color][Piece.King]; if (piece == 0) { return(offset); } var from = BitOperations.BitScan(piece); var availableMoves = KingMovesGenerator.GetMoves(from) & boardState.Occupancy[enemyColor]; while (availableMoves != 0) { var field = BitOperations.GetLsb(availableMoves); var fieldIndex = BitOperations.BitScan(field); availableMoves = BitOperations.PopLsb(availableMoves); moves[offset++] = new Move(from, fieldIndex, MoveFlags.Capture); } if (color == Color.White) { if (IsWhiteKingCastlingAvailable(boardState, color)) { moves[offset++] = new Move(3, 1, MoveFlags.KingCastle); } if (IsWhiteQueenCastlingAvailable(boardState, color)) { moves[offset++] = new Move(3, 5, MoveFlags.QueenCastle); } } else { if (IsBlackKingCastlingAvailable(boardState, color)) { moves[offset++] = new Move(59, 57, MoveFlags.KingCastle); } if (IsBlackQueenCastlingAvailable(boardState, color)) { moves[offset++] = new Move(59, 61, MoveFlags.QueenCastle); } } return(offset); }
public bool IsFieldAttacked(int color, int fieldIndex) { var enemyColor = ColorOperations.Invert(color); var fileRankAttacks = RookMovesGenerator.GetMoves(OccupancySummary, fieldIndex) & Occupancy[enemyColor]; var attackingRooks = fileRankAttacks & (Pieces[enemyColor][Piece.Rook] | Pieces[enemyColor][Piece.Queen]); if (attackingRooks != 0) { return(true); } var diagonalAttacks = BishopMovesGenerator.GetMoves(OccupancySummary, fieldIndex) & Occupancy[enemyColor]; var attackingBishops = diagonalAttacks & (Pieces[enemyColor][Piece.Bishop] | Pieces[enemyColor][Piece.Queen]); if (attackingBishops != 0) { return(true); } var jumpAttacks = KnightMovesGenerator.GetMoves(fieldIndex); var attackingKnights = jumpAttacks & Pieces[enemyColor][Piece.Knight]; if (attackingKnights != 0) { return(true); } var boxAttacks = KingMovesGenerator.GetMoves(fieldIndex); var attackingKings = boxAttacks & Pieces[enemyColor][Piece.King]; if (attackingKings != 0) { return(true); } var field = 1ul << fieldIndex; var potentialPawns = boxAttacks & Pieces[enemyColor][Piece.Pawn]; var attackingPawns = color == Color.White ? field & ((potentialPawns >> 7) | (potentialPawns >> 9)) : field & ((potentialPawns << 7) | (potentialPawns << 9)); if (attackingPawns != 0) { return(true); } return(false); }
public static bool IsMoveLegal(BoardState boardState, Move move) { var enemyColor = ColorOperations.Invert(boardState.ColorToMove); var availableMoves = KingMovesGenerator.GetMoves(move.From); var toField = 1ul << move.To; if (move.Flags == MoveFlags.Quiet && (availableMoves & toField) != 0 && (boardState.OccupancySummary & toField) == 0) { return(true); } if (move.Flags == MoveFlags.Capture && (availableMoves & toField) != 0 && (boardState.Occupancy[enemyColor] & toField) != 0) { return(true); } if (move.Flags == MoveFlags.KingCastle) { if (boardState.ColorToMove == Color.White && IsWhiteKingCastlingAvailable(boardState, boardState.ColorToMove)) { return(true); } else if (boardState.ColorToMove == Color.Black && IsBlackKingCastlingAvailable(boardState, boardState.ColorToMove)) { return(true); } } if (move.Flags == MoveFlags.QueenCastle) { if (boardState.ColorToMove == Color.White && IsWhiteQueenCastlingAvailable(boardState, boardState.ColorToMove)) { return(true); } else if (boardState.ColorToMove == Color.Black && IsBlackQueenCastlingAvailable(boardState, boardState.ColorToMove)) { return(true); } } return(false); }