Bitboards imply to determine pawn push target squares, or equivalently their stop squares set-wise, while pawn pushes of a single pawn are the domain of mailbox-approaches. To generate the single-step targets for all pawns requires vertical shift by one rank and intersection with the set of empty squares. The resulting set might be shifted one more time for the double pushes by further intersection with empty squares on the fourth (white) or fifth (black) double push target ranks. Since double pushing triggers determination of en passant target square, it makes sense to serialize both sets separately for different move encoding.
One may rely on the generalized shift for one color parametrized pawn push routine. Since pawns don't occur on the first or eighth rank, one may either safe the wrap-ands ...
enum{ white, black };
U64 singlePushTargets(U64 pawns, U64 empty, int color){return rotateLeft( pawns, 8-(color <<4))& empty;;}
... or make the "white" north-shift unconditionally but to conditionally shift back south two ranks by color*16:
U64 singlePushTargets(U64 pawns, U64 empty, int color){return((pawns <<8)>>(color <<4))& empty;}
Table of Contents
Push per Side
Keeping different but most efficient code for both white and black pawns. The code snippets rely on shifting bitboards, specially by one step only.Pawns able to Push
To get the set of source squares of pawns able to push is about intersection of pawns with the shifted empty squares in opposite direction:and similar for black.
Generalized Push
One may rely on the generalized shift for one color parametrized pawn push routine. Since pawns don't occur on the first or eighth rank, one may either safe the wrap-ands ...... or make the "white" north-shift unconditionally but to conditionally shift back south two ranks by color*16:
Forum Posts
References
What links here?
Up one Level