Esempio n. 1
0
    internal CheckInfo(Position pos)
    {
        var them = Color.opposite(pos.side_to_move());
        ksq = pos.square(PieceType.KING, them);

        pinned = pos.pinned_pieces(pos.side_to_move());
        dcCandidates = pos.discovered_check_candidates();

        checkSquares[PieceType.PAWN] = pos.attacks_from_PS(PieceType.PAWN, ksq, them);
        checkSquares[PieceType.KNIGHT] = pos.attacks_from_PtS(PieceType.KNIGHT, ksq);
        checkSquares[PieceType.BISHOP] = pos.attacks_from_PtS(PieceType.BISHOP, ksq);
        checkSquares[PieceType.ROOK] = pos.attacks_from_PtS(PieceType.ROOK, ksq);
        checkSquares[PieceType.QUEEN] = checkSquares[PieceType.BISHOP] | checkSquares[PieceType.ROOK];
        checkSquares[PieceType.KING] = Bitboard.Create(0);
    }
Esempio n. 2
0
    internal override ScaleFactor GetScaleFactor(Position pos)
    {
        Debug.Assert(verify_material(pos, strongSide, Value.QueenValueMg, 0));
        Debug.Assert(pos.count(PieceType.ROOK, weakSide) == 1);
        Debug.Assert(pos.count(PieceType.PAWN, weakSide) >= 1);

        var kingSq = pos.square(PieceType.KING, weakSide);
        var rsq = pos.square(PieceType.ROOK, weakSide);

        if (Rank.relative_rank_CtSt(weakSide, kingSq) <= Rank.RANK_2
            && Rank.relative_rank_CtSt(weakSide, pos.square(PieceType.KING, strongSide)) >= Rank.RANK_4
            && Rank.relative_rank_CtSt(weakSide, rsq) == Rank.RANK_3
            && (pos.pieces_CtPt(weakSide, PieceType.PAWN) & pos.attacks_from_PtS(PieceType.KING, kingSq)
                & pos.attacks_from_PS(PieceType.PAWN, rsq, strongSide))!=0)
        {
            return ScaleFactor.SCALE_FACTOR_DRAW;
        }

        return ScaleFactor.SCALE_FACTOR_NONE;
    }
