Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Mon, 1 Jun 2020 08:53:27 +0000 (10:53 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Mon, 1 Jun 2020 08:53:27 +0000 (10:53 +0200)
bench: 4968875

1  2 
src/endgame.cpp
src/search.cpp
src/types.h

diff --cc src/endgame.cpp
@@@ -163,15 -136,8 +163,15 @@@ Value Endgame<KXK>::operator()(const Po
        || pos.count<ROOK>(strongSide)
        ||(pos.count<BISHOP>(strongSide) && pos.count<KNIGHT>(strongSide))
        || (   (pos.pieces(strongSide, BISHOP) & ~DarkSquares)
 -          && (pos.pieces(strongSide, BISHOP) &  DarkSquares)))
 +          && (pos.pieces(strongSide, BISHOP) &  DarkSquares))
 +      || pos.count<SILVER>(strongSide) >= 2
 +      ||(pos.count<SILVER>(strongSide) && pos.count<KNIGHT>(strongSide))
 +      ||(pos.count<SILVER>(strongSide) && pos.count<FERS>(strongSide))
 +      ||(pos.count<KNIGHT>(strongSide) && pos.count<FERS>(strongSide) >= 2)
 +      ||(pos.count<FERS>(strongSide) >= 3
 +          && ( DarkSquares & pos.pieces(strongSide, FERS))
 +          && (~DarkSquares & pos.pieces(strongSide, FERS))))
-       result = std::min(result + VALUE_KNOWN_WIN, VALUE_MATE_IN_MAX_PLY - 1);
+       result = std::min(result + VALUE_KNOWN_WIN, VALUE_TB_WIN_IN_MAX_PLY - 1);
  
    return strongSide == pos.side_to_move() ? result : -result;
  }
@@@ -194,9 -160,9 +194,9 @@@ Value Endgame<KBNK>::operator()(const P
  
    Value result =  VALUE_KNOWN_WIN
                  + PushClose[distance(winnerKSq, loserKSq)]
 -                + PushToCorners[opposite_colors(bishopSq, SQ_A1) ? ~loserKSq : loserKSq];
 +                + PushToCorners[map_to_standard_board(pos, relative_square(opposite_colors(bishopSq, SQ_A1) ? BLACK : WHITE, loserKSq, pos.max_rank()))];
  
-   assert(abs(result) < VALUE_MATE_IN_MAX_PLY);
+   assert(abs(result) < VALUE_TB_WIN_IN_MAX_PLY);
    return strongSide == pos.side_to_move() ? result : -result;
  }
  
@@@ -362,9 -318,9 +363,9 @@@ Value Endgame<KNNKP>::operator()(const 
    assert(verify_material(pos, strongSide, 2 * KnightValueMg, 0));
    assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
  
-   Value result =  2 * KnightValueEg
-                 - PawnValueEg
-                 + PushToEdges[map_to_standard_board(pos, pos.square<KING>(weakSide))];
+   Value result =      PawnValueEg
 -               +  2 * PushToEdges[pos.square<KING>(weakSide)]
++               +  2 * PushToEdges[map_to_standard_board(pos, pos.square<KING>(weakSide))]
+                - 10 * relative_rank(weakSide, pos.square<PAWN>(weakSide));
  
    return strongSide == pos.side_to_move() ? result : -result;
  }
  template<> Value Endgame<KNNK>::operator()(const Position&) const { return VALUE_DRAW; }
  
  
 +/// KFsPs vs K.
 +template<>
 +Value Endgame<KFsPsK>::operator()(const Position& pos) const {
 +
 +  assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
 +
 +  Square winnerKSq = pos.square<KING>(strongSide);
 +  Square loserKSq = pos.square<KING>(weakSide);
 +
 +  Value result =  pos.non_pawn_material(strongSide)
 +                + pos.count<PAWN>(strongSide) * PawnValueEg
 +                + PushToEdges[map_to_standard_board(pos, loserKSq)]
 +                + PushClose[distance(winnerKSq, loserKSq)];
 +
 +  if (   pos.count<FERS>(strongSide) >= 3
 +      && ( DarkSquares & pos.pieces(strongSide, FERS))
 +      && (~DarkSquares & pos.pieces(strongSide, FERS)))
-       result = std::min(result + VALUE_KNOWN_WIN, VALUE_MATE_IN_MAX_PLY - 1);
++      result = std::min(result + VALUE_KNOWN_WIN, VALUE_TB_WIN_IN_MAX_PLY - 1);
 +  else if (pos.count<FERS>(strongSide) + pos.count<PAWN>(strongSide) < 3)
 +      return VALUE_DRAW;
 +  else
 +  {
 +      bool dark  =  DarkSquares & pos.pieces(strongSide, FERS);
 +      bool light = ~DarkSquares & pos.pieces(strongSide, FERS);
 +
 +      // Determine the color of ferzes from promoting pawns
 +      Bitboard b = pos.pieces(strongSide, PAWN);
 +      while (b && (!dark || !light))
 +      {
 +          if (file_of(pop_lsb(&b)) % 2 != relative_rank(strongSide, pos.promotion_rank(), pos.max_rank()) % 2)
 +              light = true;
 +          else
 +              dark = true;
 +      }
 +      if (!dark || !light)
 +          return VALUE_DRAW; // we can not checkmate with same colored ferzes
 +  }
 +
 +  return strongSide == pos.side_to_move() ? result : -result;
 +}
 +
 +
 +/// Mate with KNS vs K.
 +template<>
 +Value Endgame<KNSK>::operator()(const Position& pos) const {
 +
 +  assert(verify_material(pos, strongSide, KnightValueMg + SilverValueMg, 0));
 +  assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
 +
 +  Square winnerKSq = pos.square<KING>(strongSide);
 +  Square loserKSq = pos.square<KING>(weakSide);
 +
 +  Value result =  VALUE_KNOWN_WIN
 +                + PushClose[distance(winnerKSq, loserKSq)]
 +                + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))];
 +
 +  return strongSide == pos.side_to_move() ? result : -result;
 +}
 +
 +
 +/// KNF vs K. Can only be won if the weaker side's king
 +/// is close to a corner of the same color as the fers.
 +template<>
 +Value Endgame<KNFK>::operator()(const Position& pos) const {
 +
 +  assert(verify_material(pos, strongSide, KnightValueMg + FersValueMg, 0));
 +  assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
 +
 +  Square winnerKSq = pos.square<KING>(strongSide);
 +  Square loserKSq = pos.square<KING>(weakSide);
 +  Square fersSq = pos.square<FERS>(strongSide);
 +
 +  // tries to drive toward corners A1 or H8. If we have a
 +  // fers that cannot reach the above squares, we flip the kings in order
 +  // to drive the enemy toward corners A8 or H1.
 +  if (opposite_colors(fersSq, SQ_A1))
 +  {
 +      winnerKSq = relative_square(BLACK, winnerKSq, pos.max_rank());
 +      loserKSq  = relative_square(BLACK, loserKSq, pos.max_rank());
 +  }
 +
 +  Value result =  Value(PushClose[distance(winnerKSq, loserKSq)])
 +                + (PushToCorners[map_to_standard_board(pos, loserKSq)] - 3000) / 10;
 +
 +  return strongSide == pos.side_to_move() ? result : -result;
 +}
 +
 +
 +/// KNSFKR vs K.
 +template<>
 +Value Endgame<KNSFKR>::operator()(const Position& pos) const {
 +
 +  assert(verify_material(pos, strongSide, KnightValueMg + SilverValueMg + FersValueMg, 0));
 +  assert(verify_material(pos, weakSide, RookValueMg, 0));
 +
 +  Square winnerKSq = pos.square<KING>(strongSide);
 +  Square loserKSq = pos.square<KING>(weakSide);
 +
 +  Value result =  KnightValueEg + SilverValueEg + FersValueEg - RookValueEg
 +                + PushClose[distance(winnerKSq, loserKSq)]
 +                + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))];
 +
 +  return strongSide == pos.side_to_move() ? result : -result;
 +}
 +
 +
 +/// Mate with KSF vs K.
 +template<>
 +Value Endgame<KSFK>::operator()(const Position& pos) const {
 +
 +  assert(verify_material(pos, strongSide, SilverValueMg + FersValueMg, 0));
 +  assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
 +
 +  Square winnerKSq = pos.square<KING>(strongSide);
 +  Square loserKSq = pos.square<KING>(weakSide);
 +
 +  Value result =  VALUE_KNOWN_WIN
 +                + PushClose[distance(winnerKSq, loserKSq)]
 +                + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))];
 +
 +  return strongSide == pos.side_to_move() ? result : -result;
 +}
 +
 +
 +/// Mate with KSF vs KF.
 +template<>
 +Value Endgame<KSFKF>::operator()(const Position& pos) const {
 +
 +  assert(verify_material(pos, strongSide, SilverValueMg + FersValueMg, 0));
 +  assert(verify_material(pos, weakSide, FersValueMg, 0));
 +
 +  Square winnerKSq = pos.square<KING>(strongSide);
 +  Square loserKSq = pos.square<KING>(weakSide);
 +  Square fersSq = pos.square<FERS>(weakSide);
 +
 +  Value result =  SilverValueEg
 +                + PushClose[distance(winnerKSq, loserKSq)]
 +                + PushAway[distance(fersSq, loserKSq)]
 +                + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))];
 +
 +  return strongSide == pos.side_to_move() ? result : -result;
 +}
 +
 +
  /// KB and one or more pawns vs K. It checks for draws with rook pawns and
  /// a bishop of the wrong color. If such a draw is detected, SCALE_FACTOR_DRAW
  /// is returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
diff --cc src/search.cpp
@@@ -960,10 -891,9 +961,10 @@@ namespace 
      // much above beta, we can (almost) safely prune the previous move.
      if (   !PvNode
          &&  depth >= 5
 +        &&  (pos.pieces() ^ pos.pieces(CLOBBER_PIECE))
-         &&  abs(beta) < VALUE_MATE_IN_MAX_PLY)
+         &&  abs(beta) < VALUE_TB_WIN_IN_MAX_PLY)
      {
 -        Value raisedBeta = std::min(beta + 189 - 45 * improving, VALUE_INFINITE);
 +        Value raisedBeta = std::min(beta + (189 + 20 * !!pos.capture_the_flag_piece()) * (1 + pos.check_counting() + (pos.extinction_value() != VALUE_NONE)) - 45 * improving, VALUE_INFINITE);
          MovePicker mp(pos, ttMove, raisedBeta - ss->staticEval, &thisThread->captureHistory);
          int probCutCount = 0;
  
@@@ -1066,16 -996,14 +1067,16 @@@ moves_loop: // When in check, search st
  
        // Step 13. Pruning at shallow depth (~200 Elo)
        if (  !rootNode
 -          && pos.non_pawn_material(us)
 +          && (pos.non_pawn_material(us) || !(pos.pieces(us) ^ pos.pieces(us, PAWN)))
-           && bestValue > VALUE_MATED_IN_MAX_PLY)
+           && bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
        {
            // Skip quiet moves if movecount exceeds our FutilityMoveCount threshold
 -          moveCountPruning = moveCount >= futility_move_count(improving, depth);
 +          moveCountPruning = moveCount >= futility_move_count(improving, depth)
 +                            || (pos.must_capture() && (moveCountPruning || (pos.capture(move) && pos.legal(move))));
  
            if (   !captureOrPromotion
 -              && !givesCheck)
 +              && !givesCheck
 +              && (!pos.must_capture() || !pos.attackers_to(to_sq(move), ~us)))
            {
                // Reduced depth of the next LMR search
                int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0);
diff --cc src/types.h
Simple merge