/// Position::set_state() computes the hash keys of the position, and other
/// data that once computed is updated incrementally as moves are made.
-/// The function is only used when a new position is set up, and to verify
-/// the correctness of the StateInfo data when running in debug mode.
+/// The function is only used when a new position is set up
void Position::set_state() const {
return true;
// Is there a discovered check?
- if ( (blockers_for_king(~sideToMove) & from)
- && !aligned(from, to, square<KING>(~sideToMove)))
- return true;
+ if (blockers_for_king(~sideToMove) & from)
+ return !aligned(from, to, square<KING>(~sideToMove))
+ || type_of(m) == CASTLING;
switch (type_of(m))
{
default: //CASTLING
{
// Castling is encoded as 'king captures the rook'
- Square ksq = square<KING>(~sideToMove);
Square rto = relative_square(sideToMove, to > from ? SQ_F1 : SQ_D1);
- return (attacks_bb<ROOK>(rto) & ksq)
- && (attacks_bb<ROOK>(rto, pieces() ^ from ^ to) & ksq);
+ return check_squares(ROOK) & rto;
}
}
}
/// SEE value of move is greater or equal to the given threshold. We'll use an
/// algorithm similar to alpha-beta pruning with a null window.
-bool Position::see_ge(Move m, Value threshold) const {
+bool Position::see_ge(Move m, Bitboard& occupied, Value threshold) const {
assert(is_ok(m));
return true;
assert(color_of(piece_on(from)) == sideToMove);
- Bitboard occupied = pieces() ^ from ^ to;
+ occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
Color stm = sideToMove;
Bitboard attackers = attackers_to(to, occupied);
Bitboard stmAttackers, bb;
// the bitboard 'attackers' any X-ray attackers behind it.
if ((bb = stmAttackers & pieces(PAWN)))
{
+ occupied ^= least_significant_square_bb(bb);
if ((swap = PawnValueMg - swap) < res)
break;
- occupied ^= least_significant_square_bb(bb);
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(KNIGHT)))
{
+ occupied ^= least_significant_square_bb(bb);
if ((swap = KnightValueMg - swap) < res)
break;
-
- occupied ^= least_significant_square_bb(bb);
}
else if ((bb = stmAttackers & pieces(BISHOP)))
{
+ occupied ^= least_significant_square_bb(bb);
if ((swap = BishopValueMg - swap) < res)
break;
- occupied ^= least_significant_square_bb(bb);
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(ROOK)))
{
+ occupied ^= least_significant_square_bb(bb);
if ((swap = RookValueMg - swap) < res)
break;
- occupied ^= least_significant_square_bb(bb);
attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
}
else if ((bb = stmAttackers & pieces(QUEEN)))
{
+ occupied ^= least_significant_square_bb(bb);
if ((swap = QueenValueMg - swap) < res)
break;
- occupied ^= least_significant_square_bb(bb);
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
}
return bool(res);
}
+bool Position::see_ge(Move m, Value threshold) const {
+ Bitboard occupied;
+ return see_ge(m, occupied, threshold);
+}
+
/// Position::is_draw() tests whether the position is drawn by 50-move rule
/// or by repetition. It does not detect stalemates.