Esempio n. 3
0
    internal static ExtMoveArrayWrapper generate_pawn_moves(
        ColorT Us,
        GenType Type,
        Position pos,
        ExtMoveArrayWrapper moveList,
        BitboardT target,
        CheckInfo ci)
    {
        // Compute our parametrized parameters at compile time, named according to
        // the point of view of white side.
        var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);
        var TRank8BB = (Us == Color.WHITE ? Bitboard.Rank8BB : Bitboard.Rank1BB);
        var TRank7BB = (Us == Color.WHITE ? Bitboard.Rank7BB : Bitboard.Rank2BB);
        var TRank3BB = (Us == Color.WHITE ? Bitboard.Rank3BB : Bitboard.Rank6BB);
        var Up = (Us == Color.WHITE ? Square.DELTA_N : Square.DELTA_S);
        var Right = (Us == Color.WHITE ? Square.DELTA_NE : Square.DELTA_SW);
        var Left = (Us == Color.WHITE ? Square.DELTA_NW : Square.DELTA_SE);

        var emptySquares = Bitboard.Create(0);

        var pawnsOn7 = pos.pieces_CtPt(Us, PieceType.PAWN) & TRank7BB;
        var pawnsNotOn7 = pos.pieces_CtPt(Us, PieceType.PAWN) & ~TRank7BB;

        var enemies = (Type == GenType.EVASIONS
            ? pos.pieces_Ct(Them) & target
            : Type == GenType.CAPTURES ? target : pos.pieces_Ct(Them));

        // Single and double pawn pushes, no promotions
        if (Type != GenType.CAPTURES)
        {
            emptySquares = (Type == GenType.QUIETS || Type == GenType.QUIET_CHECKS ? target : ~pos.pieces());

            var b1 = Bitboard.shift_bb(Up, pawnsNotOn7) & emptySquares;
            var b2 = Bitboard.shift_bb(Up, b1 & TRank3BB) & emptySquares;

            if (Type == GenType.EVASIONS) // Consider only blocking squares
            {
                b1 &= target;
                b2 &= target;
            }

            if (Type == GenType.QUIET_CHECKS)
            {
                b1 &= pos.attacks_from_PS(PieceType.PAWN, ci.ksq, Them);
                b2 &= pos.attacks_from_PS(PieceType.PAWN, ci.ksq, Them);

                // Add pawn pushes which give discovered check. This is possible only
                // if the pawn is not on the same file as the enemy king, because we
                // don't generate captures. Note that a possible discovery check
                // promotion has been already generated amongst the captures.
                if ((pawnsNotOn7 & ci.dcCandidates) != 0)
                {
                    var dc1 = Bitboard.shift_bb(Up, pawnsNotOn7 & ci.dcCandidates) & emptySquares
                              & ~Utils.file_bb_St(ci.ksq);
                    var dc2 = Bitboard.shift_bb(Up, dc1 & TRank3BB) & emptySquares;

                    b1 |= dc1;
                    b2 |= dc2;
                }
            }

            while (b1 != 0)
            {
                var to = Utils.pop_lsb(ref b1);
                (moveList).Add(Move.make_move(to - Up, to));
            }

            while (b2 != 0)
            {
                var to = Utils.pop_lsb(ref b2);
                (moveList).Add(Move.make_move(to - Up - Up, to));
            }
        }

        // Promotions and underpromotions
        if (pawnsOn7 != 0 && (Type != GenType.EVASIONS || ((target & TRank8BB) != 0)))
        {
            if (Type == GenType.CAPTURES)
            {
                emptySquares = ~pos.pieces();
            }

            if (Type == GenType.EVASIONS)
            {
                emptySquares &= target;
            }

            var b1 = Bitboard.shift_bb(Right, pawnsOn7) & enemies;
            var b2 = Bitboard.shift_bb(Left, pawnsOn7) & enemies;
            var b3 = Bitboard.shift_bb(Up, pawnsOn7) & emptySquares;

            while (b1 != 0)
            {
                moveList = make_promotions(Type, Right, moveList, Utils.pop_lsb(ref b1), ci);
            }

            while (b2 != 0)
            {
                moveList = make_promotions(Type, Left, moveList, Utils.pop_lsb(ref b2), ci);
            }

            while (b3 != 0)
            {
                moveList = make_promotions(Type, Up, moveList, Utils.pop_lsb(ref b3), ci);
            }
        }

        // Standard and en-passant captures
        if (Type == GenType.CAPTURES || Type == GenType.EVASIONS || Type == GenType.NON_EVASIONS)
        {
            var b1 = Bitboard.shift_bb(Right, pawnsNotOn7) & enemies;
            var b2 = Bitboard.shift_bb(Left, pawnsNotOn7) & enemies;

            while (b1 != 0)
            {
                var to = Utils.pop_lsb(ref b1);
                (moveList).Add(Move.make_move(to - Right, to));
            }

            while (b2 != 0)
            {
                var to = Utils.pop_lsb(ref b2);
                (moveList).Add(Move.make_move(to - Left, to));
            }

            if (pos.ep_square() != Square.SQ_NONE)
            {
                Debug.Assert(Square.rank_of(pos.ep_square()) == Rank.relative_rank_CtRt(Us, Rank.RANK_6));

                // An en passant capture can be an evasion only if the checking piece
                // is the double pushed pawn and so is in the target. Otherwise this
                // is a discovery check and we are forced to do otherwise.
                if (Type == GenType.EVASIONS && Bitboard.AndWithSquare(target, (pos.ep_square() - Up))==0)
                {
                    return moveList;
                }

                b1 = pawnsNotOn7 & pos.attacks_from_PS(PieceType.PAWN, pos.ep_square(), Them);

                Debug.Assert(b1 != 0);

                while (b1 != 0)
                {
                    (moveList).Add(Move.make(MoveType.ENPASSANT, Utils.pop_lsb(ref b1), pos.ep_square()));
                }
            }
        }

        return moveList;
    }