+ Square to;
+ Bitboard b1, b2, dc1, dc2, pawnPushes, emptySquares;
+ Bitboard pawns = pos.pieces(PAWN, Us);
+ Bitboard pawnsOn7 = pawns & TRank7BB;
+ Bitboard enemyPieces = (Type == MV_CAPTURE ? target : pos.pieces_of_color(Them));
+
+ // Pre-calculate pawn pushes before changing emptySquares definition
+ if (Type != MV_CAPTURE)
+ {
+ emptySquares = (Type == MV_NON_CAPTURE ? target : pos.empty_squares());
+ pawnPushes = move_pawns<TDELTA_N>(pawns & ~TRank7BB) & emptySquares;
+ }
+
+ if (Type == MV_EVASION)
+ {
+ emptySquares &= target; // Only blocking squares
+ enemyPieces &= target; // Capture only the checker piece
+ }
+
+ // Promotions and underpromotions
+ if (pawnsOn7)
+ {
+ if (Type == MV_CAPTURE)
+ emptySquares = pos.empty_squares();
+
+ pawns &= ~TRank7BB;
+ mlist = generate_promotions<Us, Type, TDELTA_NE>(pos, mlist, pawnsOn7, enemyPieces);
+ mlist = generate_promotions<Us, Type, TDELTA_NW>(pos, mlist, pawnsOn7, enemyPieces);
+ mlist = generate_promotions<Us, Type, TDELTA_N >(pos, mlist, pawnsOn7, emptySquares);
+ }
+
+ // Standard captures
+ if (Type == MV_CAPTURE || Type == MV_EVASION)
+ {
+ mlist = generate_pawn_captures<Type, TDELTA_NE>(mlist, pawns, enemyPieces);
+ mlist = generate_pawn_captures<Type, TDELTA_NW>(mlist, pawns, enemyPieces);
+ }
+
+ // Single and double pawn pushes
+ if (Type != MV_CAPTURE)
+ {
+ b1 = pawnPushes & emptySquares;
+ b2 = move_pawns<TDELTA_N>(pawnPushes & TRank3BB) & emptySquares;
+
+ if (Type == MV_CHECK)
+ {
+ // Consider only pawn moves which give direct checks
+ b1 &= pos.attacks_from<PAWN>(ksq, Them);
+ b2 &= pos.attacks_from<PAWN>(ksq, Them);
+
+ // Add pawn moves which gives discovered check. This is possible only
+ // if the pawn is not on the same file as the enemy king, because we
+ // don't generate captures.
+ if (pawns & target) // For CHECK type target is dc bitboard
+ {
+ dc1 = move_pawns<TDELTA_N>(pawns & target & ~file_bb(ksq)) & emptySquares;
+ dc2 = move_pawns<TDELTA_N>(dc1 & TRank3BB) & emptySquares;
+
+ b1 |= dc1;
+ b2 |= dc2;
+ }
+ }
+ SERIALIZE_MOVES_D(b1, -TDELTA_N);
+ SERIALIZE_MOVES_D(b2, -TDELTA_N -TDELTA_N);