1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-03 18:19:35 +00:00

Use more_than_one() instead of single_bit()

It is more correct given what the function does. In
particular single_bit() returns true also in case of
empty bitboards.

Of course also the usual renaming while there :-)

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2012-04-14 09:16:34 +01:00
parent 25a9b601b2
commit f59323b56a
8 changed files with 67 additions and 68 deletions

View file

@ -45,7 +45,7 @@ Bitboard ThisAndAdjacentFilesBB[8];
Bitboard InFrontBB[2][8]; Bitboard InFrontBB[2][8];
Bitboard StepAttacksBB[16][64]; Bitboard StepAttacksBB[16][64];
Bitboard BetweenBB[64][64]; Bitboard BetweenBB[64][64];
Bitboard SquaresInFrontMask[2][64]; Bitboard ForwardBB[2][64];
Bitboard PassedPawnMask[2][64]; Bitboard PassedPawnMask[2][64];
Bitboard AttackSpanMask[2][64]; Bitboard AttackSpanMask[2][64];
Bitboard PseudoAttacks[6][64]; Bitboard PseudoAttacks[6][64];
@ -189,9 +189,9 @@ void Bitboards::init() {
for (Color c = WHITE; c <= BLACK; c++) for (Color c = WHITE; c <= BLACK; c++)
for (Square s = SQ_A1; s <= SQ_H8; s++) for (Square s = SQ_A1; s <= SQ_H8; s++)
{ {
SquaresInFrontMask[c][s] = in_front_bb(c, s) & file_bb(s); ForwardBB[c][s] = in_front_bb(c, s) & file_bb(s);
PassedPawnMask[c][s] = in_front_bb(c, s) & this_and_adjacent_files_bb(file_of(s)); PassedPawnMask[c][s] = in_front_bb(c, s) & this_and_adjacent_files_bb(file_of(s));
AttackSpanMask[c][s] = in_front_bb(c, s) & adjacent_files_bb(file_of(s)); AttackSpanMask[c][s] = in_front_bb(c, s) & adjacent_files_bb(file_of(s));
} }
for (Square s1 = SQ_A1; s1 <= SQ_H8; s1++) for (Square s1 = SQ_A1; s1 <= SQ_H8; s1++)

View file

@ -50,7 +50,7 @@ extern Bitboard ThisAndAdjacentFilesBB[8];
extern Bitboard InFrontBB[2][8]; extern Bitboard InFrontBB[2][8];
extern Bitboard StepAttacksBB[16][64]; extern Bitboard StepAttacksBB[16][64];
extern Bitboard BetweenBB[64][64]; extern Bitboard BetweenBB[64][64];
extern Bitboard SquaresInFrontMask[2][64]; extern Bitboard ForwardBB[2][64];
extern Bitboard PassedPawnMask[2][64]; extern Bitboard PassedPawnMask[2][64];
extern Bitboard AttackSpanMask[2][64]; extern Bitboard AttackSpanMask[2][64];
extern Bitboard PseudoAttacks[6][64]; extern Bitboard PseudoAttacks[6][64];
@ -80,6 +80,13 @@ inline Bitboard operator^(Bitboard b, Square s) {
} }
/// more_than_one() returns true if in 'b' there is more than one bit set
inline bool more_than_one(Bitboard b) {
return b & (b - 1);
}
/// rank_bb() and file_bb() take a file or a square as input and return /// rank_bb() and file_bb() take a file or a square as input and return
/// a bitboard representing all squares on the given file or rank. /// a bitboard representing all squares on the given file or rank.
@ -131,48 +138,23 @@ inline Bitboard in_front_bb(Color c, Square s) {
} }
/// Functions for computing sliding attack bitboards. Function attacks_bb() takes /// between_bb returns a bitboard representing all squares between two squares.
/// a square and a bitboard of occupied squares as input, and returns a bitboard /// For instance, between_bb(SQ_C4, SQ_F7) returns a bitboard with the bits for
/// representing all squares attacked by Pt (bishop or rook) on the given square. /// square d5 and e6 set. If s1 and s2 are not on the same line, file or diagonal,
template<PieceType Pt> /// 0 is returned.
FORCE_INLINE unsigned magic_index(Square s, Bitboard occ) {
Bitboard* const Masks = Pt == ROOK ? RMasks : BMasks; inline Bitboard between_bb(Square s1, Square s2) {
Bitboard* const Magics = Pt == ROOK ? RMagics : BMagics;
unsigned* const Shifts = Pt == ROOK ? RShifts : BShifts;
if (Is64Bit)
return unsigned(((occ & Masks[s]) * Magics[s]) >> Shifts[s]);
unsigned lo = unsigned(occ) & unsigned(Masks[s]);
unsigned hi = unsigned(occ >> 32) & unsigned(Masks[s] >> 32);
return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s];
}
template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Bitboard occ) {
Bitboard** const Attacks = Pt == ROOK ? RAttacks : BAttacks;
return Attacks[s][magic_index<Pt>(s, occ)];
}
/// squares_between returns a bitboard representing all squares between
/// two squares. For instance, squares_between(SQ_C4, SQ_F7) returns a
/// bitboard with the bits for square d5 and e6 set. If s1 and s2 are not
/// on the same line, file or diagonal, EmptyBoardBB is returned.
inline Bitboard squares_between(Square s1, Square s2) {
return BetweenBB[s1][s2]; return BetweenBB[s1][s2];
} }
/// squares_in_front_of takes a color and a square as input, and returns a /// forward_bb takes a color and a square as input, and returns a bitboard
/// bitboard representing all squares along the line in front of the square, /// representing all squares along the line in front of the square, from the
/// from the point of view of the given color. Definition of the table is: /// point of view of the given color. Definition of the table is:
/// SquaresInFrontOf[c][s] = in_front_bb(c, s) & file_bb(s) /// ForwardBB[c][s] = in_front_bb(c, s) & file_bb(s)
inline Bitboard squares_in_front_of(Color c, Square s) { inline Bitboard forward_bb(Color c, Square s) {
return SquaresInFrontMask[c][s]; return ForwardBB[c][s];
} }
@ -214,11 +196,28 @@ inline Bitboard same_color_squares(Square s) {
} }
/// single_bit() returns true if in the 'b' bitboard is set a single bit (or if /// Functions for computing sliding attack bitboards. Function attacks_bb() takes
/// b == 0). /// a square and a bitboard of occupied squares as input, and returns a bitboard
/// representing all squares attacked by Pt (bishop or rook) on the given square.
template<PieceType Pt>
FORCE_INLINE unsigned magic_index(Square s, Bitboard occ) {
inline bool single_bit(Bitboard b) { Bitboard* const Masks = Pt == ROOK ? RMasks : BMasks;
return !(b & (b - 1)); Bitboard* const Magics = Pt == ROOK ? RMagics : BMagics;
unsigned* const Shifts = Pt == ROOK ? RShifts : BShifts;
if (Is64Bit)
return unsigned(((occ & Masks[s]) * Magics[s]) >> Shifts[s]);
unsigned lo = unsigned(occ) & unsigned(Masks[s]);
unsigned hi = unsigned(occ >> 32) & unsigned(Masks[s] >> 32);
return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s];
}
template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Bitboard occ) {
Bitboard** const Attacks = Pt == ROOK ? RAttacks : BAttacks;
return Attacks[s][magic_index<Pt>(s, occ)];
} }

