From 76bed11f7b79d939c250c02d73d0c1e2628e7a17 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 31 Aug 2009 17:07:03 +0200 Subject: [PATCH] Templetize functions to get pieces by type Use a single template to get bitboard representation of the position given the type of piece as a constant. This removes almost 80 lines of code and introduces an uniform notation to be used for querying for piece type. No functional change and no performance change. Signed-off-by: Marco Costalba --- src/endgame.cpp | 20 +++++----- src/evaluate.cpp | 34 ++++++++-------- src/material.cpp | 10 ++--- src/movegen.cpp | 28 ++++++------- src/pawns.cpp | 6 +-- src/piece.h | 3 +- src/position.cpp | 54 ++++++++++++------------- src/position.h | 102 ++++++----------------------------------------- 8 files changed, 90 insertions(+), 167 deletions(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index d9961622..69d0df51 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -329,7 +329,7 @@ Value EvaluationFunction::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.pawns() == EmptyBoardBB); + assert(pos.pieces() == EmptyBoardBB); Value result = BishopValueEndgame; Square wksq = pos.king_square(strongerSide); @@ -376,7 +376,7 @@ ScaleFactor ScalingFunction::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.pawns(strongerSide); + Bitboard pawns = pos.pieces(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::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.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) - && (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) - && (pos.piece_attacks(kingSq) & pos.pawns(weakerSide))) + && (pos.pieces(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) + && (pos.pieces(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) + && (pos.piece_attacks(kingSq) & pos.pieces(weakerSide))) { Square rsq = pos.piece_list(weakerSide, ROOK, 0); - if (pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide)) + if (pos.pawn_attacks(strongerSide, rsq) & pos.pieces(weakerSide)) return ScaleFactor(0); } return SCALE_FACTOR_NONE; @@ -616,7 +616,7 @@ ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(weakerSide) == Value(0)); assert(pos.piece_count(weakerSide, PAWN) == 0); - Bitboard pawns = pos.pawns(strongerSide); + Bitboard pawns = pos.pieces(strongerSide); // Are all pawns on the 'a' file? if ((pawns & ~FileABB) == EmptyBoardBB) @@ -694,7 +694,7 @@ ScaleFactor ScalingFunction::apply(const Position &pos) { else { Bitboard ray = ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S); - if (ray & pos.kings(weakerSide)) + if (ray & pos.pieces(weakerSide)) return ScaleFactor(0); if( (pos.piece_attacks(weakerBishopSq) & ray) && square_distance(weakerBishopSq, pawnSq) >= 3) @@ -761,13 +761,13 @@ ScaleFactor ScalingFunction::apply(const Position& pos) { if ( ksq == blockSq1 && square_color(ksq) != square_color(wbsq) && ( bbsq == blockSq2 - || (pos.piece_attacks(blockSq2) & pos.bishops(weakerSide)) + || (pos.piece_attacks(blockSq2) & pos.pieces(weakerSide)) || rank_distance(r1, r2) >= 2)) return ScaleFactor(0); else if ( ksq == blockSq2 && square_color(ksq) != square_color(wbsq) && ( bbsq == blockSq1 - || (pos.piece_attacks(blockSq1) & pos.bishops(weakerSide)))) + || (pos.piece_attacks(blockSq1) & pos.pieces(weakerSide)))) return ScaleFactor(0); else return SCALE_FACTOR_NONE; diff --git a/src/evaluate.cpp b/src/evaluate.cpp index a291ec46..a1015edf 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -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.pawns(WHITE) << 9) & ~FileABB) | ((pos.pawns(WHITE) << 7) & ~FileHBB); - ei.attackedBy[BLACK][PAWN] = ((pos.pawns(BLACK) >> 7) & ~FileABB) | ((pos.pawns(BLACK) >> 9) & ~FileHBB); + ei.attackedBy[WHITE][PAWN] = ((pos.pieces(WHITE) << 9) & ~FileABB) | ((pos.pieces(WHITE) << 7) & ~FileHBB); + ei.attackedBy[BLACK][PAWN] = ((pos.pieces(BLACK) >> 7) & ~FileABB) | ((pos.pieces(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.pawns(us))) + if (bonus && (p.pawn_attacks(them, s) & p.pieces(us))) { - if ( p.knights(them) == EmptyBoardBB - && (SquaresByColorBB[square_color(s)] & p.bishops(them)) == EmptyBoardBB) + if ( p.pieces(them) == EmptyBoardBB + && (SquaresByColorBB[square_color(s)] & p.pieces(them)) == EmptyBoardBB) bonus += bonus + bonus / 2; else bonus += bonus / 2; @@ -622,9 +622,9 @@ namespace { if (Piece == KNIGHT || Piece == QUEEN) b = pos.piece_attacks(s); else if (Piece == BISHOP) - b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.queens(us)); + b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(us)); else if (Piece == ROOK) - b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.rooks_and_queens(us)); + b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(us)); else assert(false); @@ -787,8 +787,8 @@ namespace { from = p.piece_list(them, QUEEN, i); if ( bit_is_set(p.piece_attacks(from), to) && !bit_is_set(p.pinned_pieces(them), from) - && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.rooks_and_queens(us)) - && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.bishops_and_queens(us))) + && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces(us)) + && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces(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.pawns(); + b = p.discovered_check_candidates(them) & ~p.pieces(); if (b) attackUnits += DiscoveredCheckBonus * count_1s_max_15(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.pawns(us), b2, b3, b4; + Bitboard b = ei.pi->passed_pawns() & pos.pieces(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.rooks_and_queens(them))) + && (squares_behind(us, s) & pos.pieces(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_of_color(them) & pos.pieces_of_type(PAWN)) == EmptyBoardBB); + assert((b2 & pos.pieces(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.pawns(us) & neighboring_files_bb(s); + b2 = pos.pieces(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.rooks_and_queens(them)) + else if (pos.pieces(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.pawns(us) + & ~pos.pieces(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.pawns(us); + Bitboard behindFriendlyPawns = pos.pieces(us); if (us == WHITE) { behindFriendlyPawns |= (behindFriendlyPawns >> 8); diff --git a/src/material.cpp b/src/material.cpp index b1671058..9a20292b 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -171,14 +171,14 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) { mi->evaluationFunction = &EvaluateKKX; return mi; } - else if ( pos.pawns() == EmptyBoardBB - && pos.rooks() == EmptyBoardBB - && pos.queens() == EmptyBoardBB) + else if ( pos.pieces() == EmptyBoardBB + && pos.pieces() == EmptyBoardBB + && pos.pieces() == 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.knights(WHITE) | pos.bishops(WHITE)); - assert(pos.knights(BLACK) | pos.bishops(BLACK)); + assert((pos.pieces(WHITE) | pos.pieces(WHITE))); + assert((pos.pieces(BLACK) | pos.pieces(BLACK))); if ( pos.piece_count(WHITE, BISHOP) + pos.piece_count(WHITE, KNIGHT) <= 2 && pos.piece_count(BLACK, BISHOP) + pos.piece_count(BLACK, KNIGHT) <= 2) diff --git a/src/movegen.cpp b/src/movegen.cpp index bf8293b1..41f5b077 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -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.queens() | pos.bishops()); + Bitboard b = checkers & pos.pieces(); while (b) { from = pop_1st_bit(&b); checkersAttacks |= bishop_attacks_bb(from, b_noKing); } - b = checkers & (pos.queens() | pos.rooks()); + b = checkers & pos.pieces(); 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.pawns(us) & ~pinned; + b1 = pos.pawn_attacks(them, checksq) & pos.pieces(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(checksq) & pos.knights(us)) - | (pos.piece_attacks(checksq) & pos.bishops_and_queens(us)) - | (pos.piece_attacks(checksq) & pos.rooks_and_queens(us)) ) & ~pinned; + b1 = ( (pos.piece_attacks(checksq) & pos.pieces(us)) + | (pos.piece_attacks(checksq) & pos.pieces(us)) + | (pos.piece_attacks(checksq) & pos.pieces(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.sliders()) + if (checkers & (pos.pieces() | pos.pieces() | pos.pieces())) { 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.pawns(them))) + if (pos.ep_square() != SQ_NONE && (checkers & pos.pieces(them))) { to = pos.ep_square(); - b1 = pos.pawn_attacks(them, to) & pos.pawns(us); + b1 = pos.pawn_attacks(them, to) & pos.pieces(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.pawns(Us); + Bitboard pawns = pos.pieces(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.pawns(Us); + Bitboard pawns = pos.pieces(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.pawns(Us); + Bitboard pawns = pos.pieces(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_of_color(us) & pos.pieces_of_type(Piece); + Bitboard target = pos.pieces(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(pos.pawns(Us) & ~pinned); + Bitboard b1 = move_pawns(pos.pieces(Us) & ~pinned); // We don't have to AND with empty squares here, // because the blocking squares will always be empty. diff --git a/src/pawns.cpp b/src/pawns.cpp index 96664e5c..1d8b082e 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -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.pawns(us); - Bitboard theirPawns = pos.pawns(them); + Bitboard ourPawns = pos.pieces(us); + Bitboard theirPawns = pos.pieces(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.pawns(c) & this_and_neighboring_files_bb(ksq); + Bitboard pawns = pos.pieces(c) & this_and_neighboring_files_bb(ksq); unsigned r = ksq & (7 << 3); for (int i = 1, k = (c ? -8 : 8); i < 4; i++) { diff --git a/src/piece.h b/src/piece.h index 48e26c39..5b93ea7d 100644 --- a/src/piece.h +++ b/src/piece.h @@ -35,7 +35,8 @@ enum PieceType { NO_PIECE_TYPE = 0, - PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6 + PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6, + BISHOP_AND_QUEEN = 8, ROOK_AND_QUEEN = 9 }; enum Piece { diff --git a/src/position.cpp b/src/position.cpp index 9b8f7798..aa07cd51 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -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 = (rooks_and_queens(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq]) - | (bishops_and_queens(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]); + pinners = (pieces(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq]) + | (pieces(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) & pawns(WHITE)) - | (pawn_attacks(WHITE, s) & pawns(BLACK)) - | (piece_attacks(s) & pieces_of_type(KNIGHT)) - | (piece_attacks(s) & rooks_and_queens()) - | (piece_attacks(s) & bishops_and_queens()) - | (piece_attacks(s) & pieces_of_type(KING)); + return (pawn_attacks(BLACK, s) & pieces(WHITE)) + | (pawn_attacks(WHITE, s) & pieces(BLACK)) + | (piece_attacks(s) & pieces()) + | (piece_attacks(s) & pieces()) + | (piece_attacks(s) & pieces()) + | (piece_attacks(s) & pieces()); } /// 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) & rooks_and_queens()) - |(bishop_attacks_bb(s, occ) & bishops_and_queens())) & pieces_of_color(us); + Bitboard xray = ( (rook_attacks_bb(s, occ) & pieces()) + |(bishop_attacks_bb(s, occ) & pieces())) & 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) & rooks_and_queens(them)) - && !(bishop_attacks_bb(ksq, b) & bishops_and_queens(them)); + return !(rook_attacks_bb(ksq, b) & pieces(them)) + && !(bishop_attacks_bb(ksq, b) & pieces(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) & rooks_and_queens(us)) - ||(bishop_attacks_bb(ksq, b) & bishops_and_queens(us)); + return (rook_attacks_bb(ksq, b) & pieces(us)) + ||(bishop_attacks_bb(ksq, b) & pieces(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(ksq) & rooks_and_queens(side_to_move())); + (*pCheckersBB) |= (piece_attacks(ksq) & pieces(side_to_move())); if (Piece != BISHOP) - (*pCheckersBB) |= (piece_attacks(ksq) & bishops_and_queens(side_to_move())); + (*pCheckersBB) |= (piece_attacks(ksq) & pieces(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)) & pawns(them)) + if (pawn_attacks(us, from + (us == WHITE ? DELTA_N : DELTA_S)) & pieces(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) & rooks_and_queens()) - | (bishop_attacks_bb(to, occ) & bishops_and_queens()) - | (piece_attacks(to) & knights()) - | (piece_attacks(to) & kings()) - | (pawn_attacks(WHITE, to) & pawns(BLACK)) - | (pawn_attacks(BLACK, to) & pawns(WHITE)); + attackers = (rook_attacks_bb(to, occ) & pieces()) + | (bishop_attacks_bb(to, occ) & pieces()) + | (piece_attacks(to) & pieces()) + | (piece_attacks(to) & pieces()) + | (pawn_attacks(WHITE, to) & pieces(BLACK)) + | (pawn_attacks(BLACK, to) & pieces(WHITE)); if (from != SQ_NONE) break; @@ -1422,8 +1422,8 @@ int Position::see(Square from, Square to) const { // and scan for new X-ray attacks behind the attacker. b = stmAttackers & pieces_of_type(pt); occ ^= (b & (~b + 1)); - attackers |= (rook_attacks_bb(to, occ) & rooks_and_queens()) - | (bishop_attacks_bb(to, occ) & bishops_and_queens()); + attackers |= (rook_attacks_bb(to, occ) & pieces()) + | (bishop_attacks_bb(to, occ) & pieces()); attackers &= occ; @@ -1589,7 +1589,7 @@ Key Position::compute_pawn_key() const { for (Color c = WHITE; c <= BLACK; c++) { - b = pawns(c); + b = pieces(c); while(b) { s = pop_1st_bit(&b); @@ -1679,7 +1679,7 @@ Value Position::compute_non_pawn_material(Color c) const { bool Position::is_draw() const { // Draw by material? - if ( !pawns() + if ( !pieces() && (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMidgame)) return true; diff --git a/src/position.h b/src/position.h index 16e72519..b3d0cd0a 100644 --- a/src/position.h +++ b/src/position.h @@ -163,24 +163,14 @@ public: Bitboard occupied_squares() const; Bitboard pieces_of_color(Color c) const; Bitboard pieces_of_type(PieceType pt) const; - Bitboard pawns() const; - Bitboard knights() const; - Bitboard bishops() const; - Bitboard rooks() const; - Bitboard queens() const; - Bitboard kings() const; - Bitboard rooks_and_queens() const; - Bitboard bishops_and_queens() const; - Bitboard sliders() const; - Bitboard pawns(Color c) const; - Bitboard knights(Color c) const; - Bitboard bishops(Color c) const; - Bitboard rooks(Color c) const; - Bitboard queens(Color c) const; - Bitboard kings(Color c) const; - Bitboard rooks_and_queens(Color c) const; - Bitboard bishops_and_queens(Color c) const; - Bitboard sliders_of_color(Color c) const; + + // Pieces by constant type of both colors + template Bitboard pieces() const { return byTypeBB[Piece]; } + template<> Bitboard pieces() const { return byTypeBB[BISHOP] | byTypeBB[QUEEN]; } + template<> Bitboard pieces() const { return byTypeBB[ROOK] | byTypeBB[QUEEN]; } + + // Pieces by constant type of a given color + template Bitboard pieces(Color c) const { return byColorBB[c] & pieces(); } // Number of pieces of each color and type int piece_count(Color c, PieceType pt) const; @@ -413,74 +403,6 @@ inline Bitboard Position::pieces_of_type(PieceType pt) const { return byTypeBB[pt]; } -inline Bitboard Position::pawns() const { - return pieces_of_type(PAWN); -} - -inline Bitboard Position::knights() const { - return pieces_of_type(KNIGHT); -} - -inline Bitboard Position::bishops() const { - return pieces_of_type(BISHOP); -} - -inline Bitboard Position::rooks() const { - return pieces_of_type(ROOK); -} - -inline Bitboard Position::queens() const { - return pieces_of_type(QUEEN); -} - -inline Bitboard Position::kings() const { - return pieces_of_type(KING); -} - -inline Bitboard Position::rooks_and_queens() const { - return rooks() | queens(); -} - -inline Bitboard Position::bishops_and_queens() const { - return bishops() | queens(); -} - -inline Bitboard Position::sliders() const { - return bishops() | queens() | rooks(); -} - -inline Bitboard Position::pawns(Color c) const { - return pieces_of_color(c) & pieces_of_type(PAWN); -} - -inline Bitboard Position::knights(Color c) const { - return pieces_of_color(c) & pieces_of_type(KNIGHT); -} - -inline Bitboard Position::bishops(Color c) const { - return pieces_of_color(c) & pieces_of_type(BISHOP); -} - -inline Bitboard Position::rooks(Color c) const { - return pieces_of_color(c) & pieces_of_type(ROOK); -} - -inline Bitboard Position::queens(Color c) const { - return pieces_of_color(c) & pieces_of_type(QUEEN); -} - -inline Bitboard Position::kings(Color c) const { - return pieces_of_color(c) & pieces_of_type(KING); -} - -inline Bitboard Position::rooks_and_queens(Color c) const { - return pieces_of_color(c) & rooks_and_queens(); -} - -inline Bitboard Position::bishops_and_queens(Color c) const { - return pieces_of_color(c) & bishops_and_queens(); -} - inline int Position::piece_count(Color c, PieceType pt) const { return pieceCount[c][pt]; } @@ -559,7 +481,7 @@ inline bool Position::pawn_attacks_square(Color c, Square f, Square t) const { } template -Bitboard Position::piece_attacks_square(Square f, Square t) const { +inline Bitboard Position::piece_attacks_square(Square f, Square t) const { return bit_is_set(piece_attacks(f), t); } @@ -574,7 +496,7 @@ inline bool Position::square_is_attacked(Square s, Color c) const { } inline bool Position::pawn_is_passed(Color c, Square s) const { - return !(pawns(opposite_color(c)) & passed_pawn_mask(c, s)); + return !(pieces(opposite_color(c)) & passed_pawn_mask(c, s)); } inline bool Position::pawn_is_passed(Bitboard theirPawns, Color c, Square s) { @@ -590,7 +512,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 !(pawns(c) & outpost_mask(opposite_color(c), s)); + return !(pieces(c) & outpost_mask(opposite_color(c), s)); } inline Key Position::get_key() const { @@ -666,7 +588,7 @@ inline bool Position::opposite_colored_bishops() const { inline bool Position::has_pawn_on_7th(Color c) const { - return pawns(c) & relative_rank_bb(c, RANK_7); + return pieces(c) & relative_rank_bb(c, RANK_7); } inline bool Position::move_is_capture(Move m) const { -- 2.39.2