This patch is built on Tord idea to use functions instead of
templates to access position's bitboards. This has the added advantage
that we don't need fallback functions for cases where the piece
type or the color is a variable and not a constant.
Also added Joona suggestion to workaround request for two types
of pieces like bishop_and_queens() and rook_and_queens().
No functionality or performance change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
- assert(pos.pieces<PAWN>() == EmptyBoardBB);
+ assert(pos.pieces(PAWN) == EmptyBoardBB);
Value result = BishopValueEndgame;
Square wksq = pos.king_square(strongerSide);
Value result = BishopValueEndgame;
Square wksq = pos.king_square(strongerSide);
// No assertions about the material of weakerSide, because we want draws to
// be detected even when the weaker side has some pawns.
// No assertions about the material of weakerSide, because we want draws to
// be detected even when the weaker side has some pawns.
- Bitboard pawns = pos.pieces<PAWN>(strongerSide);
+ Bitboard pawns = pos.pieces(PAWN, strongerSide);
File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
// All pawns are on a single rook file ?
File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
// All pawns are on a single rook file ?
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) & relative_rank_bb(weakerSide, RANK_3))
- && (pos.pieces<PAWN>(weakerSide) & relative_rank_bb(weakerSide, RANK_2))
- && (pos.piece_attacks<KING>(kingSq) & pos.pieces<PAWN>(weakerSide)))
+ && (pos.pieces(ROOK, weakerSide) & relative_rank_bb(weakerSide, RANK_3))
+ && (pos.pieces(PAWN, weakerSide) & relative_rank_bb(weakerSide, RANK_2))
+ && (pos.piece_attacks<KING>(kingSq) & pos.pieces(PAWN, weakerSide)))
{
Square rsq = pos.piece_list(weakerSide, ROOK, 0);
{
Square rsq = pos.piece_list(weakerSide, ROOK, 0);
- if (pos.pawn_attacks(strongerSide, rsq) & pos.pieces<PAWN>(weakerSide))
+ if (pos.pawn_attacks(strongerSide, rsq) & pos.pieces(PAWN, weakerSide))
return ScaleFactor(0);
}
return SCALE_FACTOR_NONE;
return ScaleFactor(0);
}
return SCALE_FACTOR_NONE;
assert(pos.non_pawn_material(weakerSide) == Value(0));
assert(pos.piece_count(weakerSide, PAWN) == 0);
assert(pos.non_pawn_material(weakerSide) == Value(0));
assert(pos.piece_count(weakerSide, PAWN) == 0);
- Bitboard pawns = pos.pieces<PAWN>(strongerSide);
+ Bitboard pawns = pos.pieces(PAWN, strongerSide);
// Are all pawns on the 'a' file?
if ((pawns & ~FileABB) == EmptyBoardBB)
// Are all pawns on the 'a' file?
if ((pawns & ~FileABB) == EmptyBoardBB)
else
{
Bitboard ray = ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S);
else
{
Bitboard ray = ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S);
- if (ray & pos.pieces<KING>(weakerSide))
+ if (ray & pos.pieces(KING, weakerSide))
return ScaleFactor(0);
if( (pos.piece_attacks<BISHOP>(weakerBishopSq) & ray)
&& square_distance(weakerBishopSq, pawnSq) >= 3)
return ScaleFactor(0);
if( (pos.piece_attacks<BISHOP>(weakerBishopSq) & ray)
&& square_distance(weakerBishopSq, pawnSq) >= 3)
if ( ksq == blockSq1
&& square_color(ksq) != square_color(wbsq)
&& ( bbsq == blockSq2
if ( ksq == blockSq1
&& square_color(ksq) != square_color(wbsq)
&& ( bbsq == blockSq2
- || (pos.piece_attacks<BISHOP>(blockSq2) & pos.pieces<BISHOP>(weakerSide))
+ || (pos.piece_attacks<BISHOP>(blockSq2) & pos.pieces(BISHOP, weakerSide))
|| rank_distance(r1, r2) >= 2))
return ScaleFactor(0);
else if ( ksq == blockSq2
&& square_color(ksq) != square_color(wbsq)
&& ( bbsq == blockSq1
|| rank_distance(r1, r2) >= 2))
return ScaleFactor(0);
else if ( ksq == blockSq2
&& square_color(ksq) != square_color(wbsq)
&& ( bbsq == blockSq1
- || (pos.piece_attacks<BISHOP>(blockSq1) & pos.pieces<BISHOP>(weakerSide))))
+ || (pos.piece_attacks<BISHOP>(blockSq1) & pos.pieces(BISHOP, weakerSide))))
return ScaleFactor(0);
else
return SCALE_FACTOR_NONE;
return ScaleFactor(0);
else
return SCALE_FACTOR_NONE;
ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8);
// Initialize pawn attack bitboards for both sides
ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8);
// Initialize pawn attack bitboards for both sides
- ei.attackedBy[WHITE][PAWN] = ((pos.pieces<PAWN>(WHITE) << 9) & ~FileABB) | ((pos.pieces<PAWN>(WHITE) << 7) & ~FileHBB);
- ei.attackedBy[BLACK][PAWN] = ((pos.pieces<PAWN>(BLACK) >> 7) & ~FileABB) | ((pos.pieces<PAWN>(BLACK) >> 9) & ~FileHBB);
+ ei.attackedBy[WHITE][PAWN] = ((pos.pieces(PAWN, WHITE) << 9) & ~FileABB) | ((pos.pieces(PAWN, WHITE) << 7) & ~FileHBB);
+ ei.attackedBy[BLACK][PAWN] = ((pos.pieces(PAWN, BLACK) >> 7) & ~FileABB) | ((pos.pieces(PAWN, BLACK) >> 9) & ~FileHBB);
Bitboard b1 = ei.attackedBy[WHITE][PAWN] & ei.attackedBy[BLACK][KING];
Bitboard b2 = ei.attackedBy[BLACK][PAWN] & ei.attackedBy[WHITE][KING];
if (b1)
Bitboard b1 = ei.attackedBy[WHITE][PAWN] & ei.attackedBy[BLACK][KING];
Bitboard b2 = ei.attackedBy[BLACK][PAWN] & ei.attackedBy[WHITE][KING];
if (b1)
// Increase bonus if supported by pawn, especially if the opponent has
// no minor piece which can exchange the outpost piece
// Increase bonus if supported by pawn, especially if the opponent has
// no minor piece which can exchange the outpost piece
- if (bonus && (p.pawn_attacks(them, s) & p.pieces<PAWN>(us)))
+ if (bonus && (p.pawn_attacks(them, s) & p.pieces(PAWN, us)))
- if ( p.pieces<KNIGHT>(them) == EmptyBoardBB
- && (SquaresByColorBB[square_color(s)] & p.pieces<BISHOP>(them)) == EmptyBoardBB)
+ if ( p.pieces(KNIGHT, them) == EmptyBoardBB
+ && (SquaresByColorBB[square_color(s)] & p.pieces(BISHOP, them)) == EmptyBoardBB)
bonus += bonus + bonus / 2;
else
bonus += bonus / 2;
bonus += bonus + bonus / 2;
else
bonus += bonus / 2;
if (Piece == KNIGHT || Piece == QUEEN)
b = pos.piece_attacks<Piece>(s);
else if (Piece == BISHOP)
if (Piece == KNIGHT || Piece == QUEEN)
b = pos.piece_attacks<Piece>(s);
else if (Piece == BISHOP)
- b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces<QUEEN>(us));
+ b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, us));
- b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces<ROOK_AND_QUEEN>(us));
+ b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, us));
from = p.piece_list(them, QUEEN, i);
if ( bit_is_set(p.piece_attacks<QUEEN>(from), to)
&& !bit_is_set(p.pinned_pieces(them), from)
from = p.piece_list(them, QUEEN, i);
if ( bit_is_set(p.piece_attacks<QUEEN>(from), to)
&& !bit_is_set(p.pinned_pieces(them), from)
- && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces<ROOK_AND_QUEEN>(us))
- && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces<BISHOP_AND_QUEEN>(us)))
+ && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces(ROOK, QUEEN, us))
+ && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces(BISHOP, QUEEN, us)))
ei.mateThreat[them] = make_move(from, to);
}
ei.mateThreat[them] = make_move(from, to);
}
// adding pawns later).
if (DiscoveredCheckBonus)
{
// adding pawns later).
if (DiscoveredCheckBonus)
{
- b = p.discovered_check_candidates(them) & ~p.pieces<PAWN>();
+ b = p.discovered_check_candidates(them) & ~p.pieces(PAWN);
if (b)
attackUnits += DiscoveredCheckBonus * count_1s_max_15<HasPopCnt>(b) * (sente? 2 : 1);
}
if (b)
attackUnits += DiscoveredCheckBonus * count_1s_max_15<HasPopCnt>(b) * (sente? 2 : 1);
}
Color them = opposite_color(us);
Square ourKingSq = pos.king_square(us);
Square theirKingSq = pos.king_square(them);
Color them = opposite_color(us);
Square ourKingSq = pos.king_square(us);
Square theirKingSq = pos.king_square(them);
- Bitboard b = ei.pi->passed_pawns() & pos.pieces<PAWN>(us), b2, b3, b4;
+ Bitboard b = ei.pi->passed_pawns() & pos.pieces(PAWN, us), b2, b3, b4;
// If there is an enemy rook or queen attacking the pawn from behind,
// add all X-ray attacks by the rook or queen.
if ( bit_is_set(ei.attacked_by(them,ROOK) | ei.attacked_by(them,QUEEN),s)
// If there is an enemy rook or queen attacking the pawn from behind,
// add all X-ray attacks by the rook or queen.
if ( bit_is_set(ei.attacked_by(them,ROOK) | ei.attacked_by(them,QUEEN),s)
- && (squares_behind(us, s) & pos.pieces<ROOK_AND_QUEEN>(them)))
+ && (squares_behind(us, s) & pos.pieces(ROOK, QUEEN, them)))
b3 = b2;
// Squares attacked or occupied by enemy pieces
b3 |= (b2 & pos.pieces_of_color(them));
// There are no enemy pawns in the pawn's path
b3 = b2;
// Squares attacked or occupied by enemy pieces
b3 |= (b2 & pos.pieces_of_color(them));
// There are no enemy pawns in the pawn's path
- assert((b2 & pos.pieces<PAWN>(them)) == EmptyBoardBB);
+ assert((b2 & pos.pieces(PAWN, them)) == EmptyBoardBB);
// Are any of the squares in the pawn's path attacked or occupied by the enemy?
if (b3 == EmptyBoardBB)
// Are any of the squares in the pawn's path attacked or occupied by the enemy?
if (b3 == EmptyBoardBB)
}
// If the pawn is supported by a friendly pawn, increase bonus
}
// If the pawn is supported by a friendly pawn, increase bonus
- b2 = pos.pieces<PAWN>(us) & neighboring_files_bb(s);
+ b2 = pos.pieces(PAWN, us) & neighboring_files_bb(s);
if (b2 & rank_bb(s))
ebonus += Value(r * 20);
else if (pos.pawn_attacks(them, s) & b2)
if (b2 & rank_bb(s))
ebonus += Value(r * 20);
else if (pos.pawn_attacks(them, s) & b2)
if ( pos.non_pawn_material(them) <= KnightValueMidgame
&& pos.piece_count(them, KNIGHT) <= 1)
ebonus += ebonus / 4;
if ( pos.non_pawn_material(them) <= KnightValueMidgame
&& pos.piece_count(them, KNIGHT) <= 1)
ebonus += ebonus / 4;
- else if (pos.pieces<ROOK_AND_QUEEN>(them))
+ else if (pos.pieces(ROOK, QUEEN, them))
// pawn, or if it is undefended and attacked by an enemy piece.
Bitboard safeSquares = SpaceMask[us]
// pawn, or if it is undefended and attacked by an enemy piece.
Bitboard safeSquares = SpaceMask[us]
- & ~pos.pieces<PAWN>(us)
+ & ~pos.pieces(PAWN, us)
& ~ei.attacked_by(them, PAWN)
& ~(~ei.attacked_by(us) & ei.attacked_by(them));
// Find all squares which are at most three squares behind some friendly
// pawn.
& ~ei.attacked_by(them, PAWN)
& ~(~ei.attacked_by(us) & ei.attacked_by(them));
// Find all squares which are at most three squares behind some friendly
// pawn.
- Bitboard behindFriendlyPawns = pos.pieces<PAWN>(us);
+ Bitboard behindFriendlyPawns = pos.pieces(PAWN, us);
if (us == WHITE)
{
behindFriendlyPawns |= (behindFriendlyPawns >> 8);
if (us == WHITE)
{
behindFriendlyPawns |= (behindFriendlyPawns >> 8);
mi->evaluationFunction = &EvaluateKKX;
return mi;
}
mi->evaluationFunction = &EvaluateKKX;
return mi;
}
- else if ( pos.pieces<PAWN>() == EmptyBoardBB
- && pos.pieces<ROOK>() == EmptyBoardBB
- && pos.pieces<QUEEN>() == EmptyBoardBB)
+ else if ( pos.pieces(PAWN) == EmptyBoardBB
+ && pos.pieces(ROOK) == EmptyBoardBB
+ && pos.pieces(QUEEN) == EmptyBoardBB)
{
// Minor piece endgame with at least one minor piece per side and
// no pawns. Note that the case KmmK is already handled by KXK.
{
// Minor piece endgame with at least one minor piece per side and
// no pawns. Note that the case KmmK is already handled by KXK.
- assert((pos.pieces<KNIGHT>(WHITE) | pos.pieces<BISHOP>(WHITE)));
- assert((pos.pieces<KNIGHT>(BLACK) | pos.pieces<BISHOP>(BLACK)));
+ assert((pos.pieces(KNIGHT, WHITE) | pos.pieces(BISHOP, WHITE)));
+ assert((pos.pieces(KNIGHT, BLACK) | pos.pieces(BISHOP, BLACK)));
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.piece_count(WHITE, BISHOP) + pos.piece_count(WHITE, KNIGHT) <= 2
&& pos.piece_count(BLACK, BISHOP) + pos.piece_count(BLACK, KNIGHT) <= 2)
// and to be able to use square_is_attacked().
Bitboard checkers = pos.checkers();
Bitboard checkersAttacks = EmptyBoardBB;
// and to be able to use square_is_attacked().
Bitboard checkers = pos.checkers();
Bitboard checkersAttacks = EmptyBoardBB;
- Bitboard b = checkers & pos.pieces<BISHOP_AND_QUEEN>();
+ Bitboard b = checkers & pos.pieces(BISHOP, QUEEN);
while (b)
{
from = pop_1st_bit(&b);
checkersAttacks |= bishop_attacks_bb(from, b_noKing);
}
while (b)
{
from = pop_1st_bit(&b);
checkersAttacks |= bishop_attacks_bb(from, b_noKing);
}
- b = checkers & pos.pieces<ROOK_AND_QUEEN>();
+ b = checkers & pos.pieces(ROOK, QUEEN);
while (b)
{
from = pop_1st_bit(&b);
while (b)
{
from = pop_1st_bit(&b);
// Generate captures of the checking piece
// Pawn captures
// Generate captures of the checking piece
// Pawn captures
- b1 = pos.pawn_attacks(them, checksq) & pos.pieces<PAWN>(us) & ~pinned;
+ b1 = pos.pawn_attacks(them, checksq) & pos.pieces(PAWN, us) & ~pinned;
while (b1)
{
from = pop_1st_bit(&b1);
while (b1)
{
from = pop_1st_bit(&b1);
- b1 = ( (pos.piece_attacks<KNIGHT>(checksq) & pos.pieces<KNIGHT>(us))
- | (pos.piece_attacks<BISHOP>(checksq) & pos.pieces<BISHOP_AND_QUEEN>(us))
- | (pos.piece_attacks<ROOK>(checksq) & pos.pieces<ROOK_AND_QUEEN>(us)) ) & ~pinned;
+ b1 = ( (pos.piece_attacks<KNIGHT>(checksq) & pos.pieces(KNIGHT, us))
+ | (pos.piece_attacks<BISHOP>(checksq) & pos.pieces(BISHOP, QUEEN, us))
+ | (pos.piece_attacks<ROOK>(checksq) & pos.pieces(ROOK, QUEEN, us)) ) & ~pinned;
// Blocking check evasions are possible only if the checking piece is
// a slider.
// Blocking check evasions are possible only if the checking piece is
// a slider.
- if (checkers & (pos.pieces<BISHOP>() | pos.pieces<ROOK>() | pos.pieces<QUEEN>()))
+ if (checkers & (pos.pieces(BISHOP) | pos.pieces(ROOK) | pos.pieces(QUEEN)))
{
Bitboard blockSquares = squares_between(checksq, ksq);
{
Bitboard blockSquares = squares_between(checksq, ksq);
// check. If pos.ep_square() is set, the last move made must have been
// a double pawn push. If, furthermore, the checking piece is a pawn,
// an en passant check evasion may be possible.
// check. If pos.ep_square() is set, the last move made must have been
// a double pawn push. If, furthermore, the checking piece is a pawn,
// an en passant check evasion may be possible.
- if (pos.ep_square() != SQ_NONE && (checkers & pos.pieces<PAWN>(them)))
+ if (pos.ep_square() != SQ_NONE && (checkers & pos.pieces(PAWN, them)))
- b1 = pos.pawn_attacks(them, to) & pos.pieces<PAWN>(us);
+ b1 = pos.pawn_attacks(them, to) & pos.pieces(PAWN, us);
// The checking pawn cannot be a discovered (bishop) check candidate
// otherwise we were in check also before last double push move.
// The checking pawn cannot be a discovered (bishop) check candidate
// otherwise we were in check also before last double push move.
const SquareDelta TDELTA_N = (Us == WHITE ? DELTA_N : DELTA_S);
Square to;
const SquareDelta TDELTA_N = (Us == WHITE ? DELTA_N : DELTA_S);
Square to;
- Bitboard pawns = pos.pieces<PAWN>(Us);
+ Bitboard pawns = pos.pieces(PAWN, Us);
Bitboard enemyPieces = pos.pieces_of_color(opposite_color(Us));
bool possiblePromotion = (pawns & TRank7BB);
Bitboard enemyPieces = pos.pieces_of_color(opposite_color(Us));
bool possiblePromotion = (pawns & TRank7BB);
Bitboard b1, b2;
Square to;
Bitboard b1, b2;
Square to;
- Bitboard pawns = pos.pieces<PAWN>(Us);
+ Bitboard pawns = pos.pieces(PAWN, Us);
Bitboard emptySquares = pos.empty_squares();
if (pawns & TRank7BB) // There is some promotion candidate ?
Bitboard emptySquares = pos.empty_squares();
if (pawns & TRank7BB) // There is some promotion candidate ?
Square to;
Bitboard b1, b2, b3;
Square to;
Bitboard b1, b2, b3;
- Bitboard pawns = pos.pieces<PAWN>(Us);
+ Bitboard pawns = pos.pieces(PAWN, Us);
MoveStack* generate_piece_checks(const Position& pos, MoveStack* mlist, Color us,
Bitboard dc, Square ksq) {
MoveStack* generate_piece_checks(const Position& pos, MoveStack* mlist, Color us,
Bitboard dc, Square ksq) {
- Bitboard target = pos.pieces<Piece>(us);
+ Bitboard target = pos.pieces(Piece, us);
// Discovered checks
Bitboard b = target & dc;
// Discovered checks
Bitboard b = target & dc;
Square to;
// Find non-pinned pawns and push them one square
Square to;
// Find non-pinned pawns and push them one square
- Bitboard b1 = move_pawns<Us, DELTA_N>(pos.pieces<PAWN>(Us) & ~pinned);
+ Bitboard b1 = move_pawns<Us, DELTA_N>(pos.pieces(PAWN, Us) & ~pinned);
// We don't have to AND with empty squares here,
// because the blocking squares will always be empty.
// We don't have to AND with empty squares here,
// because the blocking squares will always be empty.
for (Color us = WHITE; us <= BLACK; us++)
{
Color them = opposite_color(us);
for (Color us = WHITE; us <= BLACK; us++)
{
Color them = opposite_color(us);
- Bitboard ourPawns = pos.pieces<PAWN>(us);
- Bitboard theirPawns = pos.pieces<PAWN>(them);
+ Bitboard ourPawns = pos.pieces(PAWN, us);
+ Bitboard theirPawns = pos.pieces(PAWN, them);
Bitboard pawns = ourPawns;
// Initialize pawn storm scores by giving bonuses for open files
Bitboard pawns = ourPawns;
// Initialize pawn storm scores by giving bonuses for open files
int PawnInfo::updateShelter(const Position& pos, Color c, Square ksq) {
unsigned shelter = 0;
int PawnInfo::updateShelter(const Position& pos, Color c, Square ksq) {
unsigned shelter = 0;
- Bitboard pawns = pos.pieces<PAWN>(c) & this_and_neighboring_files_bb(ksq);
+ Bitboard pawns = pos.pieces(PAWN, c) & this_and_neighboring_files_bb(ksq);
unsigned r = ksq & (7 << 3);
for (int i = 1, k = (c ? -8 : 8); i < 4; i++)
{
unsigned r = ksq & (7 << 3);
for (int i = 1, k = (c ? -8 : 8); i < 4; i++)
{
enum PieceType {
NO_PIECE_TYPE = 0,
enum PieceType {
NO_PIECE_TYPE = 0,
- PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6,
- BISHOP_AND_QUEEN = 8, ROOK_AND_QUEEN = 9
+ PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6
// Pinners are sliders, not checkers, that give check when
// candidate pinned is removed.
// Pinners are sliders, not checkers, that give check when
// candidate pinned is removed.
- pinners = (pieces<ROOK_AND_QUEEN>(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq])
- | (pieces<BISHOP_AND_QUEEN>(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]);
+ pinners = (pieces(ROOK, QUEEN, FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq])
+ | (pieces(BISHOP, QUEEN, FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]);
if (FindPinned && pinners)
pinners &= ~st->checkersBB;
if (FindPinned && pinners)
pinners &= ~st->checkersBB;
Bitboard Position::attacks_to(Square s) const {
Bitboard Position::attacks_to(Square s) const {
- return (pawn_attacks(BLACK, s) & pieces<PAWN>(WHITE))
- | (pawn_attacks(WHITE, s) & pieces<PAWN>(BLACK))
- | (piece_attacks<KNIGHT>(s) & pieces<KNIGHT>())
- | (piece_attacks<ROOK>(s) & pieces<ROOK_AND_QUEEN>())
- | (piece_attacks<BISHOP>(s) & pieces<BISHOP_AND_QUEEN>())
- | (piece_attacks<KING>(s) & pieces<KING>());
+ return (pawn_attacks(BLACK, s) & pieces(PAWN, WHITE))
+ | (pawn_attacks(WHITE, s) & pieces(PAWN, BLACK))
+ | (piece_attacks<KNIGHT>(s) & pieces(KNIGHT))
+ | (piece_attacks<ROOK>(s) & pieces(ROOK, QUEEN))
+ | (piece_attacks<BISHOP>(s) & pieces(BISHOP, QUEEN))
+ | (piece_attacks<KING>(s) & pieces(KING));
}
/// Position::piece_attacks_square() tests whether the piece on square f
}
/// Position::piece_attacks_square() tests whether the piece on square f
Color us = color_of_piece_on(f);
clear_bit(&occ, f);
set_bit(&occ, t);
Color us = color_of_piece_on(f);
clear_bit(&occ, f);
set_bit(&occ, t);
- Bitboard xray = ( (rook_attacks_bb(s, occ) & pieces<ROOK_AND_QUEEN>())
- |(bishop_attacks_bb(s, occ) & pieces<BISHOP_AND_QUEEN>())) & pieces_of_color(us);
+ Bitboard xray = ( (rook_attacks_bb(s, occ) & pieces(ROOK, QUEEN))
+ |(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN))) & pieces_of_color(us);
// If we have attacks we need to verify that are caused by our move
// and are not already existent ones.
// If we have attacks we need to verify that are caused by our move
// and are not already existent ones.
clear_bit(&b, capsq);
set_bit(&b, to);
clear_bit(&b, capsq);
set_bit(&b, to);
- return !(rook_attacks_bb(ksq, b) & pieces<ROOK_AND_QUEEN>(them))
- && !(bishop_attacks_bb(ksq, b) & pieces<BISHOP_AND_QUEEN>(them));
+ return !(rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, them))
+ && !(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, them));
}
// If the moving piece is a king, check whether the destination
}
// If the moving piece is a king, check whether the destination
clear_bit(&b, from);
clear_bit(&b, capsq);
set_bit(&b, to);
clear_bit(&b, from);
clear_bit(&b, capsq);
set_bit(&b, to);
- return (rook_attacks_bb(ksq, b) & pieces<ROOK_AND_QUEEN>(us))
- ||(bishop_attacks_bb(ksq, b) & pieces<BISHOP_AND_QUEEN>(us));
+ return (rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us))
+ ||(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, us));
if (Piece != QUEEN && bit_is_set(dcCandidates, from))
{
if (Piece != ROOK)
if (Piece != QUEEN && bit_is_set(dcCandidates, from))
{
if (Piece != ROOK)
- (*pCheckersBB) |= (piece_attacks<ROOK>(ksq) & pieces<ROOK_AND_QUEEN>(side_to_move()));
+ (*pCheckersBB) |= (piece_attacks<ROOK>(ksq) & pieces(ROOK, QUEEN, side_to_move()));
- (*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & pieces<BISHOP_AND_QUEEN>(side_to_move()));
+ (*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & pieces(BISHOP, QUEEN, side_to_move()));
// Set en passant square, only if moved pawn can be captured
if (abs(int(to) - int(from)) == 16)
{
// Set en passant square, only if moved pawn can be captured
if (abs(int(to) - int(from)) == 16)
{
- if (pawn_attacks(us, from + (us == WHITE ? DELTA_N : DELTA_S)) & pieces<PAWN>(them))
+ if (pawn_attacks(us, from + (us == WHITE ? DELTA_N : DELTA_S)) & pieces(PAWN, them))
{
st->epSquare = Square((int(from) + int(to)) / 2);
key ^= zobEp[st->epSquare];
{
st->epSquare = Square((int(from) + int(to)) / 2);
key ^= zobEp[st->epSquare];
while (true)
{
clear_bit(&occ, from);
while (true)
{
clear_bit(&occ, from);
- attackers = (rook_attacks_bb(to, occ) & pieces<ROOK_AND_QUEEN>())
- | (bishop_attacks_bb(to, occ) & pieces<BISHOP_AND_QUEEN>())
- | (piece_attacks<KNIGHT>(to) & pieces<KNIGHT>())
- | (piece_attacks<KING>(to) & pieces<KING>())
- | (pawn_attacks(WHITE, to) & pieces<PAWN>(BLACK))
- | (pawn_attacks(BLACK, to) & pieces<PAWN>(WHITE));
+ attackers = (rook_attacks_bb(to, occ) & pieces(ROOK, QUEEN))
+ | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN))
+ | (piece_attacks<KNIGHT>(to) & pieces(KNIGHT))
+ | (piece_attacks<KING>(to) & pieces(KING))
+ | (pawn_attacks(WHITE, to) & pieces(PAWN, BLACK))
+ | (pawn_attacks(BLACK, to) & pieces(PAWN, WHITE));
if (from != SQ_NONE)
break;
if (from != SQ_NONE)
break;
// and use it to initialize from square.
stmAttackers = attackers & pieces_of_color(us);
PieceType pt;
// and use it to initialize from square.
stmAttackers = attackers & pieces_of_color(us);
PieceType pt;
- for (pt = PAWN; !(stmAttackers & pieces_of_type(pt)); pt++)
+ for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
- from = first_1(stmAttackers & pieces_of_type(pt));
+ from = first_1(stmAttackers & pieces(pt));
piece = piece_on(from);
}
piece = piece_on(from);
}
// Locate the least valuable attacker for the side to move. The loop
// below looks like it is potentially infinite, but it isn't. We know
// that the side to move still has at least one attacker left.
// Locate the least valuable attacker for the side to move. The loop
// below looks like it is potentially infinite, but it isn't. We know
// that the side to move still has at least one attacker left.
- for (pt = PAWN; !(stmAttackers & pieces_of_type(pt)); pt++)
+ for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
assert(pt < KING);
// Remove the attacker we just found from the 'attackers' bitboard,
// and scan for new X-ray attacks behind the attacker.
assert(pt < KING);
// Remove the attacker we just found from the 'attackers' bitboard,
// and scan for new X-ray attacks behind the attacker.
- b = stmAttackers & pieces_of_type(pt);
+ b = stmAttackers & pieces(pt);
- attackers |= (rook_attacks_bb(to, occ) & pieces<ROOK_AND_QUEEN>())
- | (bishop_attacks_bb(to, occ) & pieces<BISHOP_AND_QUEEN>());
+ attackers |= (rook_attacks_bb(to, occ) & pieces(ROOK, QUEEN))
+ | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN));
for (Color c = WHITE; c <= BLACK; c++)
{
for (Color c = WHITE; c <= BLACK; c++)
{
while(b)
{
s = pop_1st_bit(&b);
while(b)
{
s = pop_1st_bit(&b);
for (Color c = WHITE; c <= BLACK; c++)
for (PieceType pt = PAWN; pt <= KING; pt++)
{
for (Color c = WHITE; c <= BLACK; c++)
for (PieceType pt = PAWN; pt <= KING; pt++)
{
- b = pieces_of_color(c) & pieces_of_type(pt);
while(b)
{
s = pop_1st_bit(&b);
while(b)
{
s = pop_1st_bit(&b);
for (PieceType pt = KNIGHT; pt <= QUEEN; pt++)
{
for (PieceType pt = KNIGHT; pt <= QUEEN; pt++)
{
- Bitboard b = pieces_of_color(c) & pieces_of_type(pt);
+ Bitboard b = pieces(pt, c);
while (b)
{
assert(piece_on(first_1(b)) == piece_of_color_and_type(c, pt));
while (b)
{
assert(piece_on(first_1(b)) == piece_of_color_and_type(c, pt));
bool Position::is_draw() const {
// Draw by material?
bool Position::is_draw() const {
// Draw by material?
&& (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMidgame))
return true;
&& (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMidgame))
return true;
// Separate piece type bitboards must have empty intersections
for (PieceType p1 = PAWN; p1 <= KING; p1++)
for (PieceType p2 = PAWN; p2 <= KING; p2++)
// Separate piece type bitboards must have empty intersections
for (PieceType p1 = PAWN; p1 <= KING; p1++)
for (PieceType p2 = PAWN; p2 <= KING; p2++)
- if (p1 != p2 && (pieces_of_type(p1) & pieces_of_type(p2)))
+ if (p1 != p2 && (pieces(p1) & pieces(p2)))
if (debugPieceCounts)
for (Color c = WHITE; c <= BLACK; c++)
for (PieceType pt = PAWN; pt <= KING; pt++)
if (debugPieceCounts)
for (Color c = WHITE; c <= BLACK; c++)
for (PieceType pt = PAWN; pt <= KING; pt++)
- if (pieceCount[c][pt] != count_1s(pieces_of_color(c) & pieces_of_type(pt)))
+ if (pieceCount[c][pt] != count_1s(pieces(pt, c)))
return false;
if (failedStep) (*failedStep)++;
return false;
if (failedStep) (*failedStep)++;
for(PieceType pt = PAWN; pt <= KING; pt++)
for(int i = 0; i < pieceCount[c][pt]; i++)
{
for(PieceType pt = PAWN; pt <= KING; pt++)
for(int i = 0; i < pieceCount[c][pt]; i++)
{
- if (piece_on(piece_list(c, pt, i)) != (pieces_of_color(c) & pieces_of_type(pt)))
+ if (piece_on(piece_list(c, pt, i)) != (pieces(pt, c)))
return false;
if (index[piece_list(c, pt, i)] != i)
return false;
if (index[piece_list(c, pt, i)] != i)
Bitboard empty_squares() const;
Bitboard occupied_squares() const;
Bitboard pieces_of_color(Color c) const;
Bitboard empty_squares() const;
Bitboard occupied_squares() const;
Bitboard pieces_of_color(Color c) const;
- Bitboard pieces_of_type(PieceType pt) const;
-
- // Pieces by constant type of both colors
- template<PieceType Piece> Bitboard pieces() const { return byTypeBB[Piece]; }
- template<> Bitboard pieces<BISHOP_AND_QUEEN>() const { return byTypeBB[BISHOP] | byTypeBB[QUEEN]; }
- template<> Bitboard pieces<ROOK_AND_QUEEN>() const { return byTypeBB[ROOK] | byTypeBB[QUEEN]; }
-
- // Pieces by constant type of a given color
- template<PieceType Piece> Bitboard pieces(Color c) const { return byColorBB[c] & pieces<Piece>(); }
+ Bitboard pieces(PieceType pt) const;
+ Bitboard pieces(PieceType pt, Color c) const;
+ Bitboard pieces(PieceType pt1, PieceType pt2) const;
+ Bitboard pieces(PieceType pt1, PieceType pt2, Color c) const;
// Number of pieces of each color and type
int piece_count(Color c, PieceType pt) const;
// Number of pieces of each color and type
int piece_count(Color c, PieceType pt) const;
-inline Bitboard Position::pieces_of_type(PieceType pt) const {
+inline Bitboard Position::pieces(PieceType pt) const {
+inline Bitboard Position::pieces(PieceType pt, Color c) const {
+ return byTypeBB[pt] & byColorBB[c];
+}
+
+inline Bitboard Position::pieces(PieceType pt1, PieceType pt2) const {
+ return byTypeBB[pt1] | byTypeBB[pt2];
+}
+
+inline Bitboard Position::pieces(PieceType pt1, PieceType pt2, Color c) const {
+ return (byTypeBB[pt1] | byTypeBB[pt2]) & byColorBB[c];
+}
+
inline int Position::piece_count(Color c, PieceType pt) const {
return pieceCount[c][pt];
}
inline int Position::piece_count(Color c, PieceType pt) const {
return pieceCount[c][pt];
}
}
inline bool Position::pawn_is_passed(Color c, Square s) const {
}
inline bool Position::pawn_is_passed(Color c, Square s) const {
- return !(pieces<PAWN>(opposite_color(c)) & passed_pawn_mask(c, s));
+ return !(pieces(PAWN, opposite_color(c)) & passed_pawn_mask(c, s));
}
inline bool Position::pawn_is_passed(Bitboard theirPawns, Color c, Square s) {
}
inline bool Position::pawn_is_passed(Bitboard theirPawns, Color c, Square s) {
}
inline bool Position::square_is_weak(Square s, Color c) const {
}
inline bool Position::square_is_weak(Square s, Color c) const {
- return !(pieces<PAWN>(c) & outpost_mask(opposite_color(c), s));
+ return !(pieces(PAWN, c) & outpost_mask(opposite_color(c), s));
}
inline Key Position::get_key() const {
}
inline Key Position::get_key() const {
inline bool Position::has_pawn_on_7th(Color c) const {
inline bool Position::has_pawn_on_7th(Color c) const {
- return pieces<PAWN>(c) & relative_rank_bb(c, RANK_7);
+ return pieces(PAWN, c) & relative_rank_bb(c, RANK_7);
}
inline bool Position::move_is_capture(Move m) const {
}
inline bool Position::move_is_capture(Move m) const {