Esempio n. 1
0
    /// generate
    /// EVASIONS
    ///     generates all pseudo-legal check evasions when the side
    ///     to move is in check. Returns a pointer to the end of the move list.
    private static ExtMoveArrayWrapper generate_EVASIONS(Position pos, ExtMoveArrayWrapper moveList)
    {
        Debug.Assert(pos.checkers() != 0);

        var us = pos.side_to_move();
        var ksq = pos.square(PieceType.KING, us);
        var sliderAttacks = Bitboard.Create(0);
        var sliders = pos.checkers() & ~pos.pieces_PtPt(PieceType.KNIGHT, PieceType.PAWN);

        // Find all the squares attacked by slider checkers. We will remove them from
        // the king evasions in order to skip known illegal moves, which avoids any
        // useless legality checks later on.
        while (sliders != 0)
        {
            var checksq1 = Utils.pop_lsb(ref sliders);
            sliderAttacks |= Bitboard.XorWithSquare(Utils.LineBB[checksq1, ksq], checksq1);
        }

        // Generate evasions for king, capture and non capture moves
        var b = pos.attacks_from_PtS(PieceType.KING, ksq) & ~pos.pieces_Ct(us) & ~sliderAttacks;
        while (b != 0)
        {
            (moveList).Add(Move.make_move(ksq, Utils.pop_lsb(ref b)));
        }

        if (Bitboard.more_than_one(pos.checkers()))
        {
            return moveList; // Double check, only a king move can save the day
        }

        // Generate blocking evasions or captures of the checking piece
        var checksq = Utils.lsb(pos.checkers());
        var target = Bitboard.OrWithSquare(Utils.between_bb(checksq, ksq), checksq);

        return us == Color.WHITE
            ? generate_all(Color.WHITE, GenType.EVASIONS, pos, moveList, target)
            : generate_all(Color.BLACK, GenType.EVASIONS, pos, moveList, target);
    }
Esempio n. 2
0
    // evaluate_passed_pawns() evaluates the passed pawns of the given color
    private static ScoreT evaluate_passed_pawns(ColorT Us, bool DoTrace, Position pos, EvalInfo ei)
    {
        var Them = (Us == Color.WHITE ? Color.BLACK : Color.WHITE);

        var score = Score.SCORE_ZERO;

        var b = ei.pi.passed_pawns(Us);

        while (b!=0)
        {
            var s = Utils.pop_lsb(ref b);

            Debug.Assert(pos.pawn_passed(Us, s));

            int r = Rank.relative_rank_CtSt(Us, s) - Rank.RANK_2;
            var rr = r*(r - 1);

            ValueT mbonus = Passed[(int) Phase.MG][r], ebonus = Passed[(int) Phase.EG][r];

            if (rr != 0)
            {
                var blockSq = s + Square.pawn_push(Us);

                // Adjust bonus based on the king's proximity
                ebonus += Utils.distance_Square(pos.square(PieceType.KING, Them), blockSq)*5*rr
                          - Utils.distance_Square(pos.square(PieceType.KING, Us), blockSq)*2*rr;

                // If blockSq is not the queening square then consider also a second push
                if (Rank.relative_rank_CtSt(Us, blockSq) != Rank.RANK_8)
                {
                    ebonus -= Utils.distance_Square(pos.square(PieceType.KING, Us), blockSq + Square.pawn_push(Us))*rr;
                }

                // If the pawn is free to advance, then increase the bonus
                if (pos.empty(blockSq))
                {
                    // If there is a rook or queen attacking/defending the pawn from behind,
                    // consider all the squaresToQueen. Otherwise consider only the squares
                    // in the pawn's path attacked or occupied by the enemy.
                    BitboardT squaresToQueen;
                    BitboardT unsafeSquares;
                    var defendedSquares = unsafeSquares = squaresToQueen = Utils.forward_bb(Us, s);

                    var bb = Utils.forward_bb(Them, s) & pos.pieces_PtPt(PieceType.ROOK, PieceType.QUEEN)
                             & pos.attacks_from_PtS(PieceType.ROOK, s);

                    if ((pos.pieces_Ct(Us) & bb)==0)
                    {
                        defendedSquares &= ei.attackedBy[Us, PieceType.ALL_PIECES];
                    }

                    if ((pos.pieces_Ct(Them) & bb) == 0)
                    {
                        unsafeSquares &= ei.attackedBy[Them, PieceType.ALL_PIECES] | pos.pieces_Ct(Them);
                    }

                    // If there aren't any enemy attacks, assign a big bonus. Otherwise
                    // assign a smaller bonus if the block square isn't attacked.
                    var k = unsafeSquares == 0 ? 18 : Bitboard.AndWithSquare(unsafeSquares, blockSq)==0 ? 8 : 0;

                    // If the path to queen is fully defended, assign a big bonus.
                    // Otherwise assign a smaller bonus if the block square is defended.
                    if (defendedSquares == squaresToQueen)
                    {
                        k += 6;
                    }

                    else if (Bitboard.AndWithSquare(defendedSquares, blockSq)!=0)
                    {
                        k += 4;
                    }

                    mbonus += k*rr;
                    ebonus += k*rr;
                }
                else if (Bitboard.AndWithSquare(pos.pieces_Ct(Us), blockSq)!=0)
                {
                    mbonus += rr*3 + r*2 + 3;
                    ebonus += rr + r*2;
                }
            } // rr != 0

            if (pos.count(PieceType.PAWN, Us) < pos.count(PieceType.PAWN, Them))
            {
                ebonus += ebonus/4;
            }

            score += Score.make_score(mbonus, ebonus) + PassedFile[Square.file_of(s)];
        }

        if (DoTrace)
        {
            add_IdxCtSt((int) Term.PASSED, Us, Score.Multiply(score, Weights[PassedPawns]));
        }

        // Add the scores to the middlegame and endgame eval
        return Score.Multiply(score, Weights[PassedPawns]);
    }