generateCaptures method

void generateCaptures(
  1. List<int> out
)

Append pseudo-legal captures (and all promotions) — the quiescence set.

Implementation

void generateCaptures(List<int> out) {
  final us = turn, them = turn ^ 1;
  final enemyOcc = occ[them];

  // Pawns: capturing promotions + capturing pushes + en passant, and quiet
  // promotions (a promotion is a big material swing worth resolving).
  final promoRank = us == white ? 7 : 0;
  final fwd = us == white ? 8 : -8;
  final empty = ~occAll;
  var pbb = pieces[us][pawn];
  while (pbb != 0) {
    final from = lsb(pbb);
    pbb &= pbb - 1;
    // Quiet promotion push.
    final one = from + fwd;
    if (one >= 0 && one < 64 && (empty & (1 << one)) != 0 &&
        (one >> 3) == promoRank) {
      _addPromotions(out, from, one, false);
    }
    var caps = pawnAttacks[us][from] & enemyOcc;
    while (caps != 0) {
      final to = lsb(caps);
      caps &= caps - 1;
      if ((to >> 3) == promoRank) {
        _addPromotions(out, from, to, true);
      } else {
        out.add(encodeMove(from, to, flagCapture));
      }
    }
    if (epSquare >= 0 && (pawnAttacks[us][from] & (1 << epSquare)) != 0) {
      out.add(encodeMove(from, epSquare, flagEpCapture));
    }
  }

  void emit(int bb, int Function(int) attacks) {
    while (bb != 0) {
      final from = lsb(bb);
      bb &= bb - 1;
      var t = attacks(from) & enemyOcc;
      while (t != 0) {
        final to = lsb(t);
        t &= t - 1;
        out.add(encodeMove(from, to, flagCapture));
      }
    }
  }

  emit(pieces[us][knight], (f) => knightAttacks[f]);
  emit(pieces[us][king], (f) => kingAttacks[f]);
  emit(pieces[us][bishop], (f) => bishopAttacks(f, occAll));
  emit(pieces[us][rook], (f) => rookAttacks(f, occAll));
  emit(pieces[us][queen], (f) => queenAttacks(f, occAll));
}