Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Tue, 18 May 2021 13:34:32 +0000 (15:34 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Tue, 18 May 2021 13:34:32 +0000 (15:34 +0200)
bench: 5269468

1  2 
AUTHORS
src/bitboard.cpp
src/bitboard.h
src/misc.cpp
src/misc.h
src/position.cpp
src/position.h
src/search.cpp
src/search.h

diff --cc AUTHORS
Simple merge
@@@ -203,18 -55,18 +203,18 @@@ inline Bitboard safe_destination(Squar
  /// Bitboards::pretty() returns an ASCII representation of a bitboard suitable
  /// to be printed to standard output. Useful for debugging.
  
- const std::string Bitboards::pretty(Bitboard b) {
+ std::string Bitboards::pretty(Bitboard b) {
  
 -  std::string s = "+---+---+---+---+---+---+---+---+\n";
 +  std::string s = "+---+---+---+---+---+---+---+---+---+---+---+---+\n";
  
 -  for (Rank r = RANK_8; r >= RANK_1; --r)
 +  for (Rank r = RANK_MAX; r >= RANK_1; --r)
    {
 -      for (File f = FILE_A; f <= FILE_H; ++f)
 +      for (File f = FILE_A; f <= FILE_MAX; ++f)
            s += b & make_square(f, r) ? "| X " : "|   ";
  
 -      s += "| " + std::to_string(1 + r) + "\n+---+---+---+---+---+---+---+---+\n";
 +      s += "| " + std::to_string(1 + r) + "\n+---+---+---+---+---+---+---+---+---+---+---+---+\n";
    }
 -  s += "  a   b   c   d   e   f   g   h\n";
 +  s += "  a   b   c   d   e   f   g   h   i   j   k\n";
  
    return s;
  }
diff --cc src/bitboard.h
@@@ -32,9 -32,8 +32,9 @@@ bool probe(Square wksq, Square wpsq, Sq
  
  namespace Bitboards {
  
 +void init_pieces();
  void init();
- const std::string pretty(Bitboard b);
+ std::string pretty(Bitboard b);
  
  }
  
diff --cc src/misc.cpp
@@@ -138,7 -138,7 +138,7 @@@ public
  /// the program was compiled) or "Stockfish <Version>", depending on whether
  /// Version is empty.
  
- const string engine_info(bool to_uci, bool to_xboard) {
 -string engine_info(bool to_uci) {
++string engine_info(bool to_uci, bool to_xboard) {
  
    const string months("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec");
    string month, day, year;
diff --cc src/misc.h
@@@ -28,8 -28,8 +28,8 @@@
  
  #include "types.h"
  
- const std::string engine_info(bool to_uci = false, bool to_xboard = false);
- const std::string compiler_info();
 -std::string engine_info(bool to_uci = false);
++std::string engine_info(bool to_uci = false, bool to_xboard = false);
+ std::string compiler_info();
  void prefetch(void* addr);
  void start_logger(const std::string& fname);
  void* std_aligned_alloc(size_t alignment, size_t size);
@@@ -633,7 -408,7 +633,7 @@@ Position& Position::set(const string& c
  /// Position::fen() returns a FEN representation of the position. In case of
  /// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
  
- const string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string holdings) const {
 -string Position::fen() const {
++string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string holdings) const {
  
    int emptyCnt;
    std::ostringstream ss;
diff --cc src/position.h
@@@ -106,101 -85,12 +106,101 @@@ public
    Position& operator=(const Position&) = delete;
  
    // FEN string input/output
 -  Position& set(const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th);
 +  Position& set(const Variant* v, const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th, bool sfen = false);
    Position& set(const std::string& code, Color c, StateInfo* si);
-   const std::string fen(bool sfen = false, bool showPromoted = false, int countStarted = 0, std::string holdings = "-") const;
 -  std::string fen() const;
++  std::string fen(bool sfen = false, bool showPromoted = false, int countStarted = 0, std::string holdings = "-") const;
 +
 +  // Variant rule properties
 +  const Variant* variant() const;
 +  Rank max_rank() const;
 +  File max_file() const;
 +  bool two_boards() const;
 +  Bitboard board_bb() const;
 +  Bitboard board_bb(Color c, PieceType pt) const;
 +  const std::set<PieceType>& piece_types() const;
 +  const std::string& piece_to_char() const;
 +  const std::string& piece_to_char_synonyms() const;
 +  Rank promotion_rank() const;
 +  const std::set<PieceType, std::greater<PieceType> >& promotion_piece_types() const;
 +  bool sittuyin_promotion() const;
 +  int promotion_limit(PieceType pt) const;
 +  PieceType promoted_piece_type(PieceType pt) const;
 +  bool piece_promotion_on_capture() const;
 +  bool mandatory_pawn_promotion() const;
 +  bool mandatory_piece_promotion() const;
 +  bool piece_demotion() const;
 +  bool blast_on_capture() const;
 +  bool endgame_eval() const;
 +  bool double_step_enabled() const;
 +  Rank double_step_rank_max() const;
 +  Rank double_step_rank_min() const;
 +  bool castling_enabled() const;
 +  bool castling_dropped_piece() const;
 +  File castling_kingside_file() const;
 +  File castling_queenside_file() const;
 +  Rank castling_rank(Color c) const;
 +  File castling_king_file() const;
 +  PieceType castling_king_piece() const;
 +  PieceType castling_rook_piece() const;
 +  PieceType king_type() const;
 +  PieceType nnue_king() const;
 +  bool checking_permitted() const;
 +  bool drop_checks() const;
 +  bool must_capture() const;
 +  bool has_capture() const;
 +  bool must_drop() const;
 +  bool piece_drops() const;
 +  bool drop_loop() const;
 +  bool captures_to_hand() const;
 +  bool first_rank_pawn_drops() const;
 +  bool drop_on_top() const;
 +  EnclosingRule enclosing_drop() const;
 +  Bitboard drop_region(Color c) const;
 +  Bitboard drop_region(Color c, PieceType pt) const;
 +  bool sittuyin_rook_drop() const;
 +  bool drop_opposite_colored_bishop() const;
 +  bool drop_promoted() const;
 +  PieceType drop_no_doubled() const;
 +  bool immobility_illegal() const;
 +  bool gating() const;
 +  bool arrow_gating() const;
 +  bool seirawan_gating() const;
 +  bool cambodian_moves() const;
 +  Bitboard diagonal_lines() const;
 +  bool pass() const;
 +  bool pass_on_stalemate() const;
 +  Bitboard promoted_soldiers(Color c) const;
 +  bool makpong() const;
 +  EnclosingRule flip_enclosed_pieces() const;
 +  // winning conditions
 +  int n_move_rule() const;
 +  int n_fold_rule() const;
 +  Value stalemate_value(int ply = 0) const;
 +  Value checkmate_value(int ply = 0) const;
 +  Value extinction_value(int ply = 0) const;
 +  bool extinction_claim() const;
 +  const std::set<PieceType>& extinction_piece_types() const;
 +  bool extinction_single_piece() const;
 +  int extinction_piece_count() const;
 +  int extinction_opponent_piece_count() const;
 +  PieceType capture_the_flag_piece() const;
 +  Bitboard capture_the_flag(Color c) const;
 +  bool flag_move() const;
 +  bool check_counting() const;
 +  int connect_n() const;
 +  CheckCount checks_remaining(Color c) const;
 +  MaterialCounting material_counting() const;
 +  CountingRule counting_rule() const;
 +
 +  // Variant-specific properties
 +  int count_in_hand(PieceType pt) const;
 +  int count_in_hand(Color c, PieceType pt) const;
 +  int count_with_hand(Color c, PieceType pt) const;
 +  bool bikjang() const;
 +  bool allow_virtual_drop(Color c, PieceType pt) const;
  
    // Position representation
 -  Bitboard pieces(PieceType pt) const;
 +  Bitboard pieces(PieceType pt = ALL_PIECES) const;
    Bitboard pieces(PieceType pt1, PieceType pt2) const;
    Bitboard pieces(Color c) const;
    Bitboard pieces(Color c, PieceType pt) const;
diff --cc src/search.cpp
@@@ -972,14 -840,12 +973,14 @@@ namespace 
      // Step 8. Null move search with verification search (~40 Elo)
      if (   !PvNode
          && (ss-1)->currentMove != MOVE_NULL
-         && (ss-1)->statScore < 22661
+         && (ss-1)->statScore < 24185
          &&  eval >= beta
          &&  eval >= ss->staticEval
 -        &&  ss->staticEval >= beta - 24 * depth - 34 * improving + 162 * ss->ttPv + 159
 +        &&  ss->staticEval >= beta - 24 * depth - 34 * improving + 162 * ss->ttPv + 159 + 200 * (!pos.double_step_enabled() && pos.piece_to_char()[PAWN] != ' ')
          && !excludedMove
          &&  pos.non_pawn_material(us)
 +        &&  pos.count<ALL_PIECES>(~us) != pos.count<PAWN>(~us)
 +        && !pos.flip_enclosed_pieces()
          && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
      {
          assert(eval - beta >= 0);
@@@ -1171,9 -1053,9 +1188,9 @@@ moves_loop: // When in check, search st
        // Calculate new depth for this move
        newDepth = depth - 1;
  
-       // Step 12. Pruning at shallow depth (~200 Elo)
+       // Step 13. Pruning at shallow depth (~200 Elo)
        if (  !rootNode
 -          && pos.non_pawn_material(us)
 +          && (pos.non_pawn_material(us) || pos.count<ALL_PIECES>(us) == pos.count<PAWN>(us))
            && bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
        {
            // Skip quiet moves if movecount exceeds our FutilityMoveCount threshold
                // Futility pruning: parent node (~5 Elo)
                if (   lmrDepth < 7
                    && !ss->inCheck
 -                  && ss->staticEval + 174 + 157 * lmrDepth <= alpha
 -                  &&  (*contHist[0])[movedPiece][to_sq(move)]
 -                    + (*contHist[1])[movedPiece][to_sq(move)]
 -                    + (*contHist[3])[movedPiece][to_sq(move)]
 -                    + (*contHist[5])[movedPiece][to_sq(move)] / 3 < 28255)
 +                  && !pos.extinction_single_piece()
 +                  && ss->staticEval + (174 + 157 * lmrDepth) * (1 + pos.check_counting()) <= alpha
 +                  &&  (*contHist[0])[history_slot(movedPiece)][to_sq(move)]
 +                    + (*contHist[1])[history_slot(movedPiece)][to_sq(move)]
 +                    + (*contHist[3])[history_slot(movedPiece)][to_sq(move)]
-                     + (*contHist[5])[history_slot(movedPiece)][to_sq(move)] / 3 < 26237)
++                    + (*contHist[5])[history_slot(movedPiece)][to_sq(move)] / 3 < 28255)
                    continue;
  
                // Prune moves with negative SEE (~20 Elo)
        ss->currentMove = move;
        ss->continuationHistory = &thisThread->continuationHistory[ss->inCheck]
                                                                  [captureOrPromotion]
 -                                                                [movedPiece]
 +                                                                [history_slot(movedPiece)]
                                                                  [to_sq(move)];
  
-       // Step 14. Make the move
+       // Step 15. Make the move
        pos.do_move(move, st, givesCheck);
  
-       // Step 15. Reduced depth search (LMR, ~200 Elo). If the move fails high it will be
-       // re-searched at full depth.
+       (ss+1)->distanceFromPv = ss->distanceFromPv + moveCount - 1;
+       // Step 16. Late moves reduction / extension (LMR, ~200 Elo)
+       // We use various heuristics for the sons of a node after the first son has
+       // been searched. In general we would like to reduce them, but there are many
+       // cases where we extend a son if it has good chances to be "interesting".
        if (    depth >= 3
            &&  moveCount > 1 + 2 * rootNode
 +          && !(pos.must_capture() && pos.has_capture())
            && (  !captureOrPromotion
                || moveCountPruning
                || ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha
                    r -= 2 + ss->ttPv - (type_of(movedPiece) == PAWN);
  
                ss->statScore =  thisThread->mainHistory[us][from_to(move)]
 -                             + (*contHist[0])[movedPiece][to_sq(move)]
 -                             + (*contHist[1])[movedPiece][to_sq(move)]
 -                             + (*contHist[3])[movedPiece][to_sq(move)]
 +                             + (*contHist[0])[history_slot(movedPiece)][to_sq(move)]
 +                             + (*contHist[1])[history_slot(movedPiece)][to_sq(move)]
 +                             + (*contHist[3])[history_slot(movedPiece)][to_sq(move)]
-                              - 5337;
+                              - 4741;
  
                // Decrease/increase reduction by comparing opponent's stat score (~10 Elo)
                if (ss->statScore >= -89 && (ss-1)->statScore < -116)
                    r++;
  
                // Decrease/increase reduction for moves with a good/bad history (~30 Elo)
-               // If we are not in check use statScore, if we are in check
-               // use sum of main history and first continuation history with an offset
+               // If we are not in check use statScore, but if we are in check we use
+               // the sum of main history and first continuation history with an offset.
                if (ss->inCheck)
                    r -= (thisThread->mainHistory[us][from_to(move)]
-                      + (*contHist[0])[history_slot(movedPiece)][to_sq(move)] - 4341) / 16384;
 -                     + (*contHist[0])[movedPiece][to_sq(move)] - 3833) / 16384;
++                     + (*contHist[0])[history_slot(movedPiece)][to_sq(move)] - 3833) / 16384;
                else
-                   r -= ss->statScore / (14382 - 4434 * pos.captures_to_hand());
 -                  r -= ss->statScore / 14790;
++                  r -= ss->statScore / (14790 - 4434 * pos.captures_to_hand());
            }
  
-           Depth d = std::clamp(newDepth - r, 1, newDepth);
+           // In general we want to cap the LMR depth search at newDepth. But for nodes
+           // close to the principal variation the cap is at (newDepth + 1), which will
+           // allow these nodes to be searched deeper than the pv (up to 4 plies deeper).
+           Depth d = std::clamp(newDepth - r, 1, newDepth + ((ss+1)->distanceFromPv <= 4));
  
            value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
  
diff --cc src/search.h
Simple merge