Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Sat, 30 Mar 2019 13:32:34 +0000 (14:32 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sat, 30 Mar 2019 13:32:34 +0000 (14:32 +0100)
No functional change.

1  2 
src/bitboard.h
src/evaluate.cpp
src/psqt.cpp
src/search.cpp
src/tt.cpp
src/tt.h
src/types.h
tests/instrumented.sh

diff --cc src/bitboard.h
@@@ -203,17 -153,7 +203,17 @@@ inline Bitboard file_bb(Square s) 
  }
  
  
 +/// make_bitboard() returns a bitboard from a list of squares
 +
 +constexpr Bitboard make_bitboard() { return 0; }
 +
 +template<typename ...Squares>
 +constexpr Bitboard make_bitboard(Square s, Squares... squares) {
 +  return (Bitboard(1) << s) | make_bitboard(squares...);
 +}
 +
 +
- /// shift() moves a bitboard one step along direction D (mainly for pawns)
+ /// shift() moves a bitboard one step along direction D
  
  template<Direction D>
  constexpr Bitboard shift(Bitboard b) {
@@@ -157,13 -151,10 +157,13 @@@ namespace 
      S(-30,-14), S(-9, -8), S( 0,  9), S( -1,  7)
    };
  
 +  // KingProximity contains a penalty according to distance from king
 +  constexpr Score KingProximity = S(2, 2);
 +
    // Assorted bonuses and penalties
    constexpr Score BishopPawns        = S(  3,  7);
-   constexpr Score CloseEnemies       = S(  8,  0);
    constexpr Score CorneredBishop     = S( 50, 50);
+   constexpr Score FlankAttacks       = S(  8,  0);
    constexpr Score Hanging            = S( 69, 36);
    constexpr Score KingProtector      = S(  7,  8);
    constexpr Score KnightOnQueen      = S( 16, 12);
      constexpr Color     Them = (Us == WHITE ? BLACK : WHITE);
      constexpr Direction Up   = (Us == WHITE ? NORTH : SOUTH);
      constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
 -    constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB: Rank7BB | Rank6BB);
 +    Bitboard LowRanks = rank_bb(relative_rank(Us, RANK_2, pos.max_rank())) | rank_bb(relative_rank(Us, RANK_3, pos.max_rank()));
  
 -    const Square ksq = pos.square<KING>(Us);
++    const Square ksq = pos.count<KING>(Us) ? pos.square<KING>(Us) : SQ_NONE;
      // Find our pawns that are blocked or on the first two ranks
      Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
  
-     // Squares occupied by those pawns, by our king or queen, or controlled by enemy pawns
-     // are excluded from the mobility area.
+     // Squares occupied by those pawns, by our king or queen or controlled by
+     // enemy pawns are excluded from the mobility area.
 -    mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them));
 +    if (pos.must_capture())
 +        mobilityArea[Us] = AllSquares;
 +    else
 +        mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them) | shift<Down>(pos.pieces(Them, SHOGI_PAWN)));
  
-     // Initialise attackedBy bitboards for kings and pawns
-     attackedBy[Us][KING]       = pos.count<KING>(Us) ? pos.attacks_from<KING>(Us, pos.square<KING>(Us)) : 0;
-     attackedBy[Us][PAWN]       = pe->pawn_attacks(Us);
+     // Initialize attackedBy[] for king and pawns
 -    attackedBy[Us][KING] = pos.attacks_from<KING>(ksq);
++    attackedBy[Us][KING] = pos.count<KING>(Us) ? pos.attacks_from<KING>(Us, ksq) : 0;
+     attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
 -    attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
 -    attackedBy2[Us]            = attackedBy[Us][KING] & attackedBy[Us][PAWN];
 +    attackedBy[Us][SHOGI_PAWN] = shift<Up>(pos.pieces(Us, SHOGI_PAWN));
 +    attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN];
 +    attackedBy2[Us]            =  (attackedBy[Us][KING] & attackedBy[Us][PAWN])
 +                                | (attackedBy[Us][KING] & attackedBy[Us][SHOGI_PAWN])
 +                                | (attackedBy[Us][PAWN] & attackedBy[Us][SHOGI_PAWN]);
  
      // Init our king safety tables
      kingRing[Us] = attackedBy[Us][KING];
