1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-01 09:13:08 +00:00

Add helper function verify_material

Allows to remove a lot of assert code in endgames.

No functional change.
This commit is contained in:
Chris Caino 2013-10-14 13:57:08 +01:00 committed by Marco Costalba
parent 3bc3c069f1
commit 027d85e82a

View file

@ -59,6 +59,12 @@ namespace {
const int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 }; const int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
const int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 }; const int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 };
#ifndef NDEBUG
bool verify_material(const Position& pos, Color c, Value npm, int num_pawns) {
return pos.non_pawn_material(c) == npm && pos.count<PAWN>(c) == num_pawns;
}
#endif
// Get the material key of a Position out of the given endgame key code // Get the material key of a Position out of the given endgame key code
// like "KBPKN". The trick here is to first forge an ad-hoc fen string // like "KBPKN". The trick here is to first forge an ad-hoc fen string
// and then let a Position object to do the work for us. Note that the // and then let a Position object to do the work for us. Note that the
@ -130,8 +136,7 @@ void Endgames::add(const string& code) {
template<> template<>
Value Endgame<KXK>::operator()(const Position& pos) const { Value Endgame<KXK>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); assert(verify_material(pos, weakerSide, VALUE_ZERO, 0));
assert(!pos.count<PAWN>(weakerSide));
assert(!pos.checkers()); // Eval is never called when in check assert(!pos.checkers()); // Eval is never called when in check
// Stalemate detection with lone king // Stalemate detection with lone king
@ -160,12 +165,8 @@ Value Endgame<KXK>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KBNK>::operator()(const Position& pos) const { Value Endgame<KBNK>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == KnightValueMg + BishopValueMg); assert(verify_material(pos, strongerSide, KnightValueMg + BishopValueMg, 0));
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); assert(verify_material(pos, weakerSide, VALUE_ZERO, 0));
assert(pos.count<BISHOP>(strongerSide) == 1);
assert(pos.count<KNIGHT>(strongerSide) == 1);
assert(pos.count< PAWN>(strongerSide) == 0);
assert(pos.count< PAWN>(weakerSide ) == 0);
Square winnerKSq = pos.king_square(strongerSide); Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide); Square loserKSq = pos.king_square(weakerSide);
@ -192,10 +193,8 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KPK>::operator()(const Position& pos) const { Value Endgame<KPK>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); assert(verify_material(pos, strongerSide, VALUE_ZERO, 1));
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); assert(verify_material(pos, weakerSide, VALUE_ZERO, 0));
assert(pos.count<PAWN>(strongerSide) == 1);
assert(pos.count<PAWN>(weakerSide ) == 0);
Square wksq = pos.king_square(strongerSide); Square wksq = pos.king_square(strongerSide);
Square bksq = pos.king_square(weakerSide); Square bksq = pos.king_square(weakerSide);
@ -233,10 +232,8 @@ Value Endgame<KPK>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KRKP>::operator()(const Position& pos) const { Value Endgame<KRKP>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == RookValueMg); assert(verify_material(pos, strongerSide, RookValueMg, 0));
assert(pos.non_pawn_material(weakerSide) == 0); assert(verify_material(pos, weakerSide, VALUE_ZERO, 1));
assert(pos.count<PAWN>(strongerSide) == 0);
assert(pos.count<PAWN>(weakerSide ) == 1);
Square wksq = pos.king_square(strongerSide); Square wksq = pos.king_square(strongerSide);
Square bksq = pos.king_square(weakerSide); Square bksq = pos.king_square(weakerSide);
@ -287,11 +284,8 @@ Value Endgame<KRKP>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KRKB>::operator()(const Position& pos) const { Value Endgame<KRKB>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == RookValueMg); assert(verify_material(pos, strongerSide, RookValueMg, 0));
assert(pos.non_pawn_material(weakerSide ) == BishopValueMg); assert(verify_material(pos, weakerSide, BishopValueMg, 0));
assert(pos.count<BISHOP>(weakerSide ) == 1);
assert(pos.count< PAWN>(weakerSide ) == 0);
assert(pos.count< PAWN>(strongerSide) == 0);
Value result = Value(PushToEdges[pos.king_square(weakerSide)]); Value result = Value(PushToEdges[pos.king_square(weakerSide)]);
return strongerSide == pos.side_to_move() ? result : -result; return strongerSide == pos.side_to_move() ? result : -result;
@ -303,11 +297,8 @@ Value Endgame<KRKB>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KRKN>::operator()(const Position& pos) const { Value Endgame<KRKN>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == RookValueMg); assert(verify_material(pos, strongerSide, RookValueMg, 0));
assert(pos.non_pawn_material(weakerSide ) == KnightValueMg); assert(verify_material(pos, weakerSide, KnightValueMg, 0));
assert(pos.count<KNIGHT>(weakerSide ) == 1);
assert(pos.count< PAWN>(weakerSide ) == 0);
assert(pos.count< PAWN>(strongerSide) == 0);
Square bksq = pos.king_square(weakerSide); Square bksq = pos.king_square(weakerSide);
Square bnsq = pos.list<KNIGHT>(weakerSide)[0]; Square bnsq = pos.list<KNIGHT>(weakerSide)[0];
@ -322,10 +313,8 @@ Value Endgame<KRKN>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KQKP>::operator()(const Position& pos) const { Value Endgame<KQKP>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == QueenValueMg); assert(verify_material(pos, strongerSide, QueenValueMg, 0));
assert(pos.non_pawn_material(weakerSide ) == VALUE_ZERO); assert(verify_material(pos, weakerSide, VALUE_ZERO, 1));
assert(pos.count<PAWN>(strongerSide) == 0);
assert(pos.count<PAWN>(weakerSide ) == 1);
Square winnerKSq = pos.king_square(strongerSide); Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide); Square loserKSq = pos.king_square(weakerSide);
@ -350,10 +339,8 @@ Value Endgame<KQKP>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KQKR>::operator()(const Position& pos) const { Value Endgame<KQKR>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == QueenValueMg); assert(verify_material(pos, strongerSide, QueenValueMg, 0));
assert(pos.non_pawn_material(weakerSide ) == RookValueMg); assert(verify_material(pos, weakerSide, RookValueMg, 0));
assert(pos.count<PAWN>(strongerSide) == 0);
assert(pos.count<PAWN>(weakerSide ) == 0);
Square winnerKSq = pos.king_square(strongerSide); Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide); Square loserKSq = pos.king_square(weakerSide);
@ -374,11 +361,8 @@ Value Endgame<KQKR>::operator()(const Position& pos) const {
template<> template<>
Value Endgame<KBBKN>::operator()(const Position& pos) const { Value Endgame<KBBKN>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == 2 * BishopValueMg); assert(verify_material(pos, strongerSide, 2 * BishopValueMg, 0));
assert(pos.non_pawn_material(weakerSide ) == KnightValueMg); assert(verify_material(pos, weakerSide, KnightValueMg, 0));
assert(pos.count<BISHOP>(strongerSide) == 2);
assert(pos.count<KNIGHT>(weakerSide ) == 1);
assert(!pos.pieces(PAWN));
Square winnerKSq = pos.king_square(strongerSide); Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide); Square loserKSq = pos.king_square(weakerSide);
@ -406,7 +390,6 @@ template<>
ScaleFactor Endgame<KBPsK>::operator()(const Position& pos) const { ScaleFactor Endgame<KBPsK>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == BishopValueMg); assert(pos.non_pawn_material(strongerSide) == BishopValueMg);
assert(pos.count<BISHOP>(strongerSide) == 1);
assert(pos.count<PAWN>(strongerSide) >= 1); assert(pos.count<PAWN>(strongerSide) >= 1);
// No assertions about the material of weakerSide, because we want draws to // No assertions about the material of weakerSide, because we want draws to
@ -483,9 +466,7 @@ ScaleFactor Endgame<KBPsK>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KQKRPs>::operator()(const Position& pos) const { ScaleFactor Endgame<KQKRPs>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == QueenValueMg); assert(verify_material(pos, strongerSide, QueenValueMg, 0));
assert(pos.count<QUEEN>(strongerSide) == 1);
assert(pos.count< PAWN>(strongerSide) == 0);
assert(pos.count<ROOK>(weakerSide) == 1); assert(pos.count<ROOK>(weakerSide) == 1);
assert(pos.count<PAWN>(weakerSide) >= 1); assert(pos.count<PAWN>(weakerSide) >= 1);
@ -513,10 +494,8 @@ ScaleFactor Endgame<KQKRPs>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const { ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == RookValueMg); assert(verify_material(pos, strongerSide, RookValueMg, 1));
assert(pos.non_pawn_material(weakerSide) == RookValueMg); assert(verify_material(pos, weakerSide, RookValueMg, 0));
assert(pos.count<PAWN>(strongerSide) == 1);
assert(pos.count<PAWN>(weakerSide ) == 0);
Square wksq = pos.king_square(strongerSide); Square wksq = pos.king_square(strongerSide);
Square bksq = pos.king_square(weakerSide); Square bksq = pos.king_square(weakerSide);
@ -628,10 +607,8 @@ ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KRPKB>::operator()(const Position& pos) const { ScaleFactor Endgame<KRPKB>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == RookValueMg); assert(verify_material(pos, strongerSide, RookValueMg, 1));
assert(pos.non_pawn_material(weakerSide) == BishopValueMg); assert(verify_material(pos, weakerSide, BishopValueMg, 0));
assert(pos.count<PAWN>(strongerSide) == 1);
assert(pos.count<PAWN>(weakerSide) == 0);
// Test for a rook pawn // Test for a rook pawn
if (pos.pieces(PAWN) & (FileABB | FileHBB)) if (pos.pieces(PAWN) & (FileABB | FileHBB))
@ -677,10 +654,8 @@ ScaleFactor Endgame<KRPKB>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KRPPKRP>::operator()(const Position& pos) const { ScaleFactor Endgame<KRPPKRP>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == RookValueMg); assert(verify_material(pos, strongerSide, RookValueMg, 2));
assert(pos.non_pawn_material(weakerSide) == RookValueMg); assert(verify_material(pos, weakerSide, RookValueMg, 1));
assert(pos.count<PAWN>(strongerSide) == 2);
assert(pos.count<PAWN>(weakerSide ) == 1);
Square wpsq1 = pos.list<PAWN>(strongerSide)[0]; Square wpsq1 = pos.list<PAWN>(strongerSide)[0];
Square wpsq2 = pos.list<PAWN>(strongerSide)[1]; Square wpsq2 = pos.list<PAWN>(strongerSide)[1];
@ -715,9 +690,8 @@ template<>
ScaleFactor Endgame<KPsK>::operator()(const Position& pos) const { ScaleFactor Endgame<KPsK>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO);
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
assert(pos.count<PAWN>(strongerSide) >= 2); assert(pos.count<PAWN>(strongerSide) >= 2);
assert(pos.count<PAWN>(weakerSide ) == 0); assert(verify_material(pos, weakerSide, VALUE_ZERO, 0));
Square ksq = pos.king_square(weakerSide); Square ksq = pos.king_square(weakerSide);
Bitboard pawns = pos.pieces(strongerSide, PAWN); Bitboard pawns = pos.pieces(strongerSide, PAWN);
@ -751,12 +725,8 @@ ScaleFactor Endgame<KPsK>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KBPKB>::operator()(const Position& pos) const { ScaleFactor Endgame<KBPKB>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == BishopValueMg); assert(verify_material(pos, strongerSide, BishopValueMg, 1));
assert(pos.non_pawn_material(weakerSide ) == BishopValueMg); assert(verify_material(pos, weakerSide, BishopValueMg, 0));
assert(pos.count<BISHOP>(strongerSide) == 1);
assert(pos.count<BISHOP>(weakerSide ) == 1);
assert(pos.count< PAWN>(strongerSide) == 1);
assert(pos.count< PAWN>(weakerSide ) == 0);
Square pawnSq = pos.list<PAWN>(strongerSide)[0]; Square pawnSq = pos.list<PAWN>(strongerSide)[0];
Square strongerBishopSq = pos.list<BISHOP>(strongerSide)[0]; Square strongerBishopSq = pos.list<BISHOP>(strongerSide)[0];
@ -806,12 +776,8 @@ ScaleFactor Endgame<KBPKB>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const { ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == BishopValueMg); assert(verify_material(pos, strongerSide, BishopValueMg, 2));
assert(pos.non_pawn_material(weakerSide ) == BishopValueMg); assert(verify_material(pos, weakerSide, BishopValueMg, 0));
assert(pos.count<BISHOP>(strongerSide) == 1);
assert(pos.count<BISHOP>(weakerSide ) == 1);
assert(pos.count< PAWN>(strongerSide) == 2);
assert(pos.count< PAWN>(weakerSide ) == 0);
Square wbsq = pos.list<BISHOP>(strongerSide)[0]; Square wbsq = pos.list<BISHOP>(strongerSide)[0];
Square bbsq = pos.list<BISHOP>(weakerSide)[0]; Square bbsq = pos.list<BISHOP>(weakerSide)[0];
@ -881,12 +847,8 @@ ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KBPKN>::operator()(const Position& pos) const { ScaleFactor Endgame<KBPKN>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == BishopValueMg); assert(verify_material(pos, strongerSide, BishopValueMg, 1));
assert(pos.non_pawn_material(weakerSide ) == KnightValueMg); assert(verify_material(pos, weakerSide, KnightValueMg, 0));
assert(pos.count<BISHOP>(strongerSide) == 1);
assert(pos.count<KNIGHT>(weakerSide ) == 1);
assert(pos.count< PAWN>(strongerSide) == 1);
assert(pos.count< PAWN>(weakerSide ) == 0);
Square pawnSq = pos.list<PAWN>(strongerSide)[0]; Square pawnSq = pos.list<PAWN>(strongerSide)[0];
Square strongerBishopSq = pos.list<BISHOP>(strongerSide)[0]; Square strongerBishopSq = pos.list<BISHOP>(strongerSide)[0];
@ -908,11 +870,8 @@ ScaleFactor Endgame<KBPKN>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KNPK>::operator()(const Position& pos) const { ScaleFactor Endgame<KNPK>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == KnightValueMg); assert(verify_material(pos, strongerSide, KnightValueMg, 1));
assert(pos.non_pawn_material(weakerSide ) == VALUE_ZERO); assert(verify_material(pos, weakerSide, VALUE_ZERO, 0));
assert(pos.count<KNIGHT>(strongerSide) == 1);
assert(pos.count< PAWN>(strongerSide) == 1);
assert(pos.count< PAWN>(weakerSide ) == 0);
Square pawnSq = pos.list<PAWN>(strongerSide)[0]; Square pawnSq = pos.list<PAWN>(strongerSide)[0];
Square weakerKingSq = pos.king_square(weakerSide); Square weakerKingSq = pos.king_square(weakerSide);
@ -955,10 +914,8 @@ ScaleFactor Endgame<KNPKB>::operator()(const Position& pos) const {
template<> template<>
ScaleFactor Endgame<KPKP>::operator()(const Position& pos) const { ScaleFactor Endgame<KPKP>::operator()(const Position& pos) const {
assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); assert(verify_material(pos, strongerSide, VALUE_ZERO, 1));
assert(pos.non_pawn_material(weakerSide ) == VALUE_ZERO); assert(verify_material(pos, weakerSide, VALUE_ZERO, 1));
assert(pos.count<PAWN>(WHITE) == 1);
assert(pos.count<PAWN>(BLACK) == 1);
Square wksq = pos.king_square(strongerSide); Square wksq = pos.king_square(strongerSide);
Square bksq = pos.king_square(weakerSide); Square bksq = pos.king_square(weakerSide);