: Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
: pos.attacks_from<Pt>(s);
- if (pos.pinned_pieces(Us) & s)
+ if (pos.blockers_for_king(Us) & s)
b &= LineBB[pos.square<KING>(Us)][s];
attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
if (Pt == QUEEN)
{
// Penalty if any relative pin or discovered attack against the queen
- Bitboard pinners;
- if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, pinners))
+ Bitboard queenPinners;
+ if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
score -= WeakQueen;
}
}
: AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
const Square ksq = pos.square<KING>(Us);
- Bitboard weak, b, b1, b2, safe, unsafeChecks;
+ Bitboard weak, b, b1, b2, safe, unsafeChecks, pinned;
// King shelter and enemy pawns storm
Score score = pe->king_safety<Us>(pos, ksq);
// Unsafe or occupied checking squares will also be considered, as long as
// the square is in the attacker's mobility area.
unsafeChecks &= mobilityArea[Them];
+ pinned = pos.blockers_for_king(Us) & pos.pieces(Us);
kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
+ 102 * kingAdjacentZoneAttacksCount[Them]
+ 191 * popcount(kingRing[Us] & weak)
- + 143 * popcount(pos.pinned_pieces(Us) | unsafeChecks)
+ + 143 * popcount(pinned | unsafeChecks)
- 848 * !pos.count<QUEEN>(Them)
- 9 * mg_value(score) / 8
+ 40;
// if the pawn is not on the same file as the enemy king, because we
// don't generate captures. Note that a possible discovery check
// promotion has been already generated amongst the captures.
- Bitboard dcCandidates = pos.discovered_check_candidates();
+ Bitboard dcCandidates = pos.blockers_for_king(Them);
if (pawnsNotOn7 & dcCandidates)
{
Bitboard dc1 = shift<Up>(pawnsNotOn7 & dcCandidates) & emptySquares & ~file_bb(ksq);
&& !(PseudoAttacks[Pt][from] & target & pos.check_squares(Pt)))
continue;
- if (pos.discovered_check_candidates() & from)
+ if (pos.blockers_for_king(~us) & from)
continue;
}
assert(!pos.checkers());
Color us = pos.side_to_move();
- Bitboard dc = pos.discovered_check_candidates();
+ Bitboard dc = pos.blockers_for_king(~us) & pos.pieces(us);
while (dc)
{
template<>
ExtMove* generate<LEGAL>(const Position& pos, ExtMove* moveList) {
- Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
- Square ksq = pos.square<KING>(pos.side_to_move());
+ Color us = pos.side_to_move();
+ Bitboard pinned = pos.blockers_for_king(us) & pos.pieces(us);
+ Square ksq = pos.square<KING>(us);
ExtMove* cur = moveList;
moveList = pos.checkers() ? generate<EVASIONS >(pos, moveList)
Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
- Bitboard result = 0;
+ Bitboard blockers = 0;
pinners = 0;
// Snipers are sliders that attack 's' when a piece is removed
Square sniperSq = pop_lsb(&snipers);
Bitboard b = between_bb(s, sniperSq) & pieces();
- if (!more_than_one(b))
+ if (b && !more_than_one(b))
{
- result |= b;
+ blockers |= b;
if (b & pieces(color_of(piece_on(s))))
pinners |= sniperSq;
}
}
- return result;
+ return blockers;
}
// A non-king move is legal if and only if it is not pinned or it
// is moving along the ray towards or away from the king.
- return !(pinned_pieces(us) & from)
+ return !(blockers_for_king(us) & from)
|| aligned(from, to_sq(m), square<KING>(us));
}
return true;
// Is there a discovered check?
- if ( (discovered_check_candidates() & from)
+ if ( (st->blockersForKing[~sideToMove] & from)
&& !aligned(from, to, square<KING>(~sideToMove)))
return true;
// Checking
Bitboard checkers() const;
- Bitboard discovered_check_candidates() const;
- Bitboard pinned_pieces(Color c) const;
+ Bitboard blockers_for_king(Color c) const;
Bitboard check_squares(PieceType pt) const;
// Attacks to/from a given square
return st->checkersBB;
}
-inline Bitboard Position::discovered_check_candidates() const {
- return st->blockersForKing[~sideToMove] & pieces(sideToMove);
-}
-
-inline Bitboard Position::pinned_pieces(Color c) const {
- return st->blockersForKing[c] & pieces(c);
+inline Bitboard Position::blockers_for_king(Color c) const {
+ return st->blockersForKing[c];
}
inline Bitboard Position::check_squares(PieceType pt) const {
void update_quiet_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus);
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCnt, int bonus);
+ inline bool gives_check(const Position& pos, Move move) {
+ Color us = pos.side_to_move();
+ return type_of(move) == NORMAL && !(pos.blockers_for_king(~us) & pos.pieces(us))
+ ? pos.check_squares(type_of(pos.moved_piece(move))) & to_sq(move)
+ : pos.gives_check(move);
+ }
+
// perft() is our utility to verify move generation. All the leaf nodes up
// to the given depth are generated and counted, and the sum is returned.
template<bool Root>
extension = DEPTH_ZERO;
captureOrPromotion = pos.capture_or_promotion(move);
movedPiece = pos.moved_piece(move);
-
- givesCheck = type_of(move) == NORMAL && !pos.discovered_check_candidates()
- ? pos.check_squares(type_of(movedPiece)) & to_sq(move)
- : pos.gives_check(move);
+ givesCheck = gives_check(pos, move);
moveCountPruning = depth < 16 * ONE_PLY
&& moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY];
{
assert(is_ok(move));
- givesCheck = type_of(move) == NORMAL && !pos.discovered_check_candidates()
- ? pos.check_squares(type_of(pos.moved_piece(move))) & to_sq(move)
- : pos.gives_check(move);
+ givesCheck = gives_check(pos, move);
moveCount++;