-     if (pos.count<KING>(Us) && relative_rank(Us, pos.square<KING>(Us), pos.max_rank()) == RANK_1)
 -    if (relative_rank(Us, ksq) == RANK_1)
++    if (pos.count<KING>(Us) && relative_rank(Us, ksq) == RANK_1)
          kingRing[Us] |= shift<Up>(kingRing[Us]);
  
-     if (pos.count<KING>(Us) && file_of(pos.square<KING>(Us)) == pos.max_file())
 -    if (file_of(ksq) == FILE_H)
++    if (pos.count<KING>(Us) && file_of(ksq) == pos.max_file())
          kingRing[Us] |= shift<WEST>(kingRing[Us]);
  
-     else if (pos.count<KING>(Us) && file_of(pos.square<KING>(Us)) == FILE_A)
 -    else if (file_of(ksq) == FILE_A)
++    else if (pos.count<KING>(Us) && file_of(ksq) == FILE_A)
          kingRing[Us] |= shift<EAST>(kingRing[Us]);
  
      kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
-     kingRing[Us] &= ~double_pawn_attacks_bb<Us>(pos.pieces(Us, PAWN));
      kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
+     // Remove from kingRing[] the squares defended by two pawns
+     kingRing[Us] &= ~pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
++
 +    kingRing[Us] &= pos.board_bb();
    }
  
  
      constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
      constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
                                                     : Rank5BB | Rank4BB | Rank3BB);
 -    const Square* pl = pos.squares<Pt>(Us);
 +    const Square* pl = pos.squares(Us, Pt);
  
      Bitboard b, bb;
