- template<Color Us, MoveType Type>
- MoveStack* generate_pawn_moves(const Position& pos, MoveStack* mlist, Bitboard target, Square ksq) {
-
- // Calculate our parametrized parameters at compile time
- const Color Them = (Us == WHITE ? BLACK : WHITE);
- const Bitboard TRank8BB = (Us == WHITE ? Rank8BB : Rank1BB);
- const Bitboard TRank7BB = (Us == WHITE ? Rank7BB : Rank2BB);
- const Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
- const SquareDelta TDELTA_N = (Us == WHITE ? DELTA_N : DELTA_S);
-
- Square to;
- Bitboard b1, b2, enemyPieces, emptySquares;
- Bitboard pawns = pos.pieces(PAWN, Us);
-
- // Standard captures and capturing promotions and underpromotions
- if (Type == CAPTURE || Type == EVASION || (pawns & TRank7BB))
- {
- enemyPieces = (Type == CAPTURE ? target : pos.pieces_of_color(opposite_color(Us)));
-
- if (Type == EVASION)
- enemyPieces &= target; // Capture only the checker piece
-
- mlist = generate_pawn_captures<Us, Type, DELTA_NE>(mlist, pawns, enemyPieces);
- mlist = generate_pawn_captures<Us, Type, DELTA_NW>(mlist, pawns, enemyPieces);
- }
-
- // Non-capturing promotions and underpromotions
- if (pawns & TRank7BB)
- {
- b1 = move_pawns<Us, DELTA_N>(pawns) & TRank8BB & pos.empty_squares();
-
- if (Type == EVASION)
- b1 &= target; // Only blocking promotion pushes
-
- while (b1)
- {
- to = pop_1st_bit(&b1);
-
- if (Type == CAPTURE || Type == EVASION)
- (*mlist++).move = make_promotion_move(to - TDELTA_N, to, QUEEN);
-
- if (Type == NON_CAPTURE || Type == EVASION)
- {
- (*mlist++).move = make_promotion_move(to - TDELTA_N, to, ROOK);
- (*mlist++).move = make_promotion_move(to - TDELTA_N, to, BISHOP);
- (*mlist++).move = make_promotion_move(to - TDELTA_N, to, KNIGHT);
- }
-
- // This is the only possible under promotion that can give a check
- // not already included in the queen-promotion.
- if (Type == CHECK && bit_is_set(pos.attacks_from<KNIGHT>(to), pos.king_square(Them)))
- (*mlist++).move = make_promotion_move(to - TDELTA_N, to, KNIGHT);
- }
- }