|
| 1 | +#include <bitbishop/attacks/bishop_attacks.hpp> |
| 2 | +#include <bitbishop/attacks/queen_attacks.hpp> |
| 3 | +#include <bitbishop/attacks/rook_attacks.hpp> |
| 4 | +#include <bitbishop/bitboard.hpp> |
| 5 | +#include <bitbishop/board.hpp> |
| 6 | +#include <bitbishop/color.hpp> |
| 7 | +#include <bitbishop/lookups/king_attacks.hpp> |
| 8 | +#include <bitbishop/lookups/knight_attacks.hpp> |
| 9 | +#include <bitbishop/lookups/pawn_attacks.hpp> |
| 10 | + |
| 11 | +/** |
| 12 | + * @brief Computes the set of squares attacked by all pieces of a given side. |
| 13 | + * |
| 14 | + * Generates a bitboard containing every square currently attacked by the |
| 15 | + * specified color, based on the current board occupancy. This includes |
| 16 | + * attacks from the king, knights, pawns, and all sliding pieces (rooks, |
| 17 | + * bishops, queens). |
| 18 | + * |
| 19 | + * The result represents geometric attacks only and does not account for |
| 20 | + * move legality, pins, discovered checks, or whether the attacking pieces |
| 21 | + * themselves are defended. |
| 22 | + * |
| 23 | + * This function is primarily used for king safety evaluation, including |
| 24 | + * legal king move generation and castling validation. |
| 25 | + * |
| 26 | + * @param board The current board position. |
| 27 | + * @param enemy The side whose attacks are to be generated. |
| 28 | + * @return A bitboard of all squares attacked by the given side. |
| 29 | + */ |
| 30 | +Bitboard generate_attacks(const Board& board, Color enemy) { |
| 31 | + Bitboard attacks = Bitboard::Zeros(); |
| 32 | + |
| 33 | + Bitboard occupied = board.occupied(); |
| 34 | + |
| 35 | + Bitboard king = board.king(enemy); |
| 36 | + if (king.any()) { |
| 37 | + Square sq = king.pop_lsb().value(); |
| 38 | + attacks |= Lookups::KING_ATTACKS[sq.value()]; |
| 39 | + } |
| 40 | + |
| 41 | + Bitboard knights = board.knights(enemy); |
| 42 | + while (knights) { |
| 43 | + Square sq = knights.pop_lsb().value(); |
| 44 | + attacks |= Lookups::KNIGHT_ATTACKS[sq.value()]; |
| 45 | + } |
| 46 | + |
| 47 | + Bitboard pawns = board.pawns(enemy); |
| 48 | + if (enemy == Color::WHITE) { |
| 49 | + while (pawns) { |
| 50 | + Square sq = pawns.pop_lsb().value(); |
| 51 | + attacks |= Lookups::WHITE_PAWN_ATTACKS[sq.value()]; |
| 52 | + } |
| 53 | + } else { |
| 54 | + while (pawns) { |
| 55 | + Square sq = pawns.pop_lsb().value(); |
| 56 | + attacks |= Lookups::BLACK_PAWN_ATTACKS[sq.value()]; |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + Bitboard rooks = board.rooks(enemy); |
| 61 | + while (rooks) { |
| 62 | + Square sq = rooks.pop_lsb().value(); |
| 63 | + attacks |= rook_attacks(sq, occupied); |
| 64 | + } |
| 65 | + |
| 66 | + Bitboard bishops = board.bishops(enemy); |
| 67 | + while (bishops) { |
| 68 | + Square sq = bishops.pop_lsb().value(); |
| 69 | + attacks |= bishop_attacks(sq, occupied); |
| 70 | + } |
| 71 | + |
| 72 | + Bitboard queens = board.queens(enemy); |
| 73 | + while (queens) { |
| 74 | + Square sq = queens.pop_lsb().value(); |
| 75 | + attacks |= queen_attacks(sq, occupied); |
| 76 | + } |
| 77 | + |
| 78 | + return attacks; |
| 79 | +} |
0 commit comments