Detect pinned pieces code This post is a follow up of this one: C++ vs Java Engine move generation performance

My goal here is to improve the performance of my move generator, which finishes perft (start_pos, 6) in 8.5 secs.
That's too slow for C++ code (the same Java code runs in 11 secs).

The bottleneck is the check for validity, which in turn tests if the king is in check. This is running for every move,
and given that most moves are legal, it's a total waste of time. As pointed out by Student T, we should restricted
this test for king in check, pinned pieces and en passant captures.

The king in check or walking to check cases are easy, this post is about pinned pieces  code.
So, the  cpwiki code goes like this:

pinned = 0;
pinner = xrayRookAttacks(occupiedBB, ownPieces, squareOfKing) &amp; opRQ;
while ( pinner ) {
   int sq  = bitScanForward(pinner);
   pinned |= obstructed(sq, squareOfKing) &amp; ownPieces;
   pinner &amp;= pinner - 1;
}

pinner = xrayBishopAttacks(occupiedBB, ownPieces, squareOfKing) &amp; opBQ;
while ( pinner ) {
   int sq  = bitScanForward(pinner);
   pinned |= obstructed(sq, squareOfKing) &amp; ownPieces;
   pinner &amp;= pinner - 1;
}


And here's the code for xrayRookAttacks():

U64 xrayRookAttacks(U64 occ, U64 blockers, enumSquare rookSq) {
   U64 attacks = rookAttacks(occ, rookSq);
   blockers &amp;= attacks;
   return attacks ^ rookAttacks(occ ^ blockers, rookSq);
}


Questions:

a) What is obstructed() doing?

b) After getting the pinned set, how exactly do I use it to test for a valid move?

Thank you all!
A: Let's use bishop for our example. xrayBishopAttacks works if we have the following position:

but it doesn't work if you have this:



The f3 knight is not pinned because there is something else behind it. obstructed takes this into consideration.

B: Once you get the pinned pieces, you can just do XAND to check if the piece you want to move is pinned. If it's pinned, you can't move it.

************** EDIT **************

You won't find obstructed() because it's just a pseudocode function. You're expected to implement pinning in obstructed() yourself.

Forget the pseudocode, you should study Stockfish. Goto https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp

Find bool Position::legal(Move m) const

Check the following:

// 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) &amp; from)
    ||  aligned(from, to_sq(m), square&lt;KING&gt;(us));


This is exactly what I'm talking about.