Skip to content

Commit

Permalink
Merge official-stockfish/master
Browse files Browse the repository at this point in the history
bench: 4262221
  • Loading branch information
ianfab committed Sep 20, 2020
2 parents 5601109 + 9587eee commit 72c8a58
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/endgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,8 +781,8 @@ ScaleFactor Endgame<KPsK>::operator()(const Position& pos) const {
Bitboard strongPawns = pos.pieces(strongSide, PAWN);

// If all pawns are ahead of the king on a single rook file, it's a draw.
if (!((strongPawns & ~FileABB) || (strongPawns & ~FileHBB)) &&
!(strongPawns & ~passed_pawn_span(weakSide, weakKing)))
if ( !(strongPawns & ~(FileABB | FileHBB))
&& !(strongPawns & ~passed_pawn_span(weakSide, weakKing)))
return SCALE_FACTOR_DRAW;

return SCALE_FACTOR_NONE;
Expand Down
49 changes: 36 additions & 13 deletions src/evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ using namespace Trace;
namespace {

// Threshold for lazy and space evaluation
constexpr Value LazyThreshold = Value(1400);
constexpr Value LazyThreshold1 = Value(1400);
constexpr Value LazyThreshold2 = Value(1300);
constexpr Value SpaceThreshold = Value(12222);

// KingAttackWeights[PieceType] contains king attack weights by piece type
Expand Down Expand Up @@ -137,6 +138,7 @@ namespace {
};

// Assorted bonuses and penalties
constexpr Score BadOutpost = S( -7, 36);
constexpr Score BishopOnKingRing = S( 24, 0);
constexpr Score BishopPawns = S( 3, 7);
constexpr Score BishopXRayPawns = S( 4, 5);
Expand Down Expand Up @@ -373,9 +375,17 @@ namespace {

if (Pt == BISHOP || Pt == KNIGHT)
{
// Bonus if piece is on an outpost square or can reach one
// Bonus if the piece is on an outpost square or can reach one
// Reduced bonus for knights (BadOutpost) if few relevant targets
bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
if (bb & s)
Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);

if ( Pt == KNIGHT
&& bb & s & ~CenterFiles // on a side outpost
&& !(b & targets) // no relevant attacks
&& (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
score += BadOutpost;
else if (bb & s)
score += Outpost[Pt == BISHOP];
else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
score += ReachableOutpost;
Expand Down Expand Up @@ -761,17 +771,21 @@ namespace {
// Bonus for threats on the next moves against enemy queen
if (pos.count<QUEEN>(Them) == 1)
{
bool queenImbalance = pos.count<QUEEN>() == 1;

Square s = pos.square<QUEEN>(Them);
safe = mobilityArea[Us] & ~stronglyProtected;
safe = mobilityArea[Us]
& ~pos.pieces(Us, PAWN)
& ~stronglyProtected;

b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);

score += KnightOnQueen * popcount(b & safe);
score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);

b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
| (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));

score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
}

if (T)
Expand Down Expand Up @@ -1157,7 +1171,8 @@ namespace {
&& pos.non_pawn_material(BLACK) == RookValueMg
&& pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
&& bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
&& (attackedBy[~strongSide][KING] & pos.pieces(~strongSide, PAWN)))
&& pos.count<KING>(~strongSide)
&& (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
sf = 36;
else if (pos.count<QUEEN>() == 1)
sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
Expand Down Expand Up @@ -1212,9 +1227,12 @@ namespace {
score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);

// Early exit if score is high
Value v = (mg_value(score) + eg_value(score)) / 2;
if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64 && Options["UCI_Variant"] == "chess")
return pos.side_to_move() == WHITE ? v : -v;
auto lazy_skip = [&](Value lazyThreshold) {
return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
};

if (lazy_skip(LazyThreshold1) && Options["UCI_Variant"] == "chess")
goto make_v;

// Main evaluation begins here
initialize<WHITE>();
Expand All @@ -1235,13 +1253,18 @@ namespace {

// More complex interactions that require fully populated attack bitboards
score += king< WHITE>() - king< BLACK>()
+ threats<WHITE>() - threats<BLACK>()
+ passed< WHITE>() - passed< BLACK>()
+ space< WHITE>() - space< BLACK>()
+ variant<WHITE>() - variant<BLACK>();

if (lazy_skip(LazyThreshold2) && Options["UCI_Variant"] == "chess")
goto make_v;

score += threats<WHITE>() - threats<BLACK>()
+ space< WHITE>() - space< BLACK>();

make_v:
// Derive single value from mg and eg parts of score
v = winnable(score);
Value v = winnable(score);

// In case of tracing add all remaining individual evaluation terms
if (T)
Expand Down
59 changes: 39 additions & 20 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ namespace {
Key posKey;
Move ttMove, move, excludedMove, bestMove;
Depth extension, newDepth;
Value bestValue, value, ttValue, eval, maxValue;
Value bestValue, value, ttValue, eval, maxValue, probcutBeta;
bool ttHit, ttPv, formerPv, givesCheck, improving, didLMR, priorCapture;
bool captureOrPromotion, doFullDepthSearch, moveCountPruning,
ttCapture, singularQuietLMR;
Expand Down Expand Up @@ -945,23 +945,33 @@ namespace {
}
}

probcutBeta = beta + (176 + 20 * !!pos.capture_the_flag_piece()) * (1 + pos.check_counting() + (pos.extinction_value() != VALUE_NONE)) - 49 * improving;

// Step 10. ProbCut (~10 Elo)
// If we have a good enough capture and a reduced search returns a value
// much above beta, we can (almost) safely prune the previous move.
if ( !PvNode
&& depth > 4
&& abs(beta) < VALUE_TB_WIN_IN_MAX_PLY)
&& abs(beta) < VALUE_TB_WIN_IN_MAX_PLY
&& !( ttHit
&& tte->depth() >= depth - 3
&& ttValue != VALUE_NONE
&& ttValue < probcutBeta))
{
Value raisedBeta = beta + (176 + 20 * !!pos.capture_the_flag_piece()) * (1 + pos.check_counting() + (pos.extinction_value() != VALUE_NONE)) - 49 * improving;
assert(raisedBeta < VALUE_INFINITE);
MovePicker mp(pos, ttMove, raisedBeta - ss->staticEval, &captureHistory);
if ( ttHit
&& tte->depth() >= depth - 3
&& ttValue != VALUE_NONE
&& ttValue >= probcutBeta
&& ttMove
&& pos.capture_or_promotion(ttMove))
return probcutBeta;

assert(probcutBeta < VALUE_INFINITE);
MovePicker mp(pos, ttMove, probcutBeta - ss->staticEval, &captureHistory);
int probCutCount = 0;

while ( (move = mp.next_move()) != MOVE_NONE
&& probCutCount < 2 + 2 * cutNode
&& !( move == ttMove
&& tte->depth() >= depth - 4
&& ttValue < raisedBeta))
&& probCutCount < 2 + 2 * cutNode)
if (move != excludedMove && pos.legal(move))
{
assert(pos.capture_or_promotion(move));
Expand All @@ -979,16 +989,24 @@ namespace {
pos.do_move(move, st);

// Perform a preliminary qsearch to verify that the move holds
value = -qsearch<NonPV>(pos, ss+1, -raisedBeta, -raisedBeta+1);
value = -qsearch<NonPV>(pos, ss+1, -probcutBeta, -probcutBeta+1);

// If the qsearch held, perform the regular search
if (value >= raisedBeta)
value = -search<NonPV>(pos, ss+1, -raisedBeta, -raisedBeta+1, depth - 4, !cutNode);
if (value >= probcutBeta)
value = -search<NonPV>(pos, ss+1, -probcutBeta, -probcutBeta+1, depth - 4, !cutNode);

pos.undo_move(move);

if (value >= raisedBeta)
if (value >= probcutBeta)
{
if ( !(ttHit
&& tte->depth() >= depth - 3
&& ttValue != VALUE_NONE))
tte->save(posKey, value_to_tt(value, ss->ply), ttPv,
BOUND_LOWER,
depth - 3, move, ss->staticEval);
return value;
}
}
}

Expand Down Expand Up @@ -1127,7 +1145,7 @@ namespace {
// search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
// then that move is singular and should be extended. To verify this we do
// a reduced search on all the other moves but the ttMove and if the
// result is lower than ttValue minus a margin then we will extend the ttMove.
// result is lower than ttValue minus a margin, then we will extend the ttMove.
if ( depth >= 6
&& move == ttMove
&& !rootNode
Expand Down Expand Up @@ -1191,12 +1209,6 @@ namespace {
if (type_of(move) == CASTLING)
extension = 1;

// Late irreversible move extension
if ( move == ttMove
&& pos.rule50_count() > 80
&& (captureOrPromotion || type_of(movedPiece) == PAWN))
extension = 2;

// Losing chess capture extension
else if ( pos.must_capture()
&& pos.capture(move)
Expand Down Expand Up @@ -1240,6 +1252,13 @@ namespace {
{
Depth r = reduction(improving, depth, moveCount);

// Decrease reduction at non-check cut nodes for second move at low depths
if ( cutNode
&& depth <= 10
&& moveCount <= 2
&& !ss->inCheck)
r--;

// Decrease reduction if the ttHit running average is large
if (thisThread->ttHitAverage > 473 * TtHitAverageResolution * TtHitAverageWindow / 1024)
r--;
Expand Down

0 comments on commit 72c8a58

Please sign in to comment.