Chess Engine: Generate a Bitboard of Pinned Pieces I'm currently working on a chess engine and have a pseudo-legal move generator working. I'm looking for a way to efficiently generate a bitboard of pinned pieces, so I could skip them when generating legal moves. How would one go about doing this, given 12 bitboards for each piece, and a bitboard called UNSAFE with all the squares the opponent is threatening?
This task is nontrivial and cannot be obtained easily or setwise from the available bitboards.

The following solution is an example for how such a task might be done for a generic slider - only obvious substitutions are necessary to convert this code to be usable for bishops, rooks and queens.

First, identify the set of possible pinning pieces by calculating sliding attacks from the king square, using the opposite side as the set of occupied squares.

BitBoard bb_pinners = slider_moves(king_square, bb_other_side) &amp; bb_other_side;


All bitboard engines should have some function similar to bishop_moves or rook_moves, which uses magic bitboards, PEXT or Koch-Stone to generate sliding moves from a square, given a bitboard of occupied squares as blockers to the slider. 

To determine the set of pinned pieces from the set of pinners, it is necessary to iterate through the set of possible pinners (this is why pinned pieces cannot be calculated setwise).

For each pinner, we consider the set of bits between the pinner square and the king square (using the utility function between), determine if there is only one bit set, and if so, add that bit to the set of pinned pieces.

BitBoard bb_pinned = 0;
while(bb_pinners) {
    Square sq = pop_bit(bb_pinners);
    BitBoard bb_possible_pinned = between(sq, king_square) &amp; bb_own_side;
    if(only_one_bit(bb_possible_pinned)) {
        bb_pinned |= bb_possible_pinned;
    }
}


Here, pop_bit finds the index of and removes the least significant bit of bb_pinners.

Stockfish implements a similar strategy in slider_blockers to determine possibly pinned pieces.

It is also worth mentioning that even with a set of these blockers, this does not mean that they may be excluded from legal move generation because if the pinned piece is a slider itself of the correct type, it may still have legal moves despite being pinned, under the above algorithm's definition.