-     Square s;
      Score score = SCORE_ZERO;
  
      attackedBy[Us][Pt] = 0;
    Score Evaluation<T>::king() const {
  
      constexpr Color    Them = (Us == WHITE ? BLACK : WHITE);
 -    constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
 -                                           : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
 +    Rank r = relative_rank(Us, std::min(Rank((pos.max_rank() - 1) / 2 + 1), pos.max_rank()), pos.max_rank());
 +    Bitboard Camp = AllSquares ^ forward_ranks_bb(Us, r);
 +
 +    if (!pos.count<KING>(Us) || !pos.checking_permitted())
 +        return SCORE_ZERO;
  
 -    Bitboard weak, b, b1, b2, safe, unsafeChecks = 0;
++    Bitboard weak, b, b1, b2, safe, QueenCheck, unsafeChecks = 0;
+     int kingDanger = 0;
      const Square ksq = pos.square<KING>(Us);
-     Bitboard kingFlank, weak, b, b1, b2, safe, unsafeChecks, QueenCheck;
  
-     // King shelter and enemy pawns storm
+     // Init the score with king shelter and enemy pawns storm
      Score score = pe->king_safety<Us>(pos);
  
-     // Find the squares that opponent attacks in our king flank, and the squares
-     // which are attacked twice in that flank but not defended by our pawns.
-     File f = std::max(std::min(file_of(ksq), File(pos.max_file() - 1)), FILE_B);
-     kingFlank = pos.max_file() == FILE_H ? KingFlank[file_of(ksq)] : file_bb(f) | adjacent_files_bb(f);
-     b1 = attackedBy[Them][ALL_PIECES] & kingFlank & Camp;
-     b2 = b1 & attackedBy2[Them];
-     int tropism = popcount(b1) + popcount(b2);
-     // Main king safety evaluation
-     int kingDanger = 0;
-     unsafeChecks = 0;
      // Attacked squares defended at most once by our queen or king
      weak =  attackedBy[Them][ALL_PIECES]
            & ~attackedBy2[Us]
      // the square is in the attacker's mobility area.
      unsafeChecks &= mobilityArea[Them];
  
++    File f = std::max(std::min(file_of(ksq), File(pos.max_file() - 1)), FILE_B);
++    Bitboard kingFlank = pos.max_file() == FILE_H ? KingFlank[file_of(ksq)] : file_bb(f) | adjacent_files_bb(f);
++
+     // Find the squares that opponent attacks in our king flank, and the squares
+     // which are attacked twice in that flank.
 -    b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
++    b1 = attackedBy[Them][ALL_PIECES] & kingFlank & Camp;
+     b2 = b1 & attackedBy2[Them];
+     int kingFlankAttacks = popcount(b1) + popcount(b2);
      kingDanger +=        kingAttackersCount[Them] * kingAttackersWeight[Them]
 -                 +  69 * kingAttacksCount[Them]
 -                 + 185 * popcount(kingRing[Us] & weak)
 +                 + 69  * kingAttacksCount[Them] * (1 + 2 * !!pos.max_check_count())
 +                 + 185 * popcount(kingRing[Us] & weak) * (1 + pos.captures_to_hand() + !!pos.max_check_count())
                   - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
                   + 150 * popcount(pos.blockers_for_king(Us) | unsafeChecks)
-                  +   5 * tropism * tropism / 16
 -                 - 873 * !pos.count<QUEEN>(Them)
 +                 - 873 * !(pos.count<QUEEN>(Them) || pos.captures_to_hand()) / (1 + !!pos.max_check_count())
                   -   6 * mg_value(score) / 8
                   +       mg_value(mobility[Them] - mobility[Us])
+                  +   5 * kingFlankAttacks * kingFlankAttacks / 16
                   -   25;
  
      // Transform the kingDanger units into a Score, and subtract it from the evaluation
      if (kingDanger > 0)
 -        score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
 +        score -= make_score(std::min(kingDanger * kingDanger / 4096, 3000), kingDanger / 16);
  
      // Penalty when our king is on a pawnless flank
 -    if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
 +    if (!(pos.pieces(PAWN) & kingFlank))
          score -= PawnlessFlank;
  
 -    // Penalty if king flank is under attack, potentially moving toward the king
 -    score -= FlankAttacks * kingFlankAttacks;
 +    // King tropism bonus, to anticipate slow motion attacks on our king
-     score -= CloseEnemies * tropism * (1 + pos.captures_to_hand() + !!pos.max_check_count());
++    score -= FlankAttacks * kingFlankAttacks * (1 + pos.captures_to_hand() + !!pos.max_check_count());
 +
 +    // For drop games, king danger is independent of game phase
 +    if (pos.captures_to_hand())
 +        score = make_score(mg_value(score), mg_value(score)) / (1 + !pos.shogi_doubled_pawn());
  
      if (T)
          Trace::add(KING, Us, score);
  
      // Interpolate between a middlegame and a (scaled by 'sf') endgame score
      ScaleFactor sf = scale_factor(eg_value(score));
 -    v =  mg_value(score) * int(me->game_phase())
 -       + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
 +    Value v =  mg_value(score) * int(me->game_phase())
 +             + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
  
-     v /= int(PHASE_MIDGAME);
+     v /= PHASE_MIDGAME;
  
      // In case of tracing add all remaining individual evaluation terms
      if (T)
diff --cc src/psqt.cpp
@@@ -68,36 -59,35 +68,36 @@@ constexpr Score Bonus[PIECE_TYPE_NB][RA
     { S(-48,-51), S( -3,-40), S(-12,-39), S(-25,-20) }
    },
    { // Rook
-    { S(-24, -2), S(-13,-6), S( -7, -3), S( 2,-2) },
-    { S(-18,-10), S(-10,-7), S( -5,  1), S( 9, 0) },
-    { S(-21, 10), S( -7,-4), S(  3,  2), S(-1,-2) },
-    { S(-13, -5), S( -5, 2), S( -4, -8), S(-6, 8) },
-    { S(-24, -8), S(-12, 5), S( -1,  4), S( 6,-9) },
-    { S(-24,  3), S( -4,-2), S(  4,-10), S(10, 7) },
-    { S( -8,  1), S(  6, 2), S( 10, 17), S(12,-8) },
-    { S(-22, 12), S(-24,-6), S( -6, 13), S( 4, 7) }
+    { S(-24, -2), S(-13,-6), S(-7, -3), S( 2,-2) },
+    { S(-18,-10), S(-10,-7), S(-5,  1), S( 9, 0) },
+    { S(-21, 10), S( -7,-4), S( 3,  2), S(-1,-2) },
+    { S(-13, -5), S( -5, 2), S(-4, -8), S(-6, 8) },
+    { S(-24, -8), S(-12, 5), S(-1,  4), S( 6,-9) },
+    { S(-24,  3), S( -4,-2), S( 4,-10), S(10, 7) },
+    { S( -8,  1), S(  6, 2), S(10, 17), S(12,-8) },
+    { S(-22, 12), S(-24,-6), S(-6, 13), S( 4, 7) }
    },
    { // Queen
-    { S(  3,-69), S(-5,-57), S(-5,-47), S( 4,-26) },
-    { S( -3,-55), S( 5,-31), S( 8,-22), S(12, -4) },
-    { S( -3,-39), S( 6,-18), S(13, -9), S( 7,  3) },
-    { S(  4,-23), S( 5, -3), S( 9, 13), S( 8, 24) },
-    { S(  0,-29), S(14, -6), S(12,  9), S( 5, 21) },
-    { S( -4,-38), S(10,-18), S( 6,-12), S( 8,  1) },
-    { S( -5,-50), S( 6,-27), S(10,-24), S( 8, -8) },
-    { S( -2,-75), S(-2,-52), S( 1,-43), S(-2,-36) }
+    { S( 3,-69), S(-5,-57), S(-5,-47), S( 4,-26) },
+    { S(-3,-55), S( 5,-31), S( 8,-22), S(12, -4) },
+    { S(-3,-39), S( 6,-18), S(13, -9), S( 7,  3) },
+    { S( 4,-23), S( 5, -3), S( 9, 13), S( 8, 24) },
+    { S( 0,-29), S(14, -6), S(12,  9), S( 5, 21) },
+    { S(-4,-38), S(10,-18), S( 6,-12), S( 8,  1) },
+    { S(-5,-50), S( 6,-27), S(10,-24), S( 8, -8) },
+    { S(-2,-75), S(-2,-52), S( 1,-43), S(-2,-36) }
 -  },
 -  { // King
 +  }
 +};
 +
 +constexpr Score KingBonus[RANK_NB][int(FILE_NB) / 2] = {
     { S(272,  0), S(325, 41), S(273, 80), S(190, 93) },
     { S(277, 57), S(305, 98), S(241,138), S(183,131) },
     { S(198, 86), S(253,138), S(168,165), S(120,173) },
     { S(169,103), S(191,152), S(136,168), S(108,169) },
-    { S(145, 98), S(176,166), S(112,197), S(69, 194) },
-    { S(122, 87), S(159,164), S(85, 174), S(36, 189) },
-    { S(87,  40), S(120, 99), S(64, 128), S(25, 141) },
-    { S(64,   5), S(87,  60), S(49,  75), S(0,   75) }
+    { S(145, 98), S(176,166), S(112,197), S( 69,194) },
+    { S(122, 87), S(159,164), S( 85,174), S( 36,189) },
+    { S( 87, 40), S(120, 99), S( 64,128), S( 25,141) },
+    { S( 64,  5), S( 87, 60), S( 49, 75), S(  0, 75) }
 -  }
  };
  
  constexpr Score PBonus[RANK_NB][FILE_NB] =
diff --cc src/search.cpp
@@@ -758,9 -749,9 +754,9 @@@ namespace 
              ss->staticEval = eval = pureStaticEval + bonus;
          }
          else
 -            ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::Tempo;
 +            ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::tempo_value(pos);
  
-         tte->save(posKey, VALUE_NONE, pvHit, BOUND_NONE, DEPTH_NONE, MOVE_NONE, pureStaticEval);
+         tte->save(posKey, VALUE_NONE, ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, pureStaticEval);
      }
  
      // Step 7. Razoring (~2 Elo)
diff --cc src/tt.cpp
Simple merge
diff --cc src/tt.h
Simple merge
diff --cc src/types.h
Simple merge
Simple merge