string sides[] = { code.substr(code.find('K', 1)), // Weaker
code.substr(0, code.find('K', 1)) }; // Stronger
string sides[] = { code.substr(code.find('K', 1)), // Weaker
code.substr(0, code.find('K', 1)) }; // Stronger
- transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
+ std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
assert(pos.piece_count(weakerSide, PAWN) == VALUE_ZERO);
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
assert(pos.piece_count(weakerSide, PAWN) == VALUE_ZERO);
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, KNIGHT) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 0);
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, KNIGHT) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 0);
- if (!probe_kpk_bitbase(wksq, wpsq, bksq, stm))
+ if (!Bitbases::probe_kpk(wksq, wpsq, bksq, stm))
assert(pos.piece_count(strongerSide, PAWN) == 0);
assert(pos.non_pawn_material(weakerSide) == 0);
assert(pos.piece_count(weakerSide, PAWN) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 0);
assert(pos.non_pawn_material(weakerSide) == 0);
assert(pos.piece_count(weakerSide, PAWN) == 1);
Value result;
// If the stronger side's king is in front of the pawn, it's a win
if (wksq < bpsq && file_of(wksq) == file_of(bpsq))
Value result;
// If the stronger side's king is in front of the pawn, it's a win
if (wksq < bpsq && file_of(wksq) == file_of(bpsq))
// If the weaker side's king is too far from the pawn and the rook,
// it's a win
else if ( square_distance(bksq, bpsq) - (tempo ^ 1) >= 3
&& square_distance(bksq, wrsq) >= 3)
// If the weaker side's king is too far from the pawn and the rook,
// it's a win
else if ( square_distance(bksq, bpsq) - (tempo ^ 1) >= 3
&& square_distance(bksq, wrsq) >= 3)
// If the pawn is far advanced and supported by the defending king,
// the position is drawish
// If the pawn is far advanced and supported by the defending king,
// the position is drawish
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, BISHOP) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, BISHOP) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide);
assert(pos.piece_count(weakerSide, PAWN) == 0);
Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide);
Value Endgame<KBBKN>::operator()(const Position& pos) const {
assert(pos.piece_count(strongerSide, BISHOP) == 2);
Value Endgame<KBBKN>::operator()(const Position& pos) const {
assert(pos.piece_count(strongerSide, BISHOP) == 2);
Square wksq = pos.king_square(strongerSide);
Square bksq = pos.king_square(weakerSide);
Square nsq = pos.piece_list(weakerSide, KNIGHT)[0];
Square wksq = pos.king_square(strongerSide);
Square bksq = pos.king_square(weakerSide);
Square nsq = pos.piece_list(weakerSide, KNIGHT)[0];
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) >= 1);
// No assertions about the material of weakerSide, because we want draws to
// be detected even when the weaker side has some pawns.
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) >= 1);
// No assertions about the material of weakerSide, because we want draws to
// be detected even when the weaker side has some pawns.
File pawnFile = file_of(pos.piece_list(strongerSide, PAWN)[0]);
// All pawns are on a single rook file ?
File pawnFile = file_of(pos.piece_list(strongerSide, PAWN)[0]);
// All pawns are on a single rook file ?
&& !(pawns & ~file_bb(pawnFile)))
{
Square bishopSq = pos.piece_list(strongerSide, BISHOP)[0];
&& !(pawns & ~file_bb(pawnFile)))
{
Square bishopSq = pos.piece_list(strongerSide, BISHOP)[0];
Square kingSq = pos.king_square(weakerSide);
if ( opposite_colors(queeningSq, bishopSq)
Square kingSq = pos.king_square(weakerSide);
if ( opposite_colors(queeningSq, bishopSq)
assert(pos.piece_count(strongerSide, QUEEN) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, ROOK) == 1);
assert(pos.piece_count(strongerSide, QUEEN) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, ROOK) == 1);
Square kingSq = pos.king_square(weakerSide);
if ( relative_rank(weakerSide, kingSq) <= RANK_2
&& relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4
Square kingSq = pos.king_square(weakerSide);
if ( relative_rank(weakerSide, kingSq) <= RANK_2
&& relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4
- && (pos.pieces(ROOK, weakerSide) & rank_bb(relative_rank(weakerSide, RANK_3)))
- && (pos.pieces(PAWN, weakerSide) & rank_bb(relative_rank(weakerSide, RANK_2)))
- && (pos.attacks_from<KING>(kingSq) & pos.pieces(PAWN, weakerSide)))
+ && (pos.pieces(weakerSide, ROOK) & rank_bb(relative_rank(weakerSide, RANK_3)))
+ && (pos.pieces(weakerSide, PAWN) & rank_bb(relative_rank(weakerSide, RANK_2)))
+ && (pos.attacks_from<KING>(kingSq) & pos.pieces(weakerSide, PAWN)))
assert(pos.piece_count(weakerSide, PAWN) == 0);
Square wksq = pos.king_square(strongerSide);
assert(pos.piece_count(weakerSide, PAWN) == 0);
Square wksq = pos.king_square(strongerSide);
int tempo = (pos.side_to_move() == strongerSide);
// If the pawn is not too far advanced and the defending king defends the
int tempo = (pos.side_to_move() == strongerSide);
// If the pawn is not too far advanced and the defending king defends the
assert(pos.piece_count(weakerSide, PAWN) == 1);
Square wpsq1 = pos.piece_list(strongerSide, PAWN)[0];
assert(pos.piece_count(weakerSide, PAWN) == 1);
Square wpsq1 = pos.piece_list(strongerSide, PAWN)[0];
assert(pos.piece_count(weakerSide, PAWN) == 0);
Square ksq = pos.king_square(weakerSide);
assert(pos.piece_count(weakerSide, PAWN) == 0);
Square ksq = pos.king_square(weakerSide);
// Are all pawns on the 'a' file?
if (!(pawns & ~FileABB))
{
// Does the defending king block the pawns?
if ( square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1
// Are all pawns on the 'a' file?
if (!(pawns & ~FileABB))
{
// Does the defending king block the pawns?
if ( square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1
- || ( file_of(ksq) == FILE_A
- && !in_front_bb(strongerSide, ksq) & pawns))
+ || ( file_of(ksq) == FILE_A
+ && !(in_front_bb(strongerSide, ksq) & pawns)))
{
// Does the defending king block the pawns?
if ( square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1
{
// Does the defending king block the pawns?
if ( square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1
- || ( file_of(ksq) == FILE_H
- && !in_front_bb(strongerSide, ksq) & pawns))
+ || ( file_of(ksq) == FILE_H
+ && !(in_front_bb(strongerSide, ksq) & pawns)))
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 1);
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 1);
assert(pos.piece_count(weakerSide, BISHOP) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, BISHOP) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 2);
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 2);
assert(pos.piece_count(weakerSide, BISHOP) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, BISHOP) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
if (relative_rank(strongerSide, psq1) > relative_rank(strongerSide, psq2))
{
blockSq1 = psq1 + pawn_push(strongerSide);
if (relative_rank(strongerSide, psq1) > relative_rank(strongerSide, psq2))
{
blockSq1 = psq1 + pawn_push(strongerSide);
|| abs(r1 - r2) >= 2))
return SCALE_FACTOR_DRAW;
else if ( ksq == blockSq2
&& opposite_colors(ksq, wbsq)
&& ( bbsq == blockSq1
|| abs(r1 - r2) >= 2))
return SCALE_FACTOR_DRAW;
else if ( ksq == blockSq2
&& opposite_colors(ksq, wbsq)
&& ( bbsq == blockSq1
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 1);
assert(pos.piece_count(strongerSide, BISHOP) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 1);
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.piece_count(strongerSide, KNIGHT) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 1);
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
assert(pos.piece_count(strongerSide, KNIGHT) == 1);
assert(pos.piece_count(strongerSide, PAWN) == 1);
assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
// Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw,
// it's probably at least a draw even with the pawn.
// Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw,
// it's probably at least a draw even with the pawn.
- return probe_kpk_bitbase(wksq, wpsq, bksq, stm) ? SCALE_FACTOR_NONE : SCALE_FACTOR_DRAW;
+ return Bitbases::probe_kpk(wksq, wpsq, bksq, stm) ? SCALE_FACTOR_NONE : SCALE_FACTOR_DRAW;