View file

@ -710,7 +710,7 @@ ScaleFactor Endgame<KBPKB>::operator()(const Position& pos) const {
return SCALE_FACTOR_DRAW; return SCALE_FACTOR_DRAW;
else else
{ {
Bitboard path = squares_in_front_of(strongerSide, pawnSq); Bitboard path = forward_bb(strongerSide, pawnSq);
if (path & pos.pieces(KING, weakerSide)) if (path & pos.pieces(KING, weakerSide))
return SCALE_FACTOR_DRAW; return SCALE_FACTOR_DRAW;

View file

@ -581,7 +581,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
assert(b); assert(b);
if (single_bit(b) && (b & pos.pieces(Them))) if (!more_than_one(b) && (b & pos.pieces(Them)))
score += ThreatBonus[Piece][type_of(pos.piece_on(first_1(b)))]; score += ThreatBonus[Piece][type_of(pos.piece_on(first_1(b)))];
} }
@ -689,8 +689,8 @@ Value do_evaluate(const Position& pos, Value& margin) {
& ~ei.attackedBy[Them][0]; & ~ei.attackedBy[Them][0];
if (undefendedMinors) if (undefendedMinors)
score += single_bit(undefendedMinors) ? UndefendedMinorPenalty score += more_than_one(undefendedMinors) ? UndefendedMinorPenalty * 2
: UndefendedMinorPenalty * 2; : UndefendedMinorPenalty;
// Enemy pieces not defended by a pawn and under our attack // Enemy pieces not defended by a pawn and under our attack
weakEnemies = pos.pieces(Them) weakEnemies = pos.pieces(Them)
@ -896,14 +896,14 @@ Value do_evaluate(const Position& pos, Value& margin) {
// If the pawn is free to advance, increase bonus // If the pawn is free to advance, increase bonus
if (pos.square_empty(blockSq)) if (pos.square_empty(blockSq))
{ {
squaresToQueen = squares_in_front_of(Us, s); squaresToQueen = forward_bb(Us, s);
defendedSquares = squaresToQueen & ei.attackedBy[Us][0]; defendedSquares = squaresToQueen & ei.attackedBy[Us][0];
// If there is an enemy rook or queen attacking the pawn from behind, // If there is an enemy rook or queen attacking the pawn from behind,
// add all X-ray attacks by the rook or queen. Otherwise consider only // add all X-ray attacks by the rook or queen. Otherwise consider only
// the squares in the pawn's path attacked or occupied by the enemy. // the squares in the pawn's path attacked or occupied by the enemy.
if ( (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them)) if ( (forward_bb(Them, s) & pos.pieces(ROOK, QUEEN, Them))
&& (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s))) && (forward_bb(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
unsafeSquares = squaresToQueen; unsafeSquares = squaresToQueen;
else else
unsafeSquares = squaresToQueen & (ei.attackedBy[Them][0] | pos.pieces(Them)); unsafeSquares = squaresToQueen & (ei.attackedBy[Them][0] | pos.pieces(Them));
@ -978,7 +978,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
{ {
s = pop_1st_bit(&b); s = pop_1st_bit(&b);
queeningSquare = relative_square(c, make_square(file_of(s), RANK_8)); queeningSquare = relative_square(c, make_square(file_of(s), RANK_8));
queeningPath = squares_in_front_of(c, s); queeningPath = forward_bb(c, s);
// Compute plies to queening and check direct advancement // Compute plies to queening and check direct advancement
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2); movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2);
@ -1026,7 +1026,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
// Check if (without even considering any obstacles) we're too far away or doubled // Check if (without even considering any obstacles) we're too far away or doubled
if ( pliesToQueen[winnerSide] + 3 <= pliesToGo if ( pliesToQueen[winnerSide] + 3 <= pliesToGo
|| (squares_in_front_of(loserSide, s) & pos.pieces(PAWN, loserSide))) || (forward_bb(loserSide, s) & pos.pieces(PAWN, loserSide)))
candidates ^= s; candidates ^= s;
} }
@ -1050,7 +1050,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
// Generate list of blocking pawns and supporters // Generate list of blocking pawns and supporters
supporters = adjacent_files_bb(file_of(s)) & candidates; supporters = adjacent_files_bb(file_of(s)) & candidates;
opposed = squares_in_front_of(loserSide, s) & pos.pieces(PAWN, winnerSide); opposed = forward_bb(loserSide, s) & pos.pieces(PAWN, winnerSide);
blockers = passed_pawn_mask(loserSide, s) & pos.pieces(PAWN, winnerSide); blockers = passed_pawn_mask(loserSide, s) & pos.pieces(PAWN, winnerSide);
assert(blockers); assert(blockers);

View file

@ -410,7 +410,7 @@ MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
// If queen and king are far or not on a diagonal line we can safely // If queen and king are far or not on a diagonal line we can safely
// remove all the squares attacked in the other direction becuase are // remove all the squares attacked in the other direction becuase are
// not reachable by the king anyway. // not reachable by the king anyway.
if (squares_between(ksq, checksq) || !(PseudoAttacks[BISHOP][checksq] & ksq)) if (between_bb(ksq, checksq) || !(PseudoAttacks[BISHOP][checksq] & ksq))
sliderAttacks |= PseudoAttacks[QUEEN][checksq]; sliderAttacks |= PseudoAttacks[QUEEN][checksq];
// Otherwise we need to use real rook attacks to check if king is safe // Otherwise we need to use real rook attacks to check if king is safe
@ -434,7 +434,7 @@ MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
return mlist; return mlist;
// Blocking evasions or captures of the checking piece // Blocking evasions or captures of the checking piece
target = squares_between(checksq, ksq) | checkers; target = between_bb(checksq, ksq) | checkers;
mlist = (us == WHITE ? generate_pawn_moves<WHITE, MV_EVASION>(pos, mlist, target) mlist = (us == WHITE ? generate_pawn_moves<WHITE, MV_EVASION>(pos, mlist, target)
: generate_pawn_moves<BLACK, MV_EVASION>(pos, mlist, target)); : generate_pawn_moves<BLACK, MV_EVASION>(pos, mlist, target));

View file

@ -152,8 +152,8 @@ Score PawnTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
// chain (but not the backward one). // chain (but not the backward one).
chain = ourPawns & adjacent_files_bb(f) & b; chain = ourPawns & adjacent_files_bb(f) & b;
isolated = !(ourPawns & adjacent_files_bb(f)); isolated = !(ourPawns & adjacent_files_bb(f));
doubled = ourPawns & squares_in_front_of(Us, s); doubled = ourPawns & forward_bb(Us, s);
opposed = theirPawns & squares_in_front_of(Us, s); opposed = theirPawns & forward_bb(Us, s);
passed = !(theirPawns & passed_pawn_mask(Us, s)); passed = !(theirPawns & passed_pawn_mask(Us, s));
// Test for backward pawn // Test for backward pawn

View file

@ -364,9 +364,9 @@ Bitboard Position::hidden_checkers() const {
while (pinners) while (pinners)
{ {
b = squares_between(ksq, pop_1st_bit(&pinners)) & pieces(); b = between_bb(ksq, pop_1st_bit(&pinners)) & pieces();
if (b && single_bit(b) && (b & pieces(sideToMove))) if (b && !more_than_one(b) && (b & pieces(sideToMove)))
result |= b; result |= b;
} }
return result; return result;
@ -608,7 +608,7 @@ bool Position::is_pseudo_legal(const Move m) const {
return false; return false;
// Our move must be a blocking evasion or a capture of the checking piece // Our move must be a blocking evasion or a capture of the checking piece
if (!((squares_between(checksq, king_square(us)) | checkers()) & to)) if (!((between_bb(checksq, king_square(us)) | checkers()) & to))
return false; return false;
} }
// In case of king moves under check we have to remove king so to catch // In case of king moves under check we have to remove king so to catch

View file

@ -1337,7 +1337,7 @@ split_point_start: // At split points actual search starts from here
// Rule 1. Checks which give opponent's king at most one escape square are dangerous // Rule 1. Checks which give opponent's king at most one escape square are dangerous
b = kingAtt & ~pos.pieces(them) & ~newAtt & ~(1ULL << to); b = kingAtt & ~pos.pieces(them) & ~newAtt & ~(1ULL << to);
if (single_bit(b)) // Catches also !b if (!more_than_one(b))
return true; return true;
// Rule 2. Queen contact check is very dangerous // Rule 2. Queen contact check is very dangerous
@ -1386,7 +1386,7 @@ split_point_start: // At split points actual search starts from here
// Case 3: Moving through the vacated square // Case 3: Moving through the vacated square
p2 = pos.piece_on(f2); p2 = pos.piece_on(f2);
if (piece_is_slider(p2) && (squares_between(f2, t2) & f1)) if (piece_is_slider(p2) && (between_bb(f2, t2) & f1))
return true; return true;
// Case 4: The destination square for m2 is defended by the moving piece in m1 // Case 4: The destination square for m2 is defended by the moving piece in m1
@ -1397,7 +1397,7 @@ split_point_start: // At split points actual search starts from here
// Case 5: Discovered check, checking piece is the piece moved in m1 // Case 5: Discovered check, checking piece is the piece moved in m1
ksq = pos.king_square(pos.side_to_move()); ksq = pos.king_square(pos.side_to_move());
if ( piece_is_slider(p1) if ( piece_is_slider(p1)
&& (squares_between(t1, ksq) & f2) && (between_bb(t1, ksq) & f2)
&& (pos.attacks_from(p1, t1, pos.pieces() ^ f2) & ksq)) && (pos.attacks_from(p1, t1, pos.pieces() ^ f2) & ksq))
return true; return true;
@ -1469,7 +1469,7 @@ split_point_start: // At split points actual search starts from here
// Case 3: If the moving piece in the threatened move is a slider, don't // Case 3: If the moving piece in the threatened move is a slider, don't
// prune safe moves which block its ray. // prune safe moves which block its ray.
if ( piece_is_slider(pos.piece_on(tfrom)) if ( piece_is_slider(pos.piece_on(tfrom))
&& (squares_between(tfrom, tto) & mto) && (between_bb(tfrom, tto) & mto)
&& pos.see_sign(m) >= 0) && pos.see_sign(m) >= 0)
return true; return true;
@ -1873,7 +1873,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
&& spCnt > 0 && spCnt > 0
&& !latest->cutoff && !latest->cutoff
&& latest->slavesMask == latest->allSlavesMask && latest->slavesMask == latest->allSlavesMask
&& !single_bit(latest->allSlavesMask)) && more_than_one(latest->allSlavesMask))
{ {
lock_grab(latest->lock); lock_grab(latest->lock);
lock_grab(Threads.splitLock); lock_grab(Threads.splitLock);
@ -1884,7 +1884,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
&& spCnt == th->splitPointsCnt && spCnt == th->splitPointsCnt
&& !latest->cutoff && !latest->cutoff
&& latest->slavesMask == latest->allSlavesMask && latest->slavesMask == latest->allSlavesMask
&& !single_bit(latest->allSlavesMask)) && more_than_one(latest->allSlavesMask))
{ {
latest->slavesMask |= 1ULL << idx; // allSlavesMask is not updated latest->slavesMask |= 1ULL << idx; // allSlavesMask is not updated
curSplitPoint = latest; curSplitPoint = latest;