1
0
Fork 0

Second take at unifying bitboard representation access

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>
sf_2.3.1_base
Marco Costalba 2009-09-02 11:57:38 +02:00
parent 76bed11f7b
commit 9f28d8a854
8 changed files with 106 additions and 100 deletions

View File

@ -329,7 +329,7 @@ Value EvaluationFunction<KBBKN>::apply(const Position& pos) {
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);
@ -376,7 +376,7 @@ ScaleFactor ScalingFunction<KBPsK>::apply(const Position& pos) {
// 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 ?
@ -432,12 +432,12 @@ ScaleFactor ScalingFunction<KQKRPs>::apply(const Position& pos) {
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);
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;
@ -616,7 +616,7 @@ ScaleFactor ScalingFunction<KPsK>::apply(const Position &pos) {
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)
@ -694,7 +694,7 @@ ScaleFactor ScalingFunction<KBPKB>::apply(const Position &pos) {
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)
@ -761,13 +761,13 @@ ScaleFactor ScalingFunction<KBPPKB>::apply(const Position& pos) {
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
|| (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;

View File

@ -348,8 +348,8 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) {
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)
@ -590,10 +590,10 @@ namespace {
// 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;
@ -622,9 +622,9 @@ namespace {
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));
else if (Piece == ROOK)
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));
else
assert(false);
@ -787,8 +787,8 @@ namespace {
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);
}
@ -841,7 +841,7 @@ namespace {
// 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);
}
@ -889,7 +889,7 @@ namespace {
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;
while (b)
{
@ -923,14 +923,14 @@ namespace {
// 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
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)
@ -951,7 +951,7 @@ namespace {
}
// 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)
@ -993,7 +993,7 @@ namespace {
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))
ebonus -= ebonus / 4;
}
@ -1115,13 +1115,13 @@ namespace {
// 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.
Bitboard behindFriendlyPawns = pos.pieces<PAWN>(us);
Bitboard behindFriendlyPawns = pos.pieces(PAWN, us);
if (us == WHITE)
{
behindFriendlyPawns |= (behindFriendlyPawns >> 8);

View File

@ -171,14 +171,14 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
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.
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)

View File

@ -238,14 +238,14 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
// 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);
}
b = checkers & pos.pieces<ROOK_AND_QUEEN>();
b = checkers & pos.pieces(ROOK, QUEEN);
while (b)
{
from = pop_1st_bit(&b);
@ -275,7 +275,7 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
// 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);
@ -290,9 +290,9 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
}
// Pieces captures
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;
while (b1)
{
@ -302,7 +302,7 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
// 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);
@ -323,10 +323,10 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
// 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)))
{
to = pos.ep_square();
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.
@ -675,7 +675,7 @@ namespace {
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);
@ -725,7 +725,7 @@ namespace {
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 ?
@ -786,7 +786,7 @@ namespace {
Square to;
Bitboard b1, b2, b3;
Bitboard pawns = pos.pieces<PAWN>(Us);
Bitboard pawns = pos.pieces(PAWN, Us);
if (dc & pawns)
{
@ -832,7 +832,7 @@ namespace {
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;
@ -881,7 +881,7 @@ namespace {
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.

View File

@ -197,8 +197,8 @@ PawnInfo* PawnInfoTable::get_pawn_info(const Position& pos) {
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
@ -392,7 +392,7 @@ PawnInfo* PawnInfoTable::get_pawn_info(const Position& pos) {
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++)
{

View File

@ -35,8 +35,7 @@
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
};
enum Piece {

View File

@ -340,8 +340,8 @@ Bitboard Position::hidden_checkers(Color c) const {
// 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;
@ -384,12 +384,12 @@ Bitboard Position::discovered_check_candidates(Color c) 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
@ -435,8 +435,8 @@ bool Position::move_attacks_square(Move m, Square s) const {
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.
@ -503,8 +503,8 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
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
@ -586,8 +586,8 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const {
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));
}
return false;
@ -674,10 +674,10 @@ inline void Position::update_checkers(Bitboard* pCheckersBB, Square ksq, Square
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()));
if (Piece != BISHOP)
(*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & pieces<BISHOP_AND_QUEEN>(side_to_move()));
(*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & pieces(BISHOP, QUEEN, side_to_move()));
}
}
@ -806,7 +806,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
// 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];
@ -1366,12 +1366,12 @@ int Position::see(Square from, Square to) const {
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;
@ -1384,10 +1384,10 @@ int Position::see(Square from, Square to) const {
// 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++)
assert(pt < KING);
from = first_1(stmAttackers & pieces_of_type(pt));
from = first_1(stmAttackers & pieces(pt));
piece = piece_on(from);
}
@ -1415,15 +1415,15 @@ int Position::see(Square from, Square to) const {
// 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.
b = stmAttackers & pieces_of_type(pt);
b = stmAttackers & pieces(pt);
occ ^= (b & (~b + 1));
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));
attackers &= occ;
@ -1589,7 +1589,7 @@ Key Position::compute_pawn_key() const {
for (Color c = WHITE; c <= BLACK; c++)
{
b = pieces<PAWN>(c);
b = pieces(PAWN, c);
while(b)
{
s = pop_1st_bit(&b);
@ -1634,7 +1634,7 @@ Value Position::compute_value() const {
for (Color c = WHITE; c <= BLACK; c++)
for (PieceType pt = PAWN; pt <= KING; pt++)
{
b = pieces_of_color(c) & pieces_of_type(pt);
b = pieces(pt, c);
while(b)
{
s = pop_1st_bit(&b);
@ -1660,7 +1660,7 @@ Value Position::compute_non_pawn_material(Color c) const {
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));
@ -1679,7 +1679,7 @@ Value Position::compute_non_pawn_material(Color c) const {
bool Position::is_draw() const {
// Draw by material?
if ( !pieces<PAWN>()
if ( !pieces(PAWN)
&& (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMidgame))
return true;
@ -1956,7 +1956,7 @@ bool Position::is_ok(int* failedStep) const {
// 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)))
return false;
}
@ -2012,7 +2012,7 @@ bool Position::is_ok(int* failedStep) const {
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)++;
@ -2022,7 +2022,7 @@ bool Position::is_ok(int* failedStep) const {
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)

View File

@ -162,15 +162,10 @@ public:
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;
@ -399,10 +394,22 @@ inline Bitboard Position::pieces_of_color(Color c) const {
return byColorBB[c];
}
inline Bitboard Position::pieces_of_type(PieceType pt) const {
inline Bitboard Position::pieces(PieceType pt) const {
return byTypeBB[pt];
}
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];
}
@ -496,7 +503,7 @@ inline bool Position::square_is_attacked(Square s, Color c) 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) {
@ -512,7 +519,7 @@ inline bool Position::pawn_is_doubled(Bitboard ourPawns, Color c, Square s) {
}
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 {
@ -588,7 +595,7 @@ inline bool Position::opposite_colored_bishops() 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 {