void MoveList::GenCheckEvasions(const Position& pos) { Clear(); COLOR side = pos.Side(); COLOR opp = side ^ 1; U64 freeOrOpp = ~pos.BitsAll(side); U64 occ = pos.BitsAll(); U64 x, y; FLD from, to; PIECE piece, captured; FLD K = pos.King(side); U64 attackers = pos.GetAttacks(K, opp, occ); U64 mask = attackers; while (attackers) { from = PopLSB(attackers); mask |= BB_BETWEEN[from][K]; } int fwd = -8 + 16 * side; int second = 6 - 5 * side; int seventh = 1 + 5 * side; piece = PW | side; x = pos.Bits(piece); while (x) { from = PopLSB(x); int row = Row(from); to = static_cast<FLD>(from + fwd); if (!pos[to]) { if (row == second) { if (BB_SINGLE[to] & mask) Add(from, to, piece); to = static_cast<FLD>(to + fwd); if (!pos[to]) { if (BB_SINGLE[to] & mask) Add(from, to, piece); } } else if (row == seventh) { if (BB_SINGLE[to] & mask) { Add(from, to, piece, NOPIECE, QW | side); Add(from, to, piece, NOPIECE, RW | side); Add(from, to, piece, NOPIECE, BW | side); Add(from, to, piece, NOPIECE, NW | side); } } else { if (BB_SINGLE[to] & mask) Add(from, to, piece); } } y = BB_PAWN_ATTACKS[from][side] & pos.BitsAll(opp) & mask; while (y) { to = PopLSB(y); captured = pos[to]; if (row == seventh) { Add(from, to, piece, captured, QW | side); Add(from, to, piece, captured, RW | side); Add(from, to, piece, captured, BW | side); Add(from, to, piece, captured, NW | side); } else Add(from, to, piece, captured); } } to = pos.Ep(); if (to != NF) { y = BB_PAWN_ATTACKS[to][opp] & pos.Bits(PW | side); while (y) { from = PopLSB(y); Add(from, to, piece, PW | opp); } } piece = NW | side; x = pos.Bits(piece); while (x) { from = PopLSB(x); y = BB_KNIGHT_ATTACKS[from] & freeOrOpp & mask; while (y) { to = PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = BW | side; x = pos.Bits(piece); while (x) { from = PopLSB(x); y = BishopAttacks(from, occ) & freeOrOpp & mask; while (y) { to = PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = RW | side; x = pos.Bits(piece); while (x) { from = PopLSB(x); y = RookAttacks(from, occ) & freeOrOpp & mask; while (y) { to = PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = QW | side; x = pos.Bits(piece); while (x) { from = PopLSB(x); y = QueenAttacks(from, occ) & freeOrOpp & mask; while (y) { to = PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = KW | side; x = pos.Bits(piece); while (x) { from = PopLSB(x); y = BB_KING_ATTACKS[from] & freeOrOpp; while (y) { to = PopLSB(y); if (!pos.IsAttacked(to, opp)) { captured = pos[to]; Add(from, to, piece, captured); } } } }
void MoveList::GenCheckEvasions(const Position& pos) { Clear(); COLOR side = pos.Side(); COLOR opp = side ^ 1; U64 freeOrOpp = ~pos.BitsAll(side); U64 occ = pos.BitsAll(); U64 x, y; FLD from, to; PIECE piece, captured; FLD K = pos.King(side); U64 attackers = pos.GetAttacks(K, opp, occ); U64 mask = attackers; while (attackers) { from = Bitboard::PopLSB(attackers); mask |= Bitboard::Between(from, K); } int fwd = -8 + 16 * side; int second = 6 - 5 * side; int seventh = 1 + 5 * side; piece = PW | side; x = pos.Bits(piece); while (x) { from = Bitboard::PopLSB(x); int row = Row(from); to = static_cast<FLD>(from + fwd); if (!pos[to]) { if (row == second) { if (Bitboard::Single(to) & mask) Add(from, to, piece); to = static_cast<FLD>(to + fwd); if (!pos[to]) { if (Bitboard::Single(to) & mask) Add(from, to, piece); } } else if (row == seventh) { if (Bitboard::Single(to) & mask) { Add(from, to, piece, NOPIECE, QW | side); Add(from, to, piece, NOPIECE, RW | side); Add(from, to, piece, NOPIECE, BW | side); Add(from, to, piece, NOPIECE, NW | side); } } else { if (Bitboard::Single(to) & mask) Add(from, to, piece); } } y = Bitboard::PawnAttacks(from, side) & pos.BitsAll(opp) & mask; while (y) { to = Bitboard::PopLSB(y); captured = pos[to]; if (row == seventh) { Add(from, to, piece, captured, QW | side); Add(from, to, piece, captured, RW | side); Add(from, to, piece, captured, BW | side); Add(from, to, piece, captured, NW | side); } else Add(from, to, piece, captured); } } to = pos.Ep(); if (to != NF) { y = Bitboard::PawnAttacks(to, opp) & pos.Bits(PW | side); while (y) { from = Bitboard::PopLSB(y); Add(from, to, piece, PW | opp); } } piece = NW | side; x = pos.Bits(piece); while (x) { from = Bitboard::PopLSB(x); y = Bitboard::KnightAttacks(from) & freeOrOpp & mask; while (y) { to = Bitboard::PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = BW | side; x = pos.Bits(piece); while (x) { from = Bitboard::PopLSB(x); y = Bitboard::BishopAttacks(from, occ) & freeOrOpp & mask; while (y) { to = Bitboard::PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = RW | side; x = pos.Bits(piece); while (x) { from = Bitboard::PopLSB(x); y = Bitboard::RookAttacks(from, occ) & freeOrOpp & mask; while (y) { to = Bitboard::PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = QW | side; x = pos.Bits(piece); while (x) { from = Bitboard::PopLSB(x); y = Bitboard::QueenAttacks(from, occ) & freeOrOpp & mask; while (y) { to = Bitboard::PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } piece = KW | side; x = pos.Bits(piece); while (x) { from = Bitboard::PopLSB(x); y = Bitboard::KingAttacks(from) & freeOrOpp; while (y) { to = Bitboard::PopLSB(y); if (!pos.IsAttacked(to, opp)) { captured = pos[to]; Add(from, to, piece, captured); } } } }