namespace {
-// next_attacker() is an helper function used by see() to locate the least
+// min_attacker() is an helper function used by see() to locate the least
// valuable attacker for the side to move, remove the attacker we just found
-// from the 'occupied' bitboard and scan for new X-ray attacks behind it.
+// from the bitboards and scan for new X-ray attacks behind it.
template<int Pt> FORCE_INLINE
-PieceType next_attacker(const Bitboard* bb, const Square& to, const Bitboard& stmAttackers,
- Bitboard& occupied, Bitboard& attackers) {
+PieceType min_attacker(const Bitboard* bb, const Square& to, const Bitboard& stmAttackers,
+ Bitboard& occupied, Bitboard& attackers) {
- if (stmAttackers & bb[Pt])
+ Bitboard b = stmAttackers & bb[Pt];
+
+ if (b)
{
- Bitboard b = stmAttackers & bb[Pt];
occupied ^= b & ~(b - 1);
if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN)
if (Pt == ROOK || Pt == QUEEN)
attackers |= attacks_bb<ROOK>(to, occupied) & (bb[ROOK] | bb[QUEEN]);
+ attackers &= occupied; // Remove the just found attacker
+
return (PieceType)Pt;
}
- return next_attacker<Pt+1>(bb, to, stmAttackers, occupied, attackers);
+ return min_attacker<Pt+1>(bb, to, stmAttackers, occupied, attackers);
}
template<> FORCE_INLINE
-PieceType next_attacker<KING>(const Bitboard*, const Square&, const Bitboard&, Bitboard&, Bitboard&) {
+PieceType min_attacker<KING>(const Bitboard*, const Square&, const Bitboard&, Bitboard&, Bitboard&) {
return KING; // No need to update bitboards, it is the last cycle
}
Square rfrom = to; // 'King captures the rook' notation
Square kto = relative_square(us, rfrom > kfrom ? SQ_G1 : SQ_C1);
Square rto = relative_square(us, rfrom > kfrom ? SQ_F1 : SQ_D1);
- Bitboard b = (pieces() ^ kfrom ^ rfrom) | rto | kto;
- return attacks_bb<ROOK>(rto, b) & ksq;
+ return (PseudoAttacks[ROOK][rto] & ksq)
+ && (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & ksq);
}
default:
assert(false);
// Early return if SEE cannot be negative because captured piece value
// is not less then capturing one. Note that king moves always return
// here because king midgame value is set to 0.
- if (PieceValue[MG][piece_on(to_sq(m))] >= PieceValue[MG][piece_moved(m)])
+ if (PieceValue[MG][piece_moved(m)] <= PieceValue[MG][piece_on(to_sq(m))])
return 1;
return see(m);
do {
assert(slIndex < 32);
+ if (captured == KING) // Stop before processing a king capture
+ {
+ swapList[slIndex++] = QueenValueMg * 16;
+ break;
+ }
+
// Add the new entry to the swap list
swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured];
slIndex++;
- // Locate and remove from 'occupied' the next least valuable attacker
- captured = next_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
-
- attackers &= occupied; // Remove the just found attacker
+ // Locate and remove the next least valuable attacker
+ captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
stm = ~stm;
stmAttackers = attackers & pieces(stm);
- if (captured == KING)
- {
- // Stop before processing a king capture
- if (stmAttackers)
- swapList[slIndex++] = QueenValueMg * 16;
-
- break;
- }
-
} while (stmAttackers);
// If we are doing asymmetric SEE evaluation and the same side does the first