const int NoPawnsSF[4] = { 6, 12, 32 };
// Polynomial material balance parameters
- const Value RedundantQueenPenalty = Value(320);
- const Value RedundantRookPenalty = Value(554);
+ const Value RedundantQueen = Value(320);
+ const Value RedundantRook = Value(554);
- const int LinearCoefficients[6] = { 1617, -162, -1172, -190, 105, 26 };
+ // pair pawn knight bishop rook queen
+ const int LinearCoefficients[6] = { 1617, -162, -1172, -190, 105, 26 };
const int QuadraticCoefficientsSameColor[][PIECE_TYPE_NB] = {
- { 7, 7, 7, 7, 7, 7 }, { 39, 2, 7, 7, 7, 7 }, { 35, 271, -4, 7, 7, 7 },
- { 7, 25, 4, 7, 7, 7 }, { -27, -2, 46, 100, 56, 7 }, { 58, 29, 83, 148, -3, -25 } };
+ // pair pawn knight bishop rook queen
+ { 7 }, // Bishop pair
+ { 39, 2 }, // Pawn
+ { 35, 271, -4 }, // Knight
+ { 7, 105, 4, 7 }, // Bishop
+ { -27, -2, 46, 100, 56 }, // Rook
+ { 58, 29, 83, 148, -3, -25 } // Queen
+ };
const int QuadraticCoefficientsOppositeColor[][PIECE_TYPE_NB] = {
- { 41, 41, 41, 41, 41, 41 }, { 37, 41, 41, 41, 41, 41 }, { 10, 62, 41, 41, 41, 41 },
- { 57, 64, 39, 41, 41, 41 }, { 50, 40, 23, -22, 41, 41 }, { 106, 101, 3, 151, 171, 41 } };
+ // THEIR PIECES
+ // pair pawn knight bishop rook queen
+ { 41 }, // Bishop pair
+ { 37, 41 }, // Pawn
+ { 10, 62, 41 }, // Knight OUR PIECES
+ { 57, 64, 39, 41 }, // Bishop
+ { 50, 40, 23, -22, 41 }, // Rook
+ { 106, 101, 3, 151, 171, 41 } // Queen
+ };
// Endgame evaluation and scaling functions accessed direcly and not through
// the function maps because correspond to more then one material hash key.
// Helper templates used to detect a given material distribution
template<Color Us> bool is_KXK(const Position& pos) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
- return pos.non_pawn_material(Them) == VALUE_ZERO
- && pos.piece_count(Them, PAWN) == 0
- && pos.non_pawn_material(Us) >= RookValueMg;
+ return !pos.count<PAWN>(Them)
+ && pos.non_pawn_material(Them) == VALUE_ZERO
+ && pos.non_pawn_material(Us) >= RookValueMg;
}
template<Color Us> bool is_KBPsKs(const Position& pos) {
- return pos.non_pawn_material(Us) == BishopValueMg
- && pos.piece_count(Us, BISHOP) == 1
- && pos.piece_count(Us, PAWN) >= 1;
+ return pos.non_pawn_material(Us) == BishopValueMg
+ && pos.count<BISHOP>(Us) == 1
+ && pos.count<PAWN >(Us) >= 1;
}
template<Color Us> bool is_KQKRPs(const Position& pos) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
- return pos.piece_count(Us, PAWN) == 0
- && pos.non_pawn_material(Us) == QueenValueMg
- && pos.piece_count(Us, QUEEN) == 1
- && pos.piece_count(Them, ROOK) == 1
- && pos.piece_count(Them, PAWN) >= 1;
+ return !pos.count<PAWN>(Us)
+ && pos.non_pawn_material(Us) == QueenValueMg
+ && pos.count<QUEEN>(Us) == 1
+ && pos.count<ROOK>(Them) == 1
+ && pos.count<PAWN>(Them) >= 1;
}
/// imbalance() calculates imbalance comparing piece count of each
// Redundancy of major pieces, formula based on Kaufman's paper
// "The Evaluation of Material Imbalances in Chess"
if (pieceCount[Us][ROOK] > 0)
- value -= RedundantRookPenalty * (pieceCount[Us][ROOK] - 1)
- + RedundantQueenPenalty * pieceCount[Us][QUEEN];
+ value -= RedundantRook * (pieceCount[Us][ROOK] - 1)
+ + RedundantQueen * pieceCount[Us][QUEEN];
// Second-degree polynomial material imbalance by Tord Romstad
for (pt1 = NO_PIECE_TYPE; pt1 <= QUEEN; pt1++)
if (e->key == key)
return e;
- memset(e, 0, sizeof(Entry));
+ std::memset(e, 0, sizeof(Entry));
e->key = key;
e->factor[WHITE] = e->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
e->gamePhase = game_phase(pos);
assert((pos.pieces(WHITE, KNIGHT) | pos.pieces(WHITE, BISHOP)));
assert((pos.pieces(BLACK, KNIGHT) | pos.pieces(BLACK, BISHOP)));
- if ( pos.piece_count(WHITE, BISHOP) + pos.piece_count(WHITE, KNIGHT) <= 2
- && pos.piece_count(BLACK, BISHOP) + pos.piece_count(BLACK, KNIGHT) <= 2)
+ if ( pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE) <= 2
+ && pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK) <= 2)
{
e->evaluationFunction = &EvaluateKmmKm[pos.side_to_move()];
return e;
if (npm_w + npm_b == VALUE_ZERO)
{
- if (pos.piece_count(BLACK, PAWN) == 0)
+ if (!pos.count<PAWN>(BLACK))
{
- assert(pos.piece_count(WHITE, PAWN) >= 2);
+ assert(pos.count<PAWN>(WHITE) >= 2);
e->scalingFunction[WHITE] = &ScaleKPsK[WHITE];
}
- else if (pos.piece_count(WHITE, PAWN) == 0)
+ else if (!pos.count<PAWN>(WHITE))
{
- assert(pos.piece_count(BLACK, PAWN) >= 2);
+ assert(pos.count<PAWN>(BLACK) >= 2);
e->scalingFunction[BLACK] = &ScaleKPsK[BLACK];
}
- else if (pos.piece_count(WHITE, PAWN) == 1 && pos.piece_count(BLACK, PAWN) == 1)
+ else if (pos.count<PAWN>(WHITE) == 1 && pos.count<PAWN>(BLACK) == 1)
{
// This is a special case because we set scaling functions
// for both colors instead of only one.
}
// No pawns makes it difficult to win, even with a material advantage
- if (pos.piece_count(WHITE, PAWN) == 0 && npm_w - npm_b <= BishopValueMg)
+ if (!pos.count<PAWN>(WHITE) && npm_w - npm_b <= BishopValueMg)
{
e->factor[WHITE] = (uint8_t)
- (npm_w == npm_b || npm_w < RookValueMg ? 0 : NoPawnsSF[std::min(pos.piece_count(WHITE, BISHOP), 2)]);
+ (npm_w == npm_b || npm_w < RookValueMg ? 0 : NoPawnsSF[std::min(pos.count<BISHOP>(WHITE), 2)]);
}
- if (pos.piece_count(BLACK, PAWN) == 0 && npm_b - npm_w <= BishopValueMg)
+ if (!pos.count<PAWN>(BLACK) && npm_b - npm_w <= BishopValueMg)
{
e->factor[BLACK] = (uint8_t)
- (npm_w == npm_b || npm_b < RookValueMg ? 0 : NoPawnsSF[std::min(pos.piece_count(BLACK, BISHOP), 2)]);
+ (npm_w == npm_b || npm_b < RookValueMg ? 0 : NoPawnsSF[std::min(pos.count<BISHOP>(BLACK), 2)]);
}
// Compute the space weight
if (npm_w + npm_b >= 2 * QueenValueMg + 4 * RookValueMg + 2 * KnightValueMg)
{
- int minorPieceCount = pos.piece_count(WHITE, KNIGHT) + pos.piece_count(WHITE, BISHOP)
- + pos.piece_count(BLACK, KNIGHT) + pos.piece_count(BLACK, BISHOP);
+ int minorPieceCount = pos.count<KNIGHT>(WHITE) + pos.count<BISHOP>(WHITE)
+ + pos.count<KNIGHT>(BLACK) + pos.count<BISHOP>(BLACK);
- e->spaceWeight = minorPieceCount * minorPieceCount;
+ e->spaceWeight = make_score(minorPieceCount * minorPieceCount, 0);
}
// Evaluate the material imbalance. We use PIECE_TYPE_NONE as a place holder
// for the bishop pair "extended piece", this allow us to be more flexible
// in defining bishop pair bonuses.
const int pieceCount[COLOR_NB][PIECE_TYPE_NB] = {
- { pos.piece_count(WHITE, BISHOP) > 1, pos.piece_count(WHITE, PAWN), pos.piece_count(WHITE, KNIGHT),
- pos.piece_count(WHITE, BISHOP) , pos.piece_count(WHITE, ROOK), pos.piece_count(WHITE, QUEEN) },
- { pos.piece_count(BLACK, BISHOP) > 1, pos.piece_count(BLACK, PAWN), pos.piece_count(BLACK, KNIGHT),
- pos.piece_count(BLACK, BISHOP) , pos.piece_count(BLACK, ROOK), pos.piece_count(BLACK, QUEEN) } };
+ { pos.count<BISHOP>(WHITE) > 1, pos.count<PAWN>(WHITE), pos.count<KNIGHT>(WHITE),
+ pos.count<BISHOP>(WHITE) , pos.count<ROOK>(WHITE), pos.count<QUEEN >(WHITE) },
+ { pos.count<BISHOP>(BLACK) > 1, pos.count<PAWN>(BLACK), pos.count<KNIGHT>(BLACK),
+ pos.count<BISHOP>(BLACK) , pos.count<ROOK>(BLACK), pos.count<QUEEN >(BLACK) } };
e->value = (int16_t)((imbalance<WHITE>(pieceCount) - imbalance<BLACK>(pieceCount)) / 16);
return e;