-namespace {
-
- int generate_pawn_captures(const PawnOffsets& ofs, const Position& pos, MoveStack* mlist) {
-
- Bitboard pawns = pos.pawns(ofs.us);
- Bitboard enemyPieces = pos.pieces_of_color(ofs.them);
- Square sq;
- int n = 0;
-
- // Captures in the a1-h8 (a8-h1 for black) direction
- Bitboard b1 = (ofs.forward_right)(pawns) & ~FileABB & enemyPieces;
-
- // Capturing promotions
- Bitboard b2 = b1 & ofs.Rank8BB;
- while (b2)
- {
- sq = pop_1st_bit(&b2);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, QUEEN);
- }
-
- // Capturing non-promotions
- b2 = b1 & ~ofs.Rank8BB;
- while (b2)
- {
- sq = pop_1st_bit(&b2);
- mlist[n++].move = make_move(sq - ofs.DELTA_NE, sq);
- }
-
- // Captures in the h1-a8 (h8-a1 for black) direction
- b1 = (ofs.forward_left)(pawns) & ~FileHBB & enemyPieces;
-
- // Capturing promotions
- b2 = b1 & ofs.Rank8BB;
- while (b2)
- {
- sq = pop_1st_bit(&b2);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, QUEEN);
- }
-
- // Capturing non-promotions
- b2 = b1 & ~ofs.Rank8BB;
- while (b2)
- {
- sq = pop_1st_bit(&b2);
- mlist[n++].move = make_move(sq - ofs.DELTA_NW, sq);
- }
-
- // Non-capturing promotions
- b1 = (ofs.forward)(pawns) & pos.empty_squares() & Rank8BB;
- while (b1)
- {
- sq = pop_1st_bit(&b1);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, QUEEN);
- }
-
- // En passant captures
- if (pos.ep_square() != SQ_NONE)
- {
- assert(ofs.us != WHITE || square_rank(pos.ep_square()) == RANK_6);
- assert(ofs.us != BLACK || square_rank(pos.ep_square()) == RANK_3);
-
- b1 = pawns & pos.pawn_attacks(ofs.them, pos.ep_square());
- assert(b1 != EmptyBoardBB);
-
- while (b1)
- {
- sq = pop_1st_bit(&b1);
- mlist[n++].move = make_ep_move(sq, pos.ep_square());
- }
- }
- return n;
- }
-
-
- int generate_pawn_noncaptures(const PawnOffsets& ofs, const Position& pos, MoveStack* mlist) {
-
- Bitboard pawns = pos.pawns(ofs.us);
- Bitboard enemyPieces = pos.pieces_of_color(ofs.them);
- Bitboard emptySquares = pos.empty_squares();
- Bitboard b1, b2;
- Square sq;
- int n = 0;
-
- // Underpromotion captures in the a1-h8 (a8-h1 for black) direction
- b1 = ofs.forward_right(pawns) & ~FileABB & enemyPieces & ofs.Rank8BB;
- while (b1)
- {
- sq = pop_1st_bit(&b1);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, ROOK);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, BISHOP);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, KNIGHT);
- }
-
- // Underpromotion captures in the h1-a8 (h8-a1 for black) direction
- b1 = ofs.forward_left(pawns) & ~FileHBB & enemyPieces & ofs.Rank8BB;
- while (b1)
- {
- sq = pop_1st_bit(&b1);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, ROOK);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, BISHOP);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, KNIGHT);
- }
-
- // Single pawn pushes
- b1 = ofs.forward(pawns) & emptySquares;
- b2 = b1 & ofs.Rank8BB;
- while (b2)
- {
- sq = pop_1st_bit(&b2);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, ROOK);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, BISHOP);
- mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, KNIGHT);
- }
- b2 = b1 & ~ofs.Rank8BB;
- while (b2)
- {
- sq = pop_1st_bit(&b2);
- mlist[n++].move = make_move(sq - ofs.DELTA_N, sq);
- }
-
- // Double pawn pushes
- b2 = (ofs.forward(b1 & ofs.Rank3BB)) & emptySquares;
- while (b2)
- {
- sq = pop_1st_bit(&b2);
- mlist[n++].move = make_move(sq - ofs.DELTA_N - ofs.DELTA_N, sq);
- }
- return n;
- }
-
-
- int generate_castle_moves(const Position &pos, MoveStack *mlist, Color us) {
-
- int n = 0;
-
- if (pos.can_castle(us))
- {
- Color them = opposite_color(us);
- Square ksq = pos.king_square(us);
-
- assert(pos.piece_on(ksq) == king_of_color(us));
-
- if (pos.can_castle_kingside(us))
- {
- Square rsq = pos.initial_kr_square(us);
- Square g1 = relative_square(us, SQ_G1);
- Square f1 = relative_square(us, SQ_F1);
- Square s;
- bool illegal = false;
-
- assert(pos.piece_on(rsq) == rook_of_color(us));
-
- for (s = Min(ksq, g1); s <= Max(ksq, g1); s++)
- if ( (s != ksq && s != rsq && pos.square_is_occupied(s))
- || pos.square_is_attacked(s, them))
- illegal = true;
-
- for (s = Min(rsq, f1); s <= Max(rsq, f1); s++)
- if (s != ksq && s != rsq && pos.square_is_occupied(s))
- illegal = true;