Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Fri, 22 Mar 2019 20:05:35 +0000 (21:05 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Fri, 22 Mar 2019 20:05:35 +0000 (21:05 +0100)
bench: 3933394

1  2 
src/evaluate.cpp

@@@ -92,10 -93,9 +92,10 @@@ namespace 
  
    // Penalties for enemy's safe checks
    constexpr int QueenSafeCheck  = 780;
-   constexpr int RookSafeCheck   = 880;
-   constexpr int BishopSafeCheck = 435;
+   constexpr int RookSafeCheck   = 1080;
+   constexpr int BishopSafeCheck = 635;
    constexpr int KnightSafeCheck = 790;
 +  constexpr int OtherSafeCheck  = 600;
  
  #define S(mg, eg) make_score(mg, eg)
  
    Score Evaluation<T>::king() const {
  
      constexpr Color    Them = (Us == WHITE ? BLACK : WHITE);
 -    constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
 -                                           : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
 +    Rank r = relative_rank(Us, std::min(Rank((pos.max_rank() - 1) / 2 + 1), pos.max_rank()), pos.max_rank());
 +    Bitboard Camp = AllSquares ^ forward_ranks_bb(Us, r);
 +
 +    if (!pos.count<KING>(Us) || !pos.checking_permitted())
 +        return SCORE_ZERO;
  
      const Square ksq = pos.square<KING>(Us);
--    Bitboard kingFlank, weak, b, b1, b2, safe, unsafeChecks;
++    Bitboard kingFlank, weak, b, b1, b2, safe, unsafeChecks, QueenCheck;
  
      // King shelter and enemy pawns storm
      Score score = pe->king_safety<Us>(pos);
      safe  = ~pos.pieces(Them);
      safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
  
+     b1 = attacks_bb<ROOK  >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
+     b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
 -    // Enemy rooks checks
 -    Bitboard RookCheck =  b1
 +    std::function <Bitboard (Color, PieceType)> get_attacks = [this](Color c, PieceType pt) {
 +        return attackedBy[c][pt] | (pos.captures_to_hand() && pos.count_in_hand(c, pt) ? ~pos.pieces() : 0);
 +    };
 +    for (PieceType pt : pos.piece_types())
 +    {
 +        switch (pt)
 +        {
 +        case QUEEN:
-             b = attacks_bb(Us, pt, ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)) & get_attacks(Them, pt) & safe & ~attackedBy[Us][QUEEN] & pos.board_bb();
-             if (b)
++            // Enemy queen safe checks: we count them only if they are from squares from
++            // which we can't give a rook check, because rook checks are more valuable.
++            QueenCheck = (b1 | b2)
++                        & get_attacks(Them, QUEEN)
+                         & safe
 -                        & attackedBy[Them][ROOK];
 -
 -    if (RookCheck)
 -        kingDanger += RookSafeCheck;
 -    else
 -        unsafeChecks |= b1 & attackedBy[Them][ROOK];
 -
 -    // Enemy queen safe checks: we count them only if they are from squares from
 -    // which we can't give a rook check, because rook checks are more valuable.
 -    Bitboard QueenCheck =  (b1 | b2)
 -                         & attackedBy[Them][QUEEN]
 -                         & safe
 -                         & ~attackedBy[Us][QUEEN]
 -                         & ~RookCheck;
 -
 -    if (QueenCheck)
 -        kingDanger += QueenSafeCheck;
 -
 -    // Enemy bishops checks: we count them only if they are from squares from
 -    // which we can't give a queen check, because queen checks are more valuable.
 -    Bitboard BishopCheck =  b2 
 -                          & attackedBy[Them][BISHOP]
 -                          & safe
 -                          & ~QueenCheck;
 -
 -    if (BishopCheck)
 -        kingDanger += BishopSafeCheck;
 -    else
 -        unsafeChecks |= b2 & attackedBy[Them][BISHOP];
 -
 -    // Enemy knights checks
 -    b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
++                        & ~attackedBy[Us][QUEEN]
++                        & ~(b1 & attackedBy[Them][ROOK]);
++
++            if (QueenCheck)
 +                kingDanger += QueenSafeCheck;
 +            break;
 +        case ROOK:
 +        case BISHOP:
 +        case KNIGHT:
 +            b = attacks_bb(Us, pt, ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)) & get_attacks(Them, pt) & pos.board_bb();
 +            if (b & safe)
 +                kingDanger +=  pt == ROOK   ? RookSafeCheck
-                                 : pt == BISHOP ? BishopSafeCheck
++                             : pt == BISHOP ? BishopSafeCheck
 +                                            : KnightSafeCheck;
 +            else
 +                unsafeChecks |= b;
 +            break;
 +        case PAWN:
 +            if (pos.captures_to_hand() && pos.count_in_hand(Them, pt))
 +            {
 +                b = attacks_bb(Us, pt, ksq, pos.pieces()) & ~pos.pieces() & pos.board_bb();
 +                if (b & safe)
 +                    kingDanger += OtherSafeCheck;
 +                else
 +                    unsafeChecks |= b;
 +            }
 +            break;
 +        case SHOGI_PAWN:
 +        case KING:
 +            break;
 +        default:
 +            b = attacks_bb(Us, pt, ksq, pos.pieces()) & get_attacks(Them, pt) & pos.board_bb();
 +            if (b & safe)
 +                kingDanger += OtherSafeCheck;
 +            else
 +                unsafeChecks |= b;
 +        }
 +    }
  
 -    if (b & safe)
 -        kingDanger += KnightSafeCheck;
 -    else
 -        unsafeChecks |= b;
 +    if (pos.max_check_count())
 +        kingDanger *= 2;
  
      // Unsafe or occupied checking squares will also be considered, as long as
      // the square is in the attacker's mobility area.