-
- int generate_white_pawn_captures(const Position&, MoveStack*);
- int generate_black_pawn_captures(const Position&, MoveStack*);
- int generate_white_pawn_noncaptures(const Position&, MoveStack*);
- int generate_black_pawn_noncaptures(const Position&, MoveStack*);
- int generate_knight_moves(const Position&, MoveStack*, Color side, Bitboard t);
- int generate_bishop_moves(const Position&, MoveStack*, Color side, Bitboard t);
- int generate_rook_moves(const Position&, MoveStack*, Color side, Bitboard t);
- int generate_queen_moves(const Position&, MoveStack*, Color side, Bitboard t);
- int generate_king_moves(const Position&, MoveStack*, Square from, Bitboard t);
- int generate_castle_moves(const Position&, MoveStack*, Color us);
+
+ enum CastlingSide {
+ KING_SIDE,
+ QUEEN_SIDE
+ };
+
+ enum MoveType {
+ CAPTURE,
+ NON_CAPTURE,
+ CHECK,
+ EVASION
+ };
+
+ template<CastlingSide Side>
+ MoveStack* generate_castle_moves(const Position&, MoveStack*);
+
+ template<Color Us, MoveType Type>
+ MoveStack* generate_pawn_moves(const Position&, MoveStack*, Bitboard, Square);
+
+ template<PieceType Piece>
+ inline MoveStack* generate_discovered_checks(const Position& pos, MoveStack* mlist, Square from) {
+
+ assert(Piece != QUEEN);
+
+ Bitboard b = pos.attacks_from<Piece>(from) & pos.empty_squares();
+ if (Piece == KING)
+ {
+ Square ksq = pos.king_square(opposite_color(pos.side_to_move()));
+ b &= ~QueenPseudoAttacks[ksq];
+ }
+ SERIALIZE_MOVES(b);
+ return mlist;
+ }
+
+ template<PieceType Piece>
+ inline MoveStack* generate_direct_checks(const Position& pos, MoveStack* mlist, Color us,
+ Bitboard dc, Square ksq) {
+ assert(Piece != KING);
+
+ Bitboard checkSqs, b;
+ Square from;
+ const Square* ptr = pos.piece_list_begin(us, Piece);
+
+ if ((from = *ptr++) == SQ_NONE)
+ return mlist;
+
+ checkSqs = pos.attacks_from<Piece>(ksq) & pos.empty_squares();
+
+ do
+ {
+ if ( (Piece == QUEEN && !(QueenPseudoAttacks[from] & checkSqs))
+ || (Piece == ROOK && !(RookPseudoAttacks[from] & checkSqs))
+ || (Piece == BISHOP && !(BishopPseudoAttacks[from] & checkSqs)))
+ continue;
+
+ if (dc && bit_is_set(dc, from))
+ continue;
+
+ b = pos.attacks_from<Piece>(from) & checkSqs;
+ SERIALIZE_MOVES(b);
+
+ } while ((from = *ptr++) != SQ_NONE);
+
+ return mlist;
+ }
+
+ template<>
+ inline MoveStack* generate_direct_checks<PAWN>(const Position& p, MoveStack* m, Color us, Bitboard dc, Square ksq) {
+
+ return (us == WHITE ? generate_pawn_moves<WHITE, CHECK>(p, m, dc, ksq)
+ : generate_pawn_moves<BLACK, CHECK>(p, m, dc, ksq));
+ }
+
+ template<PieceType Piece, MoveType Type>
+ inline MoveStack* generate_piece_moves(const Position& p, MoveStack* m, Color us, Bitboard t) {
+
+ assert(Piece == PAWN);
+ assert(Type == CAPTURE || Type == NON_CAPTURE || Type == EVASION);
+
+ return (us == WHITE ? generate_pawn_moves<WHITE, Type>(p, m, t, SQ_NONE)
+ : generate_pawn_moves<BLACK, Type>(p, m, t, SQ_NONE));
+ }
+
+ template<PieceType Piece>
+ inline MoveStack* generate_piece_moves(const Position& pos, MoveStack* mlist, Color us, Bitboard target) {
+
+ Bitboard b;
+ Square from;
+ const Square* ptr = pos.piece_list_begin(us, Piece);
+
+ if (*ptr != SQ_NONE)
+ {
+ do {
+ from = *ptr;
+ b = pos.attacks_from<Piece>(from) & target;
+ SERIALIZE_MOVES(b);
+ } while (*++ptr != SQ_NONE);
+ }
+ return mlist;
+ }
+
+ template<>
+ inline MoveStack* generate_piece_moves<KING>(const Position& pos, MoveStack* mlist, Color us, Bitboard target) {
+
+ Bitboard b;
+ Square from = pos.king_square(us);
+
+ b = pos.attacks_from<KING>(from) & target;
+ SERIALIZE_MOVES(b);
+ return mlist;
+ }