enum Tracing { NO_TRACE, TRACE };
enum Term { // The first 8 entries are reserved for PieceType
- MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, INITIATIVE, TOTAL, TERM_NB
+ MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, INITIATIVE, VARIANT, TOTAL, TERM_NB
};
Score scores[TERM_NB][COLOR_NB];
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(Value eg) const;
}
+ // 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 == WHITE ? BLACK : WHITE);
+
+ Score score = SCORE_ZERO;
+
+ // Capture the flag
+ if (pos.capture_the_flag(Us))
+ {
+ Bitboard target_squares = pos.capture_the_flag(Us);
+ while (target_squares)
+ {
+ Square s = pop_lsb(&target_squares);
+ int dist = distance(pos.square<KING>(Us), s)
+ + popcount(pos.attackers_to(s) & pos.pieces(Them))
+ + !!(pos.pieces(Us) & s);
+ score += make_score(3000, 3000) / (1 + dist * dist);
+ }
+ }
+
+ // nCheck
+ if (pos.max_check_count())
+ {
+ int remainingChecks = pos.max_check_count() - pos.checks_given(Us);
+ assert(remainingChecks > 0);
+ score += make_score(3000, 1000) / (remainingChecks * remainingChecks);
+ }
+
+ if (T)
+ Trace::add(VARIANT, Us, score);
+
+ return score;
+ }
+
+
// Evaluation::initiative() computes the initiative correction value
// for the position. It is a second order bonus/malus based on the
// known attacking/defending status of the players.
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(eg_value(score));
<< " Threats | " << Term(THREAT)
<< " Passed | " << Term(PASSED)
<< " Space | " << Term(SPACE)
+ << " Variant | " << Term(VARIANT)
<< " ------------+-------------+-------------+------------\n"
<< " Total | " << Term(TOTAL);
Bitboard capture_the_flag(Color c) const;
bool flag_move() const;
CheckCount max_check_count() const;
+ CheckCount checks_given(Color c) const;
bool is_variant_end() const;
bool is_variant_end(Value& result, int ply = 0) const;
return var->maxCheckCount;
}
+inline CheckCount Position::checks_given(Color c) const {
+ return st->checksGiven[c];
+}
+
inline bool Position::is_variant_end() const {
Value result;
return is_variant_end(result);
const Variant* kingofthehill = [&]{
Variant* v = new Variant();
v->whiteFlag = make_bitboard(SQ_D4, SQ_E4, SQ_D5, SQ_E5);
- v->whiteFlag = make_bitboard(SQ_D4, SQ_E4, SQ_D5, SQ_E5);
+ v->blackFlag = make_bitboard(SQ_D4, SQ_E4, SQ_D5, SQ_E5);
v->flagMove = false;
return v;
} ();
Variant* v = new Variant();
v->startFen = "8/8/8/8/8/8/krbnNBRK/qrbnNBRQ w - - 0 1";
v->whiteFlag = Rank8BB;
- v->whiteFlag = Rank8BB;
+ v->blackFlag = Rank8BB;
v->flagMove = true;
v->castling = false;
v->checking = false;