Пример #1
0
    public void FindPinnedPieces()
    {
        var ownKingSquare          = Bitwise.FirstSetSquare(GetKing(ColorToMove));
        var ownPieces              = ColorOccupancy[(int)ColorToMove];
        var enemyRankFileAttackers = GetRooks(ColorLastMoved) | GetQueens(ColorLastMoved);
        var enemyDiagonalAttackers = GetBishops(ColorLastMoved) | GetQueens(ColorLastMoved);
        var enemyPieces            = ColorOccupancy[(int)ColorLastMoved];

        // Find pieces pinned to own king by enemy rank / file attackers.
        PinnedPieces = 0;
        Square attackerSquare;

        while ((attackerSquare = Bitwise.PopFirstSetSquare(ref enemyRankFileAttackers)) != Square.Illegal)
        {
            var betweenSquares = Board.RankFileBetweenSquares[(int)attackerSquare][(int)ownKingSquare];
            if (betweenSquares == 0)
            {
                continue;
            }
            if ((betweenSquares & enemyPieces) == 0)
            {
                // No enemy pieces between enemy attacker and own king.
                var pinnedPieces = betweenSquares & ownPieces;
                if (Bitwise.CountSetBits(pinnedPieces) == 1)
                {
                    // Exactly one own piece between enemy attacker and own king.
                    // Piece is pinned to own king.
                    PinnedPieces |= pinnedPieces;
                }
            }
        }
        // Find pieces pinned to own king by enemy diagonal attackers.
        while ((attackerSquare = Bitwise.PopFirstSetSquare(ref enemyDiagonalAttackers)) != Square.Illegal)
        {
            var betweenSquares = Board.DiagonalBetweenSquares[(int)attackerSquare][(int)ownKingSquare];
            if (betweenSquares == 0)
            {
                continue;
            }
            if ((betweenSquares & enemyPieces) == 0)
            {
                // No enemy pieces between enemy attacker and own king.
                var pinnedPieces = betweenSquares & ownPieces;
                if (Bitwise.CountSetBits(pinnedPieces) == 1)
                {
                    // Exactly one own piece between enemy attacker and own king.
                    // Piece is pinned to own king.
                    PinnedPieces |= pinnedPieces;
                }
            }
        }
    }
Пример #2
0
    private void GenerateKingMoves(MoveGeneration moveGeneration, ulong fromSquareMask, ulong toSquareMask)
    {
        var king = GetKing(ColorToMove) & fromSquareMask;

        if (king == 0)
        {
            return;
        }
        var   unOrEnemyOccupiedSquares = ~ColorOccupancy[(int)ColorToMove];
        var   enemyOccupiedSquares     = ColorOccupancy[(int)ColorLastMoved];
        var   attacker = PieceHelper.GetPieceOfColor(ColorlessPiece.King, ColorToMove);
        ulong move;
        var   fromSquare = Bitwise.FirstSetSquare(king);

        if (fromSquare == Square.Illegal)
        {
            return;
        }
        var kingDestinations = moveGeneration switch
        {
            MoveGeneration.AllMoves => Board.KingMoveMasks[(int)fromSquare] & unOrEnemyOccupiedSquares & toSquareMask,
            MoveGeneration.OnlyCaptures => Board.KingMoveMasks[(int)fromSquare] & enemyOccupiedSquares & toSquareMask,
            MoveGeneration.OnlyNonCaptures => Board.KingMoveMasks[(int)fromSquare] & ~Occupancy & toSquareMask,
            _ => throw new Exception($"{moveGeneration} move generation not supported.")
        };
        Square toSquare;

        while ((toSquare = Bitwise.PopFirstSetSquare(ref kingDestinations)) != Square.Illegal)
        {
            var victim = GetPiece(toSquare);
            move = Move.Null;
            Move.SetPiece(ref move, attacker);
            Move.SetFrom(ref move, fromSquare);
            Move.SetTo(ref move, toSquare);
            if (victim != Piece.None)
            {
                Move.SetCaptureAttacker(ref move, attacker);
            }
            Move.SetCaptureVictim(ref move, victim);
            Move.SetIsKingMove(ref move, true);
            Moves[MoveIndex] = move;
            MoveIndex++;
        }
        if (moveGeneration != MoveGeneration.OnlyCaptures)
        {
            for (var boardSide = BoardSide.Queen; boardSide <= BoardSide.King; boardSide++)
            {
                var castleEmptySquaresMask = Board.CastleEmptySquaresMask[(int)ColorToMove][(int)boardSide];
                if (!KingInCheck && Game.Castling.Permitted(Castling, ColorToMove, boardSide) && ((Occupancy & castleEmptySquaresMask) == 0))
                {
                    // Castle
                    toSquare = Board.CastleToSquares[(int)ColorToMove][(int)boardSide];
                    if ((Board.SquareMasks[(int)toSquare] & toSquareMask) > 0)
                    {
                        move = Move.Null;
                        Move.SetPiece(ref move, attacker);
                        Move.SetFrom(ref move, fromSquare);
                        Move.SetTo(ref move, toSquare);
                        Move.SetIsCastling(ref move, true);
                        Move.SetIsKingMove(ref move, true);
                        Moves[MoveIndex] = move;
                        MoveIndex++;
                    }
                }
            }
        }
    }