Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Thu, 29 Oct 2020 10:42:31 +0000 (11:42 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Thu, 29 Oct 2020 10:42:31 +0000 (11:42 +0100)
bench: 4282417

1  2 
src/Makefile
src/evaluate.cpp
src/evaluate.h
src/movepick.cpp
src/position.cpp
src/search.cpp
src/thread.h
src/timeman.cpp

diff --cc src/Makefile
Simple merge
@@@ -225,9 -221,13 +225,15 @@@ namespace 
        S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
        S(112,178), S(114,185), S(114,187), S(119,221) }
    };
 +  constexpr Score MaxMobility  = S(150, 200);
 +  constexpr Score DropMobility = S(10, 10);
  
+   // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
+   // squares of the same color as our bishop.
+   constexpr Score BishopPawns[int(FILE_NB) / 2] = {
+     S(3, 8), S(3, 9), S(1, 8), S(3, 7)
+   };
    // KingProtector[knight/bishop] contains penalty for each distance unit to own king
    constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
  
              sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
                                                          : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
          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;
-       
          sf -= 4 * !pawnsOnBothFlanks;
      }
  
diff --cc src/evaluate.h
Simple merge
Simple merge
@@@ -306,157 -218,69 +306,159 @@@ Position& Position::set(const Variant* 
    // 2. Active color
    ss >> token;
    sideToMove = (token == 'w' ? WHITE : BLACK);
 +  // Invert side to move for SFEN
 +  if (sfen)
 +      sideToMove = ~sideToMove;
    ss >> token;
  
 -  // 3. Castling availability. Compatible with 3 standards: Normal FEN standard,
 -  // Shredder-FEN that uses the letters of the columns on which the rooks began
 -  // the game instead of KQkq and also X-FEN standard that, in case of Chess960,
 -  // if an inner rook is associated with the castling right, the castling tag is
 -  // replaced by the file letter of the involved rook, as for the Shredder-FEN.
 -  while ((ss >> token) && !isspace(token))
 +  // 3-4. Skip parsing castling and en passant flags if not present
 +  st->epSquare = SQ_NONE;
 +  if (!isdigit(ss.peek()) && !sfen)
    {
 -      Square rsq;
 -      Color c = islower(token) ? BLACK : WHITE;
 -      Piece rook = make_piece(c, ROOK);
 +      // 3. Castling availability. Compatible with 3 standards: Normal FEN standard,
 +      // Shredder-FEN that uses the letters of the columns on which the rooks began
 +      // the game instead of KQkq and also X-FEN standard that, in case of Chess960,
 +      // if an inner rook is associated with the castling right, the castling tag is
 +      // replaced by the file letter of the involved rook, as for the Shredder-FEN.
 +      while ((ss >> token) && !isspace(token))
 +      {
 +          Square rsq;
 +          Color c = islower(token) ? BLACK : WHITE;
 +          Piece rook = make_piece(c, castling_rook_piece());
  
 -      token = char(toupper(token));
 +          token = char(toupper(token));
  
 -      if (token == 'K')
 -          for (rsq = relative_square(c, SQ_H1); piece_on(rsq) != rook; --rsq) {}
 +          if (token == 'K')
 +              for (rsq = make_square(FILE_MAX, castling_rank(c)); piece_on(rsq) != rook; --rsq) {}
  
 -      else if (token == 'Q')
 -          for (rsq = relative_square(c, SQ_A1); piece_on(rsq) != rook; ++rsq) {}
 +          else if (token == 'Q')
 +              for (rsq = make_square(FILE_A, castling_rank(c)); piece_on(rsq) != rook; ++rsq) {}
  
 -      else if (token >= 'A' && token <= 'H')
 -          rsq = make_square(File(token - 'A'), relative_rank(c, RANK_1));
 +          else if (token >= 'A' && token <= 'A' + max_file())
 +              rsq = make_square(File(token - 'A'), castling_rank(c));
  
 -      else
 -          continue;
 +          else
 +              continue;
  
 -      set_castling_right(c, rsq);
 +          // Set gates (and skip castling rights)
 +          if (gating())
 +          {
 +              st->gatesBB[c] |= rsq;
 +              if (token == 'K' || token == 'Q')
 +                  st->gatesBB[c] |= count<KING>(c) ? square<KING>(c) : make_square(FILE_E, castling_rank(c));
 +              // Do not set castling rights for gates unless there are no pieces in hand,
 +              // which means that the file is referring to a chess960 castling right.
 +              else if (!seirawan_gating() || count_in_hand(c, ALL_PIECES) || captures_to_hand())
 +                  continue;
 +          }
 +
 +          if (castling_enabled())
 +              set_castling_right(c, rsq);
 +      }
 +
 +      // Set castling rights for 960 gating variants
 +      if (gating() && castling_enabled())
 +          for (Color c : {WHITE, BLACK})
 +              if ((gates(c) & pieces(KING)) && !castling_rights(c) && (!seirawan_gating() || count_in_hand(c, ALL_PIECES) || captures_to_hand()))
 +              {
 +                  Bitboard castling_rooks = gates(c) & pieces(castling_rook_piece());
 +                  while (castling_rooks)
 +                      set_castling_right(c, pop_lsb(&castling_rooks));
 +              }
 +
 +      // counting limit
 +      if (counting_rule() && isdigit(ss.peek()))
 +          ss >> st->countingLimit;
 +
 +      // 4. En passant square.
 +      // Ignore if square is invalid or not on side to move relative rank 6.
 +      else if (   ((ss >> col) && (col >= 'a' && col <= 'a' + max_file()))
 +               && ((ss >> row) && (row >= '1' && row <= '1' + max_rank())))
 +      {
 +          st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
 +
 +          // En passant square will be considered only if
 +          // a) side to move have a pawn threatening epSquare
 +          // b) there is an enemy pawn in front of epSquare
 +          // c) there is no piece on epSquare or behind epSquare
 +          bool enpassant;
 +          enpassant = pawn_attacks_bb(~sideToMove, st->epSquare) & pieces(sideToMove, PAWN)
 +                  && (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove)))
 +                  && !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove))));
 +          if (!enpassant)
 +              st->epSquare = SQ_NONE;
 +      }
    }
  
 -  // 4. En passant square.
 -  // Ignore if square is invalid or not on side to move relative rank 6.
 -  bool enpassant = false;
 +  // Check counter for nCheck
 +  ss >> std::skipws >> token >> std::noskipws;
  
 -  if (   ((ss >> col) && (col >= 'a' && col <= 'h'))
 -      && ((ss >> row) && (row == (sideToMove == WHITE ? '6' : '3'))))
 +  if (check_counting())
    {
 -      st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
 -
 -      // En passant square will be considered only if
 -      // a) side to move have a pawn threatening epSquare
 -      // b) there is an enemy pawn in front of epSquare
 -      // c) there is no piece on epSquare or behind epSquare
 -      enpassant = pawn_attacks_bb(~sideToMove, st->epSquare) & pieces(sideToMove, PAWN)
 -               && (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove)))
 -               && !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove))));
 +      if (ss.peek() == '+')
 +      {
 +          st->checksRemaining[WHITE] = CheckCount(std::max(token - '0', 0));
 +          ss >> token >> token;
 +          st->checksRemaining[BLACK] = CheckCount(std::max(token - '0', 0));
 +      }
 +      else
 +      {
 +          // If check count is not provided, assume that the next check wins
 +          st->checksRemaining[WHITE] = CheckCount(1);
 +          st->checksRemaining[BLACK] = CheckCount(1);
 +          ss.putback(token);
 +      }
    }
 -
 -  if (!enpassant)
 -      st->epSquare = SQ_NONE;
 +  else
 +      ss.putback(token);
  
    // 5-6. Halfmove clock and fullmove number
 -  ss >> std::skipws >> st->rule50 >> gamePly;
 +  if (sfen)
 +  {
 +      // Pieces in hand for SFEN
 +      int handCount = 1;
 +      while ((ss >> token) && !isspace(token))
 +      {
 +          if (token == '-')
 +              continue;
 +          else if (isdigit(token))
 +          {
 +              handCount = token - '0';
 +              while (isdigit(ss.peek()) && ss >> token)
 +                  handCount = 10 * handCount + (token - '0');
 +          }
 +          else if ((idx = piece_to_char().find(token)) != string::npos)
 +          {
 +              for (int i = 0; i < handCount; i++)
 +                  add_to_hand(Piece(idx));
 +              handCount = 1;
 +          }
 +      }
 +      // Move count is in ply for SFEN
 +      ss >> std::skipws >> gamePly;
 +      gamePly = std::max(gamePly - 1, 0);
 +  }
 +  else
 +  {
 +      ss >> std::skipws >> st->rule50 >> gamePly;
  
 -  // Convert from fullmove starting from 1 to gamePly starting from 0,
 -  // handle also common incorrect FEN with fullmove = 0.
 -  gamePly = std::max(2 * (gamePly - 1), 0) + (sideToMove == BLACK);
 +      // Convert from fullmove starting from 1 to gamePly starting from 0,
 +      // handle also common incorrect FEN with fullmove = 0.
 +      gamePly = std::max(2 * (gamePly - 1), 0) + (sideToMove == BLACK);
 +  }
  
 -  chess960 = isChess960;
 +  // counting rules
 +  if (st->countingLimit && st->rule50)
 +  {
 +      st->countingPly = st->rule50;
 +      st->rule50 = 0;
 +  }
 +
 +  chess960 = isChess960 || v->chess960;
    thisThread = th;
    set_state(st);
+   st->accumulator.state[WHITE] = Eval::NNUE::INIT;
+   st->accumulator.state[BLACK] = Eval::NNUE::INIT;
  
    assert(pos_is_ok());
  
@@@ -1205,11 -703,10 +1207,12 @@@ void Position::do_move(Move m, StateInf
    ++gamePly;
    ++st->rule50;
    ++st->pliesFromNull;
 +  if (st->countingLimit)
 +      ++st->countingPly;
  
    // Used by NNUE
-   st->accumulator.computed_accumulation = false;
+   st->accumulator.state[WHITE] = Eval::NNUE::EMPTY;
+   st->accumulator.state[BLACK] = Eval::NNUE::EMPTY;
    auto& dp = st->dirtyPiece;
    dp.dirty_num = 1;
  
diff --cc src/search.cpp
Simple merge
diff --cc src/thread.h
Simple merge
diff --cc src/timeman.cpp
Simple merge