From 027d85e82a0a4bb3210039ae9b60da5bbaff546b Mon Sep 17 00:00:00 2001 From: Chris Caino Date: Mon, 14 Oct 2013 13:57:08 +0100 Subject: [PATCH 1/1] Add helper function verify_material Allows to remove a lot of assert code in endgames. No functional change. --- src/endgame.cpp | 137 +++++++++++++++++------------------------------- 1 file changed, 47 insertions(+), 90 deletions(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index 45a04815..f65a267d 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -59,6 +59,12 @@ namespace { const int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 }; 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(c) == num_pawns; + } +#endif + // 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 // 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<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); - assert(!pos.count(weakerSide)); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 0)); assert(!pos.checkers()); // Eval is never called when in check // Stalemate detection with lone king @@ -142,9 +147,9 @@ Value Endgame::operator()(const Position& pos) const { Square loserKSq = pos.king_square(weakerSide); Value result = pos.non_pawn_material(strongerSide) - + pos.count(strongerSide) * PawnValueEg - + PushToEdges[loserKSq] - + PushClose[square_distance(winnerKSq, loserKSq)]; + + pos.count(strongerSide) * PawnValueEg + + PushToEdges[loserKSq] + + PushClose[square_distance(winnerKSq, loserKSq)]; if ( pos.count(strongerSide) || pos.count(strongerSide) @@ -160,12 +165,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == KnightValueMg + BishopValueMg); - assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); - assert(pos.count(strongerSide) == 1); - assert(pos.count(strongerSide) == 1); - assert(pos.count< PAWN>(strongerSide) == 0); - assert(pos.count< PAWN>(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, KnightValueMg + BishopValueMg, 0)); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 0)); Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); @@ -192,10 +193,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); - assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); - assert(pos.count(strongerSide) == 1); - assert(pos.count(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, VALUE_ZERO, 1)); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 0)); Square wksq = pos.king_square(strongerSide); Square bksq = pos.king_square(weakerSide); @@ -233,10 +232,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == RookValueMg); - assert(pos.non_pawn_material(weakerSide) == 0); - assert(pos.count(strongerSide) == 0); - assert(pos.count(weakerSide ) == 1); + assert(verify_material(pos, strongerSide, RookValueMg, 0)); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 1)); Square wksq = pos.king_square(strongerSide); Square bksq = pos.king_square(weakerSide); @@ -287,11 +284,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == RookValueMg); - assert(pos.non_pawn_material(weakerSide ) == BishopValueMg); - assert(pos.count(weakerSide ) == 1); - assert(pos.count< PAWN>(weakerSide ) == 0); - assert(pos.count< PAWN>(strongerSide) == 0); + assert(verify_material(pos, strongerSide, RookValueMg, 0)); + assert(verify_material(pos, weakerSide, BishopValueMg, 0)); Value result = Value(PushToEdges[pos.king_square(weakerSide)]); return strongerSide == pos.side_to_move() ? result : -result; @@ -303,11 +297,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == RookValueMg); - assert(pos.non_pawn_material(weakerSide ) == KnightValueMg); - assert(pos.count(weakerSide ) == 1); - assert(pos.count< PAWN>(weakerSide ) == 0); - assert(pos.count< PAWN>(strongerSide) == 0); + assert(verify_material(pos, strongerSide, RookValueMg, 0)); + assert(verify_material(pos, weakerSide, KnightValueMg, 0)); Square bksq = pos.king_square(weakerSide); Square bnsq = pos.list(weakerSide)[0]; @@ -322,10 +313,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == QueenValueMg); - assert(pos.non_pawn_material(weakerSide ) == VALUE_ZERO); - assert(pos.count(strongerSide) == 0); - assert(pos.count(weakerSide ) == 1); + assert(verify_material(pos, strongerSide, QueenValueMg, 0)); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 1)); Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); @@ -350,10 +339,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == QueenValueMg); - assert(pos.non_pawn_material(weakerSide ) == RookValueMg); - assert(pos.count(strongerSide) == 0); - assert(pos.count(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, QueenValueMg, 0)); + assert(verify_material(pos, weakerSide, RookValueMg, 0)); Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); @@ -374,11 +361,8 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == 2 * BishopValueMg); - assert(pos.non_pawn_material(weakerSide ) == KnightValueMg); - assert(pos.count(strongerSide) == 2); - assert(pos.count(weakerSide ) == 1); - assert(!pos.pieces(PAWN)); + assert(verify_material(pos, strongerSide, 2 * BishopValueMg, 0)); + assert(verify_material(pos, weakerSide, KnightValueMg, 0)); Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); @@ -406,8 +390,7 @@ template<> ScaleFactor Endgame::operator()(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == BishopValueMg); - assert(pos.count(strongerSide) == 1); - assert(pos.count< PAWN>(strongerSide) >= 1); + assert(pos.count(strongerSide) >= 1); // No assertions about the material of weakerSide, because we want draws to // be detected even when the weaker side has some pawns. @@ -483,11 +466,9 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == QueenValueMg); - assert(pos.count(strongerSide) == 1); - assert(pos.count< PAWN>(strongerSide) == 0); - assert(pos.count< ROOK>(weakerSide ) == 1); - assert(pos.count< PAWN>(weakerSide ) >= 1); + assert(verify_material(pos, strongerSide, QueenValueMg, 0)); + assert(pos.count(weakerSide) == 1); + assert(pos.count(weakerSide) >= 1); Square kingSq = pos.king_square(weakerSide); Square rsq = pos.list(weakerSide)[0]; @@ -513,10 +494,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == RookValueMg); - assert(pos.non_pawn_material(weakerSide) == RookValueMg); - assert(pos.count(strongerSide) == 1); - assert(pos.count(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, RookValueMg, 1)); + assert(verify_material(pos, weakerSide, RookValueMg, 0)); Square wksq = pos.king_square(strongerSide); Square bksq = pos.king_square(weakerSide); @@ -628,10 +607,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == RookValueMg); - assert(pos.non_pawn_material(weakerSide) == BishopValueMg); - assert(pos.count(strongerSide) == 1); - assert(pos.count(weakerSide) == 0); + assert(verify_material(pos, strongerSide, RookValueMg, 1)); + assert(verify_material(pos, weakerSide, BishopValueMg, 0)); // Test for a rook pawn if (pos.pieces(PAWN) & (FileABB | FileHBB)) @@ -677,10 +654,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == RookValueMg); - assert(pos.non_pawn_material(weakerSide) == RookValueMg); - assert(pos.count(strongerSide) == 2); - assert(pos.count(weakerSide ) == 1); + assert(verify_material(pos, strongerSide, RookValueMg, 2)); + assert(verify_material(pos, weakerSide, RookValueMg, 1)); Square wpsq1 = pos.list(strongerSide)[0]; Square wpsq2 = pos.list(strongerSide)[1]; @@ -715,9 +690,8 @@ template<> ScaleFactor Endgame::operator()(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); - assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); assert(pos.count(strongerSide) >= 2); - assert(pos.count(weakerSide ) == 0); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 0)); Square ksq = pos.king_square(weakerSide); Bitboard pawns = pos.pieces(strongerSide, PAWN); @@ -751,12 +725,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == BishopValueMg); - assert(pos.non_pawn_material(weakerSide ) == BishopValueMg); - assert(pos.count(strongerSide) == 1); - assert(pos.count(weakerSide ) == 1); - assert(pos.count< PAWN>(strongerSide) == 1); - assert(pos.count< PAWN>(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, BishopValueMg, 1)); + assert(verify_material(pos, weakerSide, BishopValueMg, 0)); Square pawnSq = pos.list(strongerSide)[0]; Square strongerBishopSq = pos.list(strongerSide)[0]; @@ -806,12 +776,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == BishopValueMg); - assert(pos.non_pawn_material(weakerSide ) == BishopValueMg); - assert(pos.count(strongerSide) == 1); - assert(pos.count(weakerSide ) == 1); - assert(pos.count< PAWN>(strongerSide) == 2); - assert(pos.count< PAWN>(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, BishopValueMg, 2)); + assert(verify_material(pos, weakerSide, BishopValueMg, 0)); Square wbsq = pos.list(strongerSide)[0]; Square bbsq = pos.list(weakerSide)[0]; @@ -881,12 +847,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == BishopValueMg); - assert(pos.non_pawn_material(weakerSide ) == KnightValueMg); - assert(pos.count(strongerSide) == 1); - assert(pos.count(weakerSide ) == 1); - assert(pos.count< PAWN>(strongerSide) == 1); - assert(pos.count< PAWN>(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, BishopValueMg, 1)); + assert(verify_material(pos, weakerSide, KnightValueMg, 0)); Square pawnSq = pos.list(strongerSide)[0]; Square strongerBishopSq = pos.list(strongerSide)[0]; @@ -908,11 +870,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == KnightValueMg); - assert(pos.non_pawn_material(weakerSide ) == VALUE_ZERO); - assert(pos.count(strongerSide) == 1); - assert(pos.count< PAWN>(strongerSide) == 1); - assert(pos.count< PAWN>(weakerSide ) == 0); + assert(verify_material(pos, strongerSide, KnightValueMg, 1)); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 0)); Square pawnSq = pos.list(strongerSide)[0]; Square weakerKingSq = pos.king_square(weakerSide); @@ -955,10 +914,8 @@ ScaleFactor Endgame::operator()(const Position& pos) const { template<> ScaleFactor Endgame::operator()(const Position& pos) const { - assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); - assert(pos.non_pawn_material(weakerSide ) == VALUE_ZERO); - assert(pos.count(WHITE) == 1); - assert(pos.count(BLACK) == 1); + assert(verify_material(pos, strongerSide, VALUE_ZERO, 1)); + assert(verify_material(pos, weakerSide, VALUE_ZERO, 1)); Square wksq = pos.king_square(strongerSide); Square bksq = pos.king_square(weakerSide); -- 2.39.2