Beispiel #1
0
        // Note that this doesn't check if a pawn can be taken en passant
        public bool IsAttacked(int defenderIx, Color defenderColor)
        {
            // check in roughly descending order of power

            // rook and queen
            var potentialRookCaptures = RookMoveTable.GetMoves(defenderIx, GetOccupied());

            if ((potentialRookCaptures & GetPieceBitboard(defenderColor.Other(), PieceType.Rook)) > 0)
            {
                return(true);
            }

            if ((potentialRookCaptures & GetPieceBitboard(defenderColor.Other(), PieceType.Queen)) > 0)
            {
                return(true);
            }

            // bishop and queen
            var potentialBishopCaptures = BishopMoveTable.GetMoves(defenderIx, GetOccupied());

            if ((potentialBishopCaptures & GetPieceBitboard(defenderColor.Other(), PieceType.Bishop)) > 0)
            {
                return(true);
            }

            if ((potentialBishopCaptures & GetPieceBitboard(defenderColor.Other(), PieceType.Queen)) > 0)
            {
                return(true);
            }

            var potentialKnightCaptures = KnightMoveTable.GetMoves(defenderIx);

            if ((potentialKnightCaptures & GetPieceBitboard(defenderColor.Other(), PieceType.Knight)) > 0)
            {
                return(true);
            }

            var potentialKingCaptures = KingMoveTable.GetMoves(defenderIx);

            if ((potentialKingCaptures & GetPieceBitboard(defenderColor.Other(), PieceType.King)) > 0)
            {
                return(true);
            }

            var potentialPawnCaptures = PawnCaptureMoveTable.GetMoves(defenderIx, defenderColor);

            if ((potentialPawnCaptures & GetPieceBitboard(defenderColor.Other(), PieceType.Pawn)) > 0)
            {
                return(true);
            }

            // we checked all possible attacks by all possible piece types
            return(false);
        }
Beispiel #2
0
        private void GeneratePawnMoves(List <Move> moves, Position position, ulong sourceSquares)
        {
            var   color = position.SideToMove;
            ulong promotionSourceSquares    = sourceSquares & PawnPromotionSourceTable[(int)color];
            ulong nonPromotionSourceSquares = sourceSquares & ~promotionSourceSquares;

            while (Bits.TryPopLsb(ref nonPromotionSourceSquares, out var sourceIx))
            {
                // TODO: separate out normal moves from double moves. Normal moves use normal lookup table, double moves use magic lookup table
                var quiets = PawnQuietMoveTable.GetMoves(sourceIx, color);
                quiets &= ~position.GetOccupied();

                var doubles = PawnDoubleMoveTable.GetMoves(sourceIx, position.GetOccupied(), color);
                // note: no need to mask double moves; the move table already takes care of that

                var captures          = PawnCaptureMoveTable.GetMoves(sourceIx, color);
                var normalCaptures    = captures & position.GetOccupied(color.Other());
                var enPassantCaptures = captures & position.EnPassant;

                while (Bits.TryPopLsb(ref quiets, out var dstIx))
                {
                    moves.Add(new Move(MoveType.Normal | MoveType.Quiet, sourceIx, dstIx));
                }

                while (Bits.TryPopLsb(ref doubles, out var dstIx))
                {
                    moves.Add(new Move(MoveType.DoubleMove | MoveType.Quiet, sourceIx, dstIx));
                }

                while (Bits.TryPopLsb(ref normalCaptures, out var dstIx))
                {
                    moves.Add(new Move(MoveType.Normal | MoveType.Capture, sourceIx, dstIx));
                }

                while (Bits.TryPopLsb(ref enPassantCaptures, out var dstIx))
                {
                    moves.Add(new Move(MoveType.EnPassant | MoveType.Capture, sourceIx, dstIx));
                }
            }

            while (Bits.TryPopLsb(ref promotionSourceSquares, out var sourceIx))
            {
                var quiets = PawnQuietMoveTable.GetMoves(sourceIx, color);
                quiets &= ~position.GetOccupied();

                var captures = PawnCaptureMoveTable.GetMoves(sourceIx, color);
                captures &= position.GetOccupied(color.Other());

                foreach (var piece in new[] { PieceType.Queen, PieceType.Knight, PieceType.Rook, PieceType.Bishop })
                {
                    var quietsTmp = quiets;
                    while (Bits.TryPopLsb(ref quietsTmp, out var dstIx))
                    {
                        moves.Add(new Move(MoveType.Promotion | MoveType.Quiet, sourceIx, dstIx, piece));
                    }

                    var capturesTmp = captures;
                    while (Bits.TryPopLsb(ref capturesTmp, out var dstIx))
                    {
                        moves.Add(new Move(MoveType.Promotion | MoveType.Capture, sourceIx, dstIx, piece));
                    }
                }
            }
        }