Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Fri, 14 Aug 2020 13:15:08 +0000 (15:15 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Fri, 14 Aug 2020 13:15:08 +0000 (15:15 +0200)
No functional change.

12 files changed:
1  2 
src/bitboard.cpp
src/evaluate.cpp
src/main.cpp
src/movegen.cpp
src/pawns.cpp
src/position.h
src/search.cpp
src/syzygy/tbprobe.cpp
src/thread.cpp
src/timeman.cpp
src/tt.cpp
src/ucioption.cpp

@@@ -175,144 -68,40 +175,144 @@@ const std::string Bitboards::pretty(Bit
  
  void Bitboards::init() {
  
 +  // Piece moves
 +  std::vector<Direction> RookDirectionsV = { NORTH, SOUTH};
 +  std::vector<Direction> RookDirectionsH = { EAST, WEST };
 +  std::vector<Direction> BishopDirections = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
 +  std::vector<Direction> HorseDirections = {2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +                                            NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST };
 +  std::vector<Direction> ElephantDirections = { 2 * NORTH_EAST, 2 * SOUTH_EAST, 2 * SOUTH_WEST, 2 * NORTH_WEST };
 +  std::vector<Direction> JanggiElephantDirections = { NORTH + 2 * NORTH_EAST, EAST  + 2 * NORTH_EAST,
 +                                                      EAST  + 2 * SOUTH_EAST, SOUTH + 2 * SOUTH_EAST,
 +                                                      SOUTH + 2 * SOUTH_WEST, WEST + 2 * SOUTH_WEST,
 +                                                      WEST  + 2 * NORTH_WEST, NORTH + 2 * NORTH_WEST };
 +
 +  // Initialize rider types
 +  for (PieceType pt = PAWN; pt <= KING; ++pt)
 +  {
 +      const PieceInfo* pi = pieceMap.find(pt)->second;
 +
 +      if (pi->lameLeaper)
 +      {
 +          for (Direction d : pi->stepsCapture)
 +          {
 +              if (std::find(HorseDirections.begin(), HorseDirections.end(), d) != HorseDirections.end())
 +                  AttackRiderTypes[pt] |= RIDER_HORSE;
 +              if (std::find(ElephantDirections.begin(), ElephantDirections.end(), d) != ElephantDirections.end())
 +                  AttackRiderTypes[pt] |= RIDER_ELEPHANT;
 +              if (std::find(JanggiElephantDirections.begin(), JanggiElephantDirections.end(), d) != JanggiElephantDirections.end())
 +                  AttackRiderTypes[pt] |= RIDER_JANGGI_ELEPHANT;
 +          }
 +          for (Direction d : pi->stepsQuiet)
 +          {
 +              if (std::find(HorseDirections.begin(), HorseDirections.end(), d) != HorseDirections.end())
 +                  MoveRiderTypes[pt] |= RIDER_HORSE;
 +              if (std::find(ElephantDirections.begin(), ElephantDirections.end(), d) != ElephantDirections.end())
 +                  MoveRiderTypes[pt] |= RIDER_ELEPHANT;
 +              if (std::find(JanggiElephantDirections.begin(), JanggiElephantDirections.end(), d) != JanggiElephantDirections.end())
 +                  MoveRiderTypes[pt] |= RIDER_JANGGI_ELEPHANT;
 +          }
 +      }
 +      for (Direction d : pi->sliderCapture)
 +      {
 +          if (std::find(BishopDirections.begin(), BishopDirections.end(), d) != BishopDirections.end())
 +              AttackRiderTypes[pt] |= RIDER_BISHOP;
 +          if (std::find(RookDirectionsH.begin(), RookDirectionsH.end(), d) != RookDirectionsH.end())
 +              AttackRiderTypes[pt] |= RIDER_ROOK_H;
 +          if (std::find(RookDirectionsV.begin(), RookDirectionsV.end(), d) != RookDirectionsV.end())
 +              AttackRiderTypes[pt] |= RIDER_ROOK_V;
 +      }
 +      for (Direction d : pi->sliderQuiet)
 +      {
 +          if (std::find(BishopDirections.begin(), BishopDirections.end(), d) != BishopDirections.end())
 +              MoveRiderTypes[pt] |= RIDER_BISHOP;
 +          if (std::find(RookDirectionsH.begin(), RookDirectionsH.end(), d) != RookDirectionsH.end())
 +              MoveRiderTypes[pt] |= RIDER_ROOK_H;
 +          if (std::find(RookDirectionsV.begin(), RookDirectionsV.end(), d) != RookDirectionsV.end())
 +              MoveRiderTypes[pt] |= RIDER_ROOK_V;
 +      }
 +      for (Direction d : pi->hopperCapture)
 +      {
 +          if (std::find(RookDirectionsH.begin(), RookDirectionsH.end(), d) != RookDirectionsH.end())
 +              AttackRiderTypes[pt] |= RIDER_CANNON_H;
 +          if (std::find(RookDirectionsV.begin(), RookDirectionsV.end(), d) != RookDirectionsV.end())
 +              AttackRiderTypes[pt] |= RIDER_CANNON_V;
 +      }
 +      for (Direction d : pi->hopperQuiet)
 +      {
 +          if (std::find(RookDirectionsH.begin(), RookDirectionsH.end(), d) != RookDirectionsH.end())
 +              MoveRiderTypes[pt] |= RIDER_CANNON_H;
 +          if (std::find(RookDirectionsV.begin(), RookDirectionsV.end(), d) != RookDirectionsV.end())
 +              MoveRiderTypes[pt] |= RIDER_CANNON_V;
 +      }
 +  }
 +
    for (unsigned i = 0; i < (1 << 16); ++i)
-       PopCnt16[i] = std::bitset<16>(i).count();
+       PopCnt16[i] = uint8_t(std::bitset<16>(i).count());
  
 -  for (Square s = SQ_A1; s <= SQ_H8; ++s)
 -      SquareBB[s] = (1ULL << s);
 -
 -  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
 -      for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
 -          SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
 -
 -  Direction RookDirections[] = { NORTH, EAST, SOUTH, WEST };
 -  Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
 -
 -  init_magics(RookTable, RookMagics, RookDirections);
 -  init_magics(BishopTable, BishopMagics, BishopDirections);
 -
 -  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
 +  for (Square s = SQ_A1; s <= SQ_MAX; ++s)
 +      SquareBB[s] = make_bitboard(s);
 +
 +  for (File f = FILE_A; f <= FILE_MAX; ++f)
 +      for (Rank r = RANK_1; r <= RANK_MAX; ++r)
 +          BoardSizeBB[f][r] = forward_file_bb(BLACK, make_square(f, r)) | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : Bitboard(0));
 +
 +  for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
 +      for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
 +              SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
 +
 +#ifdef PRECOMPUTED_MAGICS
 +  init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH, RookMagicHInit);
 +  init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV, RookMagicVInit);
 +  init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections, BishopMagicInit);
 +  init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH, CannonMagicHInit);
 +  init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV, CannonMagicVInit);
 +  init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections, HorseMagicInit);
 +  init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections, ElephantMagicInit);
 +  init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections, JanggiElephantMagicInit);
 +#else
 +  init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH);
 +  init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV);
 +  init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections);
 +  init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH);
 +  init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV);
 +  init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections);
 +  init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections);
 +  init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections);
 +#endif
 +
 +  for (Color c : { WHITE, BLACK })
 +      for (PieceType pt = PAWN; pt <= KING; ++pt)
 +      {
 +          const PieceInfo* pi = pieceMap.find(pt)->second;
 +
 +          for (Square s = SQ_A1; s <= SQ_MAX; ++s)
 +          {
 +              for (Direction d : pi->stepsCapture)
 +              {
 +                  PseudoAttacks[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d);
 +                  if (!pi->lameLeaper)
 +                      LeaperAttacks[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d);
 +              }
 +              for (Direction d : pi->stepsQuiet)
 +              {
 +                  PseudoMoves[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d);
 +                  if (!pi->lameLeaper)
 +                      LeaperMoves[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d);
 +              }
 +              PseudoAttacks[c][pt][s] |= sliding_attack<RIDER>(pi->sliderCapture, s, 0, c);
 +              PseudoAttacks[c][pt][s] |= sliding_attack<RIDER>(pi->hopperCapture, s, 0, c);
 +              PseudoMoves[c][pt][s] |= sliding_attack<RIDER>(pi->sliderQuiet, s, 0, c);
 +              PseudoMoves[c][pt][s] |= sliding_attack<RIDER>(pi->hopperQuiet, s, 0, c);
 +          }
 +      }
 +
 +  for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
    {
 -      PawnAttacks[WHITE][s1] = pawn_attacks_bb<WHITE>(square_bb(s1));
 -      PawnAttacks[BLACK][s1] = pawn_attacks_bb<BLACK>(square_bb(s1));
 -
 -      for (int step : {-9, -8, -7, -1, 1, 7, 8, 9} )
 -         PseudoAttacks[KING][s1] |= safe_destination(s1, step);
 -
 -      for (int step : {-17, -15, -10, -6, 6, 10, 15, 17} )
 -         PseudoAttacks[KNIGHT][s1] |= safe_destination(s1, step);
 -
 -      PseudoAttacks[QUEEN][s1]  = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0);
 -      PseudoAttacks[QUEEN][s1] |= PseudoAttacks[  ROOK][s1] = attacks_bb<  ROOK>(s1, 0);
 -
        for (PieceType pt : { BISHOP, ROOK })
 -          for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
 -              if (PseudoAttacks[pt][s1] & s2)
 -                  LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
 +          for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
 +              if (PseudoAttacks[WHITE][pt][s1] & s2)
 +                  LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2;
    }
  }
  
