template<Color Us> Score threats() const;
template<Color Us> Score passed() const;
template<Color Us> Score space() const;
+ template<Color Us> Score variant() const;
ScaleFactor scale_factor(Value eg) const;
- Score initiative(Score score) const;
+ Score initiative(Score score, Score materialScore) const;
const Position& pos;
Material::Entry* me;
// known attacking/defending status of the players.
template<Tracing T>
- Score Evaluation<T>::initiative(Score score) const {
-
- Value mg = mg_value(score);
- Value eg = eg_value(score);
+ Score Evaluation<T>::initiative(Score score, Score materialScore) const {
- int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
- - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
+ // No initiative bonus for extinction variants
+ if (pos.extinction_value() != VALUE_NONE || pos.captures_to_hand() || pos.connect_n())
+ return SCORE_ZERO;
- bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
- || rank_of(pos.square<KING>(BLACK)) < RANK_5;
+ int outflanking = !pos.count<KING>(WHITE) || !pos.count<KING>(BLACK) ? 0
+ : distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
+ - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
+
+ bool infiltration = (pos.count<KING>(WHITE) && rank_of(pos.square<KING>(WHITE)) > RANK_4)
+ || (pos.count<KING>(BLACK) && rank_of(pos.square<KING>(BLACK)) < RANK_5);
bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
&& (pos.pieces(PAWN) & KingSide);
// Early exit if score is high
Value v = (mg_value(score) + eg_value(score)) / 2;
- if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
+ if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64 && Options["UCI_Variant"] == "chess")
return pos.side_to_move() == WHITE ? v : -v;
+ // Remember this score
+ Score materialScore = score;
+
// Main evaluation begins here
initialize<WHITE>();
score += king< WHITE>() - king< BLACK>()
+ threats<WHITE>() - threats<BLACK>()
+ passed< WHITE>() - passed< BLACK>()
- + space< WHITE>() - space< BLACK>();
+ + space< WHITE>() - space< BLACK>()
+ + variant<WHITE>() - variant<BLACK>();
- score += initiative(score);
+ score += initiative(score, materialScore);
// Interpolate between a middlegame and a (scaled by 'sf') endgame score
ScaleFactor sf = scale_factor(eg_value(score));
&& eval <= alpha - RazorMargin)
return qsearch<NT>(pos, ss, alpha, beta);
- improving = (ss-2)->staticEval == VALUE_NONE ? (ss->staticEval >= (ss-4)->staticEval
- || (ss-4)->staticEval == VALUE_NONE) : ss->staticEval >= (ss-2)->staticEval;
+ improving = (ss-2)->staticEval == VALUE_NONE ? (ss->staticEval > (ss-4)->staticEval
+ || (ss-4)->staticEval == VALUE_NONE) : ss->staticEval > (ss-2)->staticEval;
+ // Skip early pruning in case of mandatory capture
+ if (pos.must_capture() && MoveList<CAPTURES>(pos).size())
+ goto moves_loop;
+
// Step 8. Futility pruning: child node (~50 Elo)
if ( !PvNode
&& depth < 6
if (!pos.see_ge(move, Value(-(32 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth)))
continue;
}
- else if (!pos.see_ge(move, Value(-194) * depth)) // (~25 Elo)
+ else if (!pos.see_ge(move, Value(-194 - 120 * pos.captures_to_hand()) * depth)) // (~25 Elo)
- continue;
+ {
+ if (captureOrPromotion && captureCount < 32)
+ capturesSearched[captureCount++] = move;
+ continue;
+ }
}
// Step 14. Extensions (~75 Elo)
// hence break make_move(). (~2 Elo)
else if ( type_of(move) == NORMAL
&& !pos.see_ge(reverse_move(move)))
- r -= 2;
+ r -= 2 + ttPv;
ss->statScore = thisThread->mainHistory[us][from_to(move)]
- + (*contHist[0])[movedPiece][to_sq(move)]
- + (*contHist[1])[movedPiece][to_sq(move)]
- + (*contHist[3])[movedPiece][to_sq(move)]
+ + (*contHist[0])[history_slot(movedPiece)][to_sq(move)]
+ + (*contHist[1])[history_slot(movedPiece)][to_sq(move)]
+ + (*contHist[3])[history_slot(movedPiece)][to_sq(move)]
- 4926;
// Reset statScore to zero if negative and most stats shows >= 0