Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 20 Sep 2020 11:55:24 +0000 (13:55 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 20 Sep 2020 11:55:24 +0000 (13:55 +0200)
No functional change.

1  2 
Readme.md
src/benchmark.cpp
src/bitboard.h
src/evaluate.cpp
src/search.cpp

diff --cc Readme.md
Simple merge
Simple merge
diff --cc src/bitboard.h
@@@ -199,11 -138,11 +199,11 @@@ constexpr bool opposite_colors(Square s
  /// rank_bb() and file_bb() return a bitboard representing all the squares on
  /// the given file or rank.
  
- inline Bitboard rank_bb(Rank r) {
+ constexpr Bitboard rank_bb(Rank r) {
 -  return Rank1BB << (8 * r);
 +  return Rank1BB << (FILE_NB * r);
  }
  
- inline Bitboard rank_bb(Square s) {
+ constexpr Bitboard rank_bb(Square s) {
    return rank_bb(rank_of(s));
  }
  
@@@ -312,23 -229,9 +312,23 @@@ inline Bitboard between_bb(Square s1, S
  /// in front of the given one, from the point of view of the given color. For instance,
  /// forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2.
  
- inline Bitboard forward_ranks_bb(Color c, Square s) {
+ constexpr Bitboard forward_ranks_bb(Color c, Square s) {
 -  return c == WHITE ? ~Rank1BB << 8 * relative_rank(WHITE, s)
 -                    : ~Rank8BB >> 8 * relative_rank(BLACK, s);
 +  return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * relative_rank(WHITE, s, RANK_MAX)
 +                    : (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * relative_rank(BLACK, s, RANK_MAX);
 +}
 +
- inline Bitboard forward_ranks_bb(Color c, Rank r) {
++constexpr Bitboard forward_ranks_bb(Color c, Rank r) {
 +  return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * (r - RANK_1)
 +                    : (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * (RANK_MAX - r);
 +}
 +
 +
 +/// promotion_zone_bb() returns a bitboard representing the squares on all the ranks
 +/// in front of and on the given relative rank, from the point of view of the given color.
 +/// For instance, promotion_zone_bb(BLACK, RANK_7) will return the 16 squares on ranks 1 and 2.
 +
 +inline Bitboard promotion_zone_bb(Color c, Rank r, Rank maxRank) {
 +  return forward_ranks_bb(c, relative_rank(c, r, maxRank)) | rank_bb(relative_rank(c, r, maxRank));
  }
  
  
@@@ -951,147 -719,9 +951,147 @@@ namespace 
    }
  
  
 +  // Evaluation::variant() computes variant-specific evaluation bonuses for a given side.
 +
 +  template<Tracing T> template<Color Us>
 +  Score Evaluation<T>::variant() const {
 +
 +    constexpr Color Them = ~Us;
 +    constexpr Direction Down = pawn_push(Them);
 +
 +    Score score = SCORE_ZERO;
 +
 +    // Capture the flag
 +    if (pos.capture_the_flag(Us))
 +    {
 +        PieceType ptCtf = pos.capture_the_flag_piece();
 +        Bitboard ctfPieces = pos.pieces(Us, ptCtf);
 +        Bitboard ctfTargets = pos.capture_the_flag(Us) & pos.board_bb();
 +        Bitboard onHold = 0;
 +        Bitboard onHold2 = 0;
 +        Bitboard processed = 0;
 +        Bitboard blocked = pos.pieces(Us, PAWN) | attackedBy[Them][ALL_PIECES];
 +        Bitboard doubleBlocked =  attackedBy2[Them]
 +                                | (pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | attackedBy[Them][ALL_PIECES]))
 +                                | (pos.pieces(Them) & pe->pawn_attacks(Them))
 +                                | (pawn_attacks_bb<Them>(pos.pieces(Them, PAWN) & pe->pawn_attacks(Them)));
 +        Bitboard inaccessible = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces(Them, PAWN));
 +        // Traverse all paths of the CTF pieces to the CTF targets.
 +        // Put squares that are attacked or occupied on hold for one iteration.
 +        for (int dist = 0; (ctfPieces || onHold || onHold2) && (ctfTargets & ~processed); dist++)
 +        {
 +            int wins = popcount(ctfTargets & ctfPieces);
 +            if (wins)
 +                score += make_score(4000, 4000) * wins / (wins + dist * dist);
 +            Bitboard current = ctfPieces & ~ctfTargets;
 +            processed |= ctfPieces;
 +            ctfPieces = onHold & ~processed;
 +            onHold = onHold2 & ~processed;
 +            onHold2 = 0;
 +            while (current)
 +            {
 +                Square s = pop_lsb(&current);
 +                Bitboard attacks = (  (PseudoAttacks[Us][ptCtf][s] & pos.pieces())
 +                                    | (PseudoMoves[Us][ptCtf][s] & ~pos.pieces())) & ~processed & pos.board_bb();
 +                ctfPieces |= attacks & ~blocked;
 +                onHold |= attacks & ~doubleBlocked;
 +                onHold2 |= attacks & ~inaccessible;
 +            }
 +        }
 +    }
 +
 +    // nCheck
 +    if (pos.check_counting())
 +    {
 +        int remainingChecks = pos.checks_remaining(Us);
 +        assert(remainingChecks > 0);
 +        score += make_score(3600, 1000) / (remainingChecks * remainingChecks);
 +    }
 +
 +    // Extinction
 +    if (pos.extinction_value() != VALUE_NONE)
 +    {
 +        for (PieceType pt : pos.extinction_piece_types())
 +            if (pt != ALL_PIECES)
 +            {
 +                int denom = std::max(pos.count(Us, pt) - pos.extinction_piece_count(), 1);
 +                if (pos.count(Them, pt) >= pos.extinction_opponent_piece_count() || pos.two_boards())
 +                    score += make_score(1000000 / (500 + PieceValue[MG][pt]),
 +                                        1000000 / (500 + PieceValue[EG][pt])) / (denom * denom)
 +                            * (pos.extinction_value() / VALUE_MATE);
 +            }
 +            else if (pos.extinction_value() == VALUE_MATE)
 +                score += make_score(pos.non_pawn_material(Us), pos.non_pawn_material(Us)) / pos.count<ALL_PIECES>(Us);
 +    }
 +
 +    // Connect-n
 +    if (pos.connect_n() > 0)
 +    {
 +        for (Direction d : {NORTH, NORTH_EAST, EAST, SOUTH_EAST})
 +        {
 +            // Find sufficiently large gaps
 +            Bitboard b = pos.board_bb() & ~pos.pieces(Them);
 +            for (int i = 1; i < pos.connect_n(); i++)
 +                b &= shift(d, b);
 +            // Count number of pieces per gap
 +            while (b)
 +            {
 +                Square s = pop_lsb(&b);
 +                int c = 0;
 +                for (int j = 0; j < pos.connect_n(); j++)
 +                    if (pos.pieces(Us) & (s - j * d))
 +                        c++;
 +                score += make_score(200, 200)  * c / (pos.connect_n() - c) / (pos.connect_n() - c);
 +            }
 +        }
 +    }
 +
 +    // Potential piece flips
 +    if (pos.flip_enclosed_pieces())
 +    {
 +        // Stable pieces
 +        if (pos.flip_enclosed_pieces() == REVERSI)
 +        {
 +            Bitboard edges = (FileABB | file_bb(pos.max_file()) | Rank1BB | rank_bb(pos.max_rank())) & pos.board_bb();
 +            Bitboard edgePieces = pos.pieces(Us) & edges;
 +            while (edgePieces)
 +            {
 +                Bitboard connectedEdge = attacks_bb(Us, ROOK, pop_lsb(&edgePieces), ~(pos.pieces(Us) & edges)) & edges;
 +                if (!more_than_one(connectedEdge & ~pos.pieces(Us)))
 +                    score += make_score(300, 300);
 +                else if (!(connectedEdge & ~pos.pieces()))
 +                    score += make_score(200, 200);
 +            }
 +        }
 +
 +        // Unstable
 +        Bitboard unstable = 0;
 +        Bitboard drops = pos.drop_region(Them, IMMOBILE_PIECE);
 +        while (drops)
 +        {
 +            Square s = pop_lsb(&drops);
 +            if (pos.flip_enclosed_pieces() == REVERSI)
 +            {
 +                Bitboard b = attacks_bb(Them, QUEEN, s, ~pos.pieces(Us)) & ~PseudoAttacks[Them][KING][s] & pos.pieces(Them);
 +                while(b)
 +                    unstable |= between_bb(s, pop_lsb(&b));
 +            }
 +            else
 +                unstable |= PseudoAttacks[Them][KING][s] & pos.pieces(Us);
 +        }
 +        score -= make_score(200, 200) * popcount(unstable);
 +    }
 +
 +    if (T)
 +        Trace::add(VARIANT, Us, score);
 +
 +    return score;
 +  }
 +
 +
-   // Evaluation::winnable() adjusts the mg and eg score components based on the
-   // known attacking/defending status of the players. A single value is derived
-   // by interpolation from the mg and eg values and returned.
+   // Evaluation::winnable() adjusts the midgame and endgame score components, based on
+   // the known attacking/defending status of the players. The final value is derived
+   // by interpolation from the midgame and endgame values.
  
    template<Tracing T>
    Value Evaluation<T>::winnable(Score score) const {
      Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
      int sf = me->scale_factor(pos, strongSide);
  
-     // If scale is not already specific, scale down the endgame via general heuristics
+     // If scale factor is not already specific, scale down via general heuristics
 -    if (sf == SCALE_FACTOR_NORMAL)
 +    if (sf == SCALE_FACTOR_NORMAL && !pos.captures_to_hand())
      {
          if (pos.opposite_bishops())
          {
diff --cc src/search.cpp
@@@ -283,12 -261,12 +283,12 @@@ void MainThread::search() 
    if (Limits.npmsec)
        Time.availableNodes += Limits.inc[us] - Threads.nodes_searched();
  
 -  Thread* bestThread = this;
 +  bestThread = this;
  
-   if (int(Options["MultiPV"]) == 1 &&
-       !Limits.depth &&
-       !(Skill(Options["Skill Level"]).enabled() || int(Options["UCI_LimitStrength"])) &&
-       rootMoves[0].pv[0] != MOVE_NONE)
+   if (   int(Options["MultiPV"]) == 1
+       && !Limits.depth
+       && !(Skill(Options["Skill Level"]).enabled() || int(Options["UCI_LimitStrength"]))
+       && rootMoves[0].pv[0] != MOVE_NONE)
        bestThread = Threads.get_best_thread();
  
    bestPreviousScore = bestThread->rootMoves[0].score;