1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-11 19:49:14 +00:00

Fully convert move_is_check() internally

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2009-11-09 21:29:22 +01:00
parent 975d5e9c64
commit 2f01d67a92
2 changed files with 80 additions and 106 deletions

View file

@ -123,6 +123,10 @@ inline PieceType move_promotion_piece(Move m) {
return PieceType((int(m) >> 12) & 7); return PieceType((int(m) >> 12) & 7);
} }
inline int move_is_special(Move m) {
return m & (0x1F << 12);
}
inline int move_is_promotion(Move m) { inline int move_is_promotion(Move m) {
return m & (7 << 12); return m & (7 << 12);
} }

View file

@ -557,99 +557,74 @@ bool Position::move_is_check(Move m) const {
bool Position::move_is_check(Move m, const CheckInfo& ci) const { bool Position::move_is_check(Move m, const CheckInfo& ci) const {
Bitboard dcCandidates = ci.dcCandidates;
assert(is_ok()); assert(is_ok());
assert(move_is_ok(m)); assert(move_is_ok(m));
assert(dcCandidates == discovered_check_candidates(side_to_move())); assert(ci.dcCandidates == discovered_check_candidates(side_to_move()));
assert(color_of_piece_on(move_from(m)) == side_to_move());
assert(piece_on(ci.ksq) == piece_of_color_and_type(opposite_color(side_to_move()), KING));
Color us = side_to_move();
Color them = opposite_color(us);
Square from = move_from(m); Square from = move_from(m);
Square to = move_to(m); Square to = move_to(m);
Square ksq = king_square(them); PieceType pt = type_of_piece_on(from);
assert(color_of_piece_on(from) == us); // Direct check ?
assert(piece_on(ksq) == piece_of_color_and_type(them, KING)); if (bit_is_set(ci.checkSq[pt], to))
// Proceed according to the type of the moving piece
switch (type_of_piece_on(from))
{
case PAWN:
if (bit_is_set(attacks_from<PAWN>(ksq, them), to)) // Normal check?
return true; return true;
if ( dcCandidates // Discovered check? // Discovery check ?
&& bit_is_set(dcCandidates, from) if (ci.dcCandidates && bit_is_set(ci.dcCandidates, from))
&& (direction_between_squares(from, ksq) != direction_between_squares(to, ksq)))
return true;
if (move_is_promotion(m)) // Promotion with check?
{ {
// For pawn and king moves we need to verify also direction
if ( (pt != PAWN && pt != KING)
||(direction_between_squares(from, ci.ksq) != direction_between_squares(to, ci.ksq)))
return true;
}
// Can we skip the ugly special cases ?
if (!move_is_special(m))
return false;
Color us = side_to_move();
Bitboard b = occupied_squares(); Bitboard b = occupied_squares();
// Promotion with check ?
if (move_is_promotion(m))
{
clear_bit(&b, from); clear_bit(&b, from);
switch (move_promotion_piece(m)) switch (move_promotion_piece(m))
{ {
case KNIGHT: case KNIGHT:
return bit_is_set(attacks_from<KNIGHT>(to), ksq); return bit_is_set(attacks_from<KNIGHT>(to), ci.ksq);
case BISHOP: case BISHOP:
return bit_is_set(bishop_attacks_bb(to, b), ksq); return bit_is_set(bishop_attacks_bb(to, b), ci.ksq);
case ROOK: case ROOK:
return bit_is_set(rook_attacks_bb(to, b), ksq); return bit_is_set(rook_attacks_bb(to, b), ci.ksq);
case QUEEN: case QUEEN:
return bit_is_set(queen_attacks_bb(to, b), ksq); return bit_is_set(queen_attacks_bb(to, b), ci.ksq);
default: default:
assert(false); assert(false);
} }
} }
// En passant capture with check? We have already handled the case // En passant capture with check? We have already handled the case
// of direct checks and ordinary discovered check, the only case we // of direct checks and ordinary discovered check, the only case we
// need to handle is the unusual case of a discovered check through the // need to handle is the unusual case of a discovered check through the
// captured pawn. // captured pawn.
else if (move_is_ep(m)) if (move_is_ep(m))
{ {
Square capsq = make_square(square_file(to), square_rank(from)); Square capsq = make_square(square_file(to), square_rank(from));
Bitboard b = occupied_squares();
clear_bit(&b, from); clear_bit(&b, from);
clear_bit(&b, capsq); clear_bit(&b, capsq);
set_bit(&b, to); set_bit(&b, to);
return (rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us)) return (rook_attacks_bb(ci.ksq, b) & pieces(ROOK, QUEEN, us))
||(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, us)); ||(bishop_attacks_bb(ci.ksq, b) & pieces(BISHOP, QUEEN, us));
} }
return false;
// Test discovered check and normal check according to piece type // Castling with check ?
case KNIGHT:
return (dcCandidates && bit_is_set(dcCandidates, from))
|| bit_is_set(attacks_from<KNIGHT>(ksq), to);
case BISHOP:
return (dcCandidates && bit_is_set(dcCandidates, from))
|| (direction_is_diagonal(ksq, to) && bit_is_set(attacks_from<BISHOP>(ksq), to));
case ROOK:
return (dcCandidates && bit_is_set(dcCandidates, from))
|| (direction_is_straight(ksq, to) && bit_is_set(attacks_from<ROOK>(ksq), to));
case QUEEN:
// Discovered checks are impossible!
assert(!bit_is_set(dcCandidates, from));
return ( (direction_is_straight(ksq, to) && bit_is_set(attacks_from<ROOK>(ksq), to))
|| (direction_is_diagonal(ksq, to) && bit_is_set(attacks_from<BISHOP>(ksq), to)));
case KING:
// Discovered check?
if ( bit_is_set(dcCandidates, from)
&& (direction_between_squares(from, ksq) != direction_between_squares(to, ksq)))
return true;
// Castling with check?
if (move_is_castle(m)) if (move_is_castle(m))
{ {
Square kfrom, kto, rfrom, rto; Square kfrom, kto, rfrom, rto;
Bitboard b = occupied_squares();
kfrom = from; kfrom = from;
rfrom = to; rfrom = to;
@ -665,14 +640,9 @@ bool Position::move_is_check(Move m, const CheckInfo& ci) const {
clear_bit(&b, rfrom); clear_bit(&b, rfrom);
set_bit(&b, rto); set_bit(&b, rto);
set_bit(&b, kto); set_bit(&b, kto);
return bit_is_set(rook_attacks_bb(rto, b), ksq); return bit_is_set(rook_attacks_bb(rto, b), ci.ksq);
} }
return false;
default: // NO_PIECE_TYPE
break;
}
assert(false);
return false; return false;
} }