Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Mon, 21 Dec 2020 10:53:07 +0000 (11:53 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Mon, 21 Dec 2020 10:53:07 +0000 (11:53 +0100)
No functional change.

1  2 
src/evaluate.cpp
src/search.cpp

@@@ -1090,11 -844,8 +1090,14 @@@ namespace 
      behind |= shift<Down>(behind);
      behind |= shift<Down+Down>(behind);
  
 +    if (pawnsOnly)
 +    {
 +        safe = pos.board_bb() & ((attackedBy2[Us] & ~attackedBy2[Them]) | (attackedBy[Us][PAWN] & ~pos.pieces(Us, PAWN)));
 +        behind = 0;
 +    }
++
+     // Compute space score based on the number of safe squares and number of our pieces
+     // increased with number of total blocked pawns in position.
      int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
      int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
      Score score = make_score(bonus * weight * weight / 16, 0);
                  && pos.non_pawn_material(BLACK) == RookValueMg
                  && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
                  && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
 +                && pos.count<KING>(~strongSide)
                  && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
              sf = 36;
+         // For queen vs no queen endgames use scale factor
+         // based on number of minors of side that doesn't have queen.
          else if (pos.count<QUEEN>() == 1)
              sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
                                                          : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
+         // In every other case use scale factor based on
+         // the number of pawns of the strong side reduced if pawns are on a single flank.
          else
 -            sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
 +            sf = std::min(sf, 36 + 7 * (pos.count<PAWN>(strongSide) + pos.count<SOLDIER>(strongSide))) - 4 * !pawnsOnBothFlanks;
  
+         // Reduce scale factor in case of pawns being on a single flank
          sf -= 4 * !pawnsOnBothFlanks;
      }
  
@@@ -1482,10 -1057,11 +1497,12 @@@ Value Eval::evaluate(const Position& po
        // If there is PSQ imbalance use classical eval, with small probability if it is small
        Value psq = Value(abs(eg_value(pos.psq_score())));
        int   r50 = 16 + pos.rule50_count();
 -      bool  largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
 -      bool  classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
 +      bool  pure = pos.capture_the_flag_piece() && pos.checking_permitted();
 +      bool  largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50 && !pure;
 +      bool  classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB) && !pure);
  
+       // Use classical evaluation for really low piece endgames.
+       // The most critical case is a bishop + A/H file pawn vs naked king draw.
        bool strongClassical = pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2;
  
        v = classical || strongClassical ? Evaluation<NO_TRACE>(pos).value() : adjusted_NNUE();
diff --cc src/search.cpp
@@@ -876,8 -809,9 +883,9 @@@ namespace 
          if ((ss-1)->currentMove != MOVE_NULL)
              ss->staticEval = eval = evaluate(pos);
          else
 -            ss->staticEval = eval = -(ss-1)->staticEval + 2 * Tempo;
 +            ss->staticEval = eval = -(ss-1)->staticEval + 2 * Eval::tempo_value(pos);
  
+         // Save static evaluation into transposition table
          tte->save(posKey, VALUE_NONE, ss->ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, eval);
      }
  
@@@ -1467,8 -1384,9 +1481,9 @@@ moves_loop: // When in check, search st
  
      if (!moveCount)
          bestValue = excludedMove ? alpha
 -                   :     ss->inCheck ? mated_in(ss->ply) : VALUE_DRAW;
 +                   :     ss->inCheck ? pos.checkmate_value(ss->ply) : pos.stalemate_value(ss->ply);
  
+     // If there is a move which produces search value greater than alpha we update stats of searched moves
      else if (bestMove)
          update_all_stats(pos, ss, bestMove, bestValue, beta, prevSq,
                           quietsSearched, quietCount, capturesSearched, captureCount, depth);
                  bestValue = ttValue;
          }
          else
+             // In case of null move search use previous static eval with a different sign
+             // and addition of two tempos
              ss->staticEval = bestValue =
              (ss-1)->currentMove != MOVE_NULL ? evaluate(pos)
 -                                             : -(ss-1)->staticEval + 2 * Tempo;
 +                                             : -(ss-1)->staticEval + 2 * Eval::tempo_value(pos);
  
          // Stand pat. Return immediately if static value is at least beta
          if (bestValue >= beta)
      {
          assert(!MoveList<LEGAL>(pos).size());
  
 -        return mated_in(ss->ply); // Plies to mate from the root
 +        return pos.checkmate_value(ss->ply); // Plies to mate from the root
      }
  
+     // Save gathered info in transposition table
      tte->save(posKey, value_to_tt(bestValue, ss->ply), pvHit,
                bestValue >= beta ? BOUND_LOWER :
                PvNode && bestValue > oldAlpha  ? BOUND_EXACT : BOUND_UPPER,
      thisThread->mainHistory[us][from_to(move)] << bonus;
      update_continuation_histories(ss, pos.moved_piece(move), to_sq(move), bonus);
  
+     // Penalty for reversed move in case of moved piece not being a pawn
 -    if (type_of(pos.moved_piece(move)) != PAWN)
 +    if (type_of(pos.moved_piece(move)) != PAWN && type_of(move) != DROP)
          thisThread->mainHistory[us][from_to(reverse_move(move))] << -bonus;
  
+     // Update countermove history
      if (is_ok((ss-1)->currentMove))
      {
          Square prevSq = to_sq((ss-1)->currentMove);