Simple merge
diff --cc src/main.cpp
Simple merge
diff --cc src/movegen.cpp
@@@ -318,29 -213,44 +318,61 @@@ namespace 
  
  
    template<Color Us, GenType Type>
-   ExtMove* generate_all(const Position& pos, ExtMove* moveList, Bitboard target) {
+   ExtMove* generate_all(const Position& pos, ExtMove* moveList) {
      constexpr bool Checks = Type == QUIET_CHECKS; // Reduce template instantations
+     Bitboard target;
+     switch (Type)
+     {
+         case CAPTURES:
+             target =  pos.pieces(~Us);
+             break;
+         case QUIETS:
+         case QUIET_CHECKS:
+             target = ~pos.pieces();
+             break;
+         case EVASIONS:
+         {
++            if (pos.checkers() & (pos.pieces(CANNON, BANNER) | pos.pieces(HORSE, ELEPHANT) | pos.pieces(JANGGI_CANNON, JANGGI_ELEPHANT)))
++            {
++                target = ~pos.pieces(Us);
++                break;
++            }
+             Square checksq = lsb(pos.checkers());
+             target = between_bb(pos.square<KING>(Us), checksq) | checksq;
++            // Leaper attacks can not be blocked
++            if (LeaperAttacks[~Us][type_of(pos.piece_on(checksq))][checksq] & pos.square<KING>(Us))
++                target = square_bb(checksq);
+             break;
+         }
+         case NON_EVASIONS:
+             target = ~pos.pieces(Us);
+             break;
+         default:
+             static_assert(true, "Unsupported type in generate_all()");
+     }
++    target &= pos.board_bb();
  
      moveList = generate_pawn_moves<Us, Type>(pos, moveList, target);
 -    moveList = generate_moves<KNIGHT, Checks>(pos, moveList, Us, target);
 -    moveList = generate_moves<BISHOP, Checks>(pos, moveList, Us, target);
 -    moveList = generate_moves<  ROOK, Checks>(pos, moveList, Us, target);
 -    moveList = generate_moves< QUEEN, Checks>(pos, moveList, Us, target);
 -
 -    if (Type != QUIET_CHECKS && Type != EVASIONS)
 +    for (PieceType pt : pos.piece_types())
 +        if (pt != PAWN && pt != KING)
 +            moveList = generate_moves<Checks>(pos, moveList, Us, pt, target);
 +    // generate drops
 +    if (pos.piece_drops() && Type != CAPTURES && pos.count_in_hand(Us, ALL_PIECES))
 +        for (PieceType pt : pos.piece_types())
 +            moveList = generate_drops<Us, Checks>(pos, moveList, pt, target & ~pos.pieces(~Us));
 +
 +    if (Type != QUIET_CHECKS && Type != EVASIONS && pos.count<KING>(Us))
      {
          Square ksq = pos.square<KING>(Us);
 -        Bitboard b = pos.attacks_from<KING>(ksq) & target;
 +        Bitboard b = (  (pos.attacks_from(Us, KING, ksq) & pos.pieces())
 +                      | (pos.moves_from(Us, KING, ksq) & ~pos.pieces())) & target;
          while (b)
 -            *moveList++ = make_move(ksq, pop_lsb(&b));
 +            moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, ksq, pop_lsb(&b));
 +
 +        // Passing move by king
 +        if (pos.pass())
 +            *moveList++ = make<SPECIAL>(ksq, ksq);
  
          if ((Type != CAPTURES) && pos.can_castle(Us & ANY_CASTLING))
              for(CastlingRights cr : { Us & KING_SIDE, Us & QUEEN_SIDE } )
@@@ -432,17 -303,17 +459,17 @@@ ExtMove* generate<QUIET_CHECKS>(const P
       Square from = pop_lsb(&dc);
       PieceType pt = type_of(pos.piece_on(from));
  
 -     Bitboard b = pos.attacks_from(pt, from) & ~pos.pieces();
 +     Bitboard b = pos.moves_from(us, pt, from) & ~pos.pieces();
  
 -     if (pt == KING)
 -         b &= ~PseudoAttacks[QUEEN][pos.square<KING>(~us)];
 +     if (pt == KING && pos.king_type() == KING)
 +         b &= ~PseudoAttacks[~us][QUEEN][pos.square<KING>(~us)];
  
       while (b)
 -         *moveList++ = make_move(from, pop_lsb(&b));
 +         moveList = make_move_and_gating<NORMAL>(pos, moveList, us, from, pop_lsb(&b));
    }
  
-   return us == WHITE ? generate_all<WHITE, QUIET_CHECKS>(pos, moveList, ~pos.pieces() & pos.board_bb())
-                      : generate_all<BLACK, QUIET_CHECKS>(pos, moveList, ~pos.pieces() & pos.board_bb());
+   return us == WHITE ? generate_all<WHITE, QUIET_CHECKS>(pos, moveList)
+                      : generate_all<BLACK, QUIET_CHECKS>(pos, moveList);
  }
  
  
@@@ -456,23 -327,7 +483,23 @@@ ExtMove* generate<EVASIONS>(const Posit
    Color us = pos.side_to_move();
    Square ksq = pos.square<KING>(us);
    Bitboard sliderAttacks = 0;
 -  Bitboard sliders = pos.checkers() & ~pos.pieces(KNIGHT, PAWN);
 +  Bitboard sliders = pos.checkers();
 +
 +  // Passing move by king in bikjang
 +  if (pos.bikjang() && pos.pass())
 +      *moveList++ = make<SPECIAL>(ksq, ksq);
 +
 +  // Consider all evasion moves for special pieces
 +  if (sliders & (pos.pieces(CANNON, BANNER) | pos.pieces(HORSE, ELEPHANT) | pos.pieces(JANGGI_CANNON, JANGGI_ELEPHANT)))
 +  {
 +      Bitboard target = pos.board_bb() & ~pos.pieces(us);
 +      Bitboard b = (  (pos.attacks_from(us, KING, ksq) & pos.pieces())
 +                    | (pos.moves_from(us, KING, ksq) & ~pos.pieces())) & target;
 +      while (b)
 +          moveList = make_move_and_gating<NORMAL>(pos, moveList, us, ksq, pop_lsb(&b));
-       return us == WHITE ? generate_all<WHITE, EVASIONS>(pos, moveList, target)
-                          : generate_all<BLACK, EVASIONS>(pos, moveList, target);
++      return us == WHITE ? generate_all<WHITE, EVASIONS>(pos, moveList)
++                         : generate_all<BLACK, EVASIONS>(pos, moveList);
 +  }
  
    // Find all the squares attacked by slider checkers. We will remove them from
    // the king evasions in order to skip known illegal moves, which avoids any
diff --cc src/pawns.cpp
@@@ -97,22 -98,19 +98,20 @@@ namespace 
  
          // Flag the pawn
          opposed    = theirPawns & forward_file_bb(Us, s);
 -        blocked    = theirPawns & (s + Up);
 +        blocked    = is_ok(s + Up) ? theirPawns & (s + Up) : Bitboard(0);
          stoppers   = theirPawns & passed_pawn_span(Us, s);
 -        lever      = theirPawns & PawnAttacks[Us][s];
 -        leverPush  = theirPawns & PawnAttacks[Us][s + Up];
 -        doubled    = ourPawns   & (s - Up);
 +        lever      = theirPawns & PseudoAttacks[Us][PAWN][s];
 +        leverPush  = relative_rank(Them, s, pos.max_rank()) > RANK_1 ? theirPawns & PseudoAttacks[Us][PAWN][s + Up] : Bitboard(0);
 +        doubled    = r > RANK_1 ? ourPawns & (s - Up) : Bitboard(0);
          neighbours = ourPawns   & adjacent_files_bb(s);
          phalanx    = neighbours & rank_bb(s);
 -        support    = neighbours & rank_bb(s - Up);
 +        support    = r > RANK_1 ? neighbours & rank_bb(s - Up) : Bitboard(0);
  
-         e->blockedCount += blocked || more_than_one(leverPush);
          // A pawn is backward when it is behind all pawns of the same color on
          // the adjacent files and cannot safely advance.
 -        backward =  !(neighbours & forward_ranks_bb(Them, s + Up))
 -                  && (leverPush | blocked);
 +        backward =   is_ok(s + Up)
 +                  && !(neighbours & forward_ranks_bb(Them, s + Up))
 +                  && (stoppers & blocked);
  
          // Compute additional span if pawn is not backward nor blocked
          if (!backward && !blocked)
@@@ -234,14 -210,13 +233,14 @@@ Score Entry::evaluate_shelter(const Pos
    for (File f = File(center - 1); f <= File(center + 1); ++f)
    {
        b = ourPawns & file_bb(f);
 -      int ourRank = b ? relative_rank(Us, frontmost_sq(Them, b)) : 0;
 +      int ourRank = b ? relative_rank(Us, frontmost_sq(Them, b), pos.max_rank()) : 0;
  
        b = theirPawns & file_bb(f);
 -      int theirRank = b ? relative_rank(Us, frontmost_sq(Them, b)) : 0;
 +      int theirRank = b ? relative_rank(Us, frontmost_sq(Them, b), pos.max_rank()) : 0;
  
-       File d = std::min(File(edge_distance(f, pos.max_file())), FILE_D);
 -      int d = edge_distance(f);
 -      bonus += make_score(ShelterStrength[d][ourRank], 0);
++      int d = std::min(File(edge_distance(f, pos.max_file())), FILE_D);
 +      bonus += make_score(ShelterStrength[d][ourRank], 0) * (1 + (pos.captures_to_hand() && ourRank <= RANK_2)
 +                                                               + (pos.check_counting() && d == 0 && ourRank == RANK_2));
  
        if (ourRank && (ourRank == theirRank - 1))
            bonus -= BlockedStorm * int(theirRank == RANK_3);
diff --cc src/position.h
@@@ -1062,11 -396,10 +1062,10 @@@ inline Thread* Position::this_thread() 
    return thisThread;
  }
  
 -inline void Position::put_piece(Piece pc, Square s) {
 +inline void Position::put_piece(Piece pc, Square s, bool isPromoted, Piece unpromotedPc) {
  
    board[s] = pc;
-   byTypeBB[ALL_PIECES] |= s;
-   byTypeBB[type_of(pc)] |= s;
+   byTypeBB[ALL_PIECES] |= byTypeBB[type_of(pc)] |= s;
    byColorBB[color_of(pc)] |= s;
    index[s] = pieceCount[pc]++;
    pieceList[pc][index[s]] = s;
diff --cc src/search.cpp
@@@ -291,12 -269,12 +291,12 @@@ void MainThread::search() 
    if (Limits.npmsec)
        Time.availableNodes += Limits.inc[us] - Threads.nodes_searched();
  
 -  Thread* bestThread = this;
 +  bestThread = this;
  
    // Check if there are threads with a better score than main thread
-   if (    Options["MultiPV"] == 1
+   if (    int(Options["MultiPV"]) == 1
        && !Limits.depth
-       && !(Skill(Options["Skill Level"]).enabled() || Options["UCI_LimitStrength"])
+       && !(Skill(Options["Skill Level"]).enabled() || int(Options["UCI_LimitStrength"]))
        &&  rootMoves[0].pv[0] != MOVE_NONE)
    {
        std::map<Move, int64_t> votes;
Simple merge
diff --cc src/thread.cpp
Simple merge
diff --cc src/timeman.cpp
@@@ -34,12 -33,12 +34,12 @@@ TimeManagement Time; // Our global tim
  //      1) x basetime (+z increment)
  //      2) x moves in y seconds (+z increment)
  
 -void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
 +void TimeManagement::init(const Position& pos, Search::LimitsType& limits, Color us, int ply) {
  
-   TimePoint minThinkingTime = Options["Minimum Thinking Time"];
-   TimePoint moveOverhead    = Options["Move Overhead"];
-   TimePoint slowMover       = Options["Slow Mover"];
-   TimePoint npmsec          = Options["nodestime"];
+   TimePoint minThinkingTime = TimePoint(Options["Minimum Thinking Time"]);
+   TimePoint moveOverhead    = TimePoint(Options["Move Overhead"]);
+   TimePoint slowMover       = TimePoint(Options["Slow Mover"]);
+   TimePoint npmsec          = TimePoint(Options["nodestime"]);
  
    // opt_scale is a percentage of available time to use for the current move.
    // max_scale is a multiplier applied to optimumTime.
diff --cc src/tt.cpp
Simple merge
@@@ -37,91 -34,14 +37,91 @@@ using std::string
  
  UCI::OptionsMap Options; // Global object
  
 +namespace PSQT {
 +  void init(const Variant* v);
 +}
 +
  namespace UCI {
  
 +// standard variants of XBoard/WinBoard
 +std::set<string> standard_variants = {
 +    "normal", "nocastle", "fischerandom", "knightmate", "3check", "makruk", "shatranj",
 +    "asean", "seirawan", "crazyhouse", "bughouse", "suicide", "giveaway", "losers",
 +    "capablanca", "gothic", "janus", "caparandom", "grand", "shogi", "xiangqi"
 +};
 +
  /// 'On change' actions, triggered by an option's value change
  void on_clear_hash(const Option&) { Search::clear(); }
- void on_hash_size(const Option& o) { TT.resize(o); }
+ void on_hash_size(const Option& o) { TT.resize(size_t(o)); }
  void on_logger(const Option& o) { start_logger(o); }
- void on_threads(const Option& o) { Threads.set(o); }
+ void on_threads(const Option& o) { Threads.set(size_t(o)); }
  void on_tb_path(const Option& o) { Tablebases::init(o); }
 +void on_variant_path(const Option& o) { variants.parse<false>(o); Options["UCI_Variant"].set_combo(variants.get_keys()); }
 +void on_variant_change(const Option &o) {
 +    const Variant* v = variants.find(o)->second;
 +    PSQT::init(v);
 +    // Do not send setup command for known variants
 +    if (standard_variants.find(o) != standard_variants.end())
 +        return;
 +    int pocketsize = v->pieceDrops ? (v->pocketSize ? v->pocketSize : v->pieceTypes.size()) : 0;
 +    if (Options["Protocol"] == "xboard")
 +    {
 +        // Send setup command
 +        sync_cout << "setup (" << v->pieceToCharTable << ") "
 +                  << v->maxFile + 1 << "x" << v->maxRank + 1
 +                  << "+" << pocketsize << "_" << v->variantTemplate
 +                  << " " << v->startFen
 +                  << sync_endl;
 +        // Send piece command with Betza notation
 +        // https://www.gnu.org/software/xboard/Betza.html
 +        for (PieceType pt : v->pieceTypes)
 +        {
 +            string suffix =   pt == PAWN && v->doubleStep     ? "ifmnD"
 +                            : pt == KING && v->cambodianMoves ? "ismN"
 +                            : pt == FERS && v->cambodianMoves ? "ifD"
 +                                                              : "";
 +            // Janggi palace moves
 +            if (v->diagonalLines)
 +            {
 +                PieceType pt2 = pt == KING ? v->kingType : pt;
 +                if (pt2 == WAZIR)
 +                    suffix += "F";
 +                else if (pt2 == SOLDIER)
 +                    suffix += "fF";
 +                else if (pt2 == ROOK)
 +                    suffix += "B";
 +                else if (pt2 == JANGGI_CANNON)
 +                    suffix += "pB";
 +            }
 +            // Castling
 +            if (pt == KING && v->castling)
 +                 suffix += "O" + std::to_string((v->castlingKingsideFile - v->castlingQueensideFile) / 2);
 +            // Drop region
 +            if (v->pieceDrops)
 +            {
 +                if (pt == PAWN && !v->firstRankPawnDrops)
 +                    suffix += "j";
 +                else if (pt == SHOGI_PAWN && !v->shogiDoubledPawn)
 +                    suffix += "f";
 +                else if (pt == BISHOP && v->dropOppositeColoredBishop)
 +                    suffix += "s";
 +                suffix += "@" + std::to_string(pt == PAWN && !v->promotionZonePawnDrops ? v->promotionRank : v->maxRank + 1);
 +            }
 +            sync_cout << "piece " << v->pieceToChar[pt] << "& " << pieceMap.find(pt == KING ? v->kingType : pt)->second->betza << suffix << sync_endl;
 +            PieceType promType = v->promotedPieceType[pt];
 +            if (promType)
 +                sync_cout << "piece +" << v->pieceToChar[pt] << "& " << pieceMap.find(promType)->second->betza << sync_endl;
 +        }
 +    }
 +    else
 +        sync_cout << "info string variant " << (std::string)o
 +                << " files " << v->maxFile + 1
 +                << " ranks " << v->maxRank + 1
 +                << " pocket " << pocketsize
 +                << " template " << v->variantTemplate
 +                << " startpos " << v->startFen
 +                << sync_endl;
 +}
  
  
  /// Our case insensitive less() function as required by UCI protocol