U64 QMagicHash::FindMagic(int sq, bool IsBishop){ QBitBoard mask(IsBishop ? BishopMask(sq) : RookMask(sq)); const int n = mask.PopCount(); const int size = 1 << n; U64 a[size]; U64 used[size]; U64 magic; const int m = IsBishop ? BBits[sq] : RBits[sq]; int j, k; bool fail = false; for(int i=0; i<size; i++) a[i] = IsBishop ? BishopAttacks(sq, m_bishop_moves[sq][i]) : RookAttacks(sq, m_rook_moves[sq][i]); for(k = 0; k<1e7; k++){ magic = RndmU64FewBits(); QBitBoard bb((mask.Bits() * magic) & 0xFF00000000000000ULL); if(bb.PopCount() < 6) continue; for(int i = 0; i < size; i++) used[i] = 0ULL; for(int i = 0, fail = false; !fail && i < size; i++) { j = IsBishop ? Transform(m_bishop_moves[sq][i],magic,m) : Transform(m_rook_moves[sq][i],magic,m); if(used[j] == 0ULL) used[j] = a[i]; else if(used[j] != a[i]) fail = true; } if(!fail) return magic; } cout << "***Failed***" << endl; return 0ULL; }
FLD Position::FindLeastAttacker(FLD to, COLOR side, const U64& mask) const { U64 x, occ = BitsAll(); // Pawn? x = BB_PAWN_ATTACKS[to][side ^ 1] & Bits(PW | side) & mask; if (x) return LSB(x); // Knight? x = BB_KNIGHT_ATTACKS[to] & Bits(NW | side) & mask; if (x) return LSB(x); // Bishop? x = BishopAttacks(to, occ) & Bits(BW | side) & mask; if (x) return LSB(x); // Rook? x = RookAttacks(to, occ) & Bits(RW | side) & mask; if (x) return LSB(x); // Queen? x = QueenAttacks(to, occ) & Bits(QW | side) & mask; if (x) return LSB(x); // King? x = BB_KING_ATTACKS[to] & Bits(KW | side) & mask; if (x) return LSB(x); return NF; }
U64 Position::GetAttacks(FLD to, COLOR side, U64 occ) const { U64 att = 0; att |= BB_PAWN_ATTACKS[to][side ^ 1] & Bits(PW | side); att |= BB_KNIGHT_ATTACKS[to] & Bits(NW | side); att |= BB_KING_ATTACKS[to] & Bits(KW | side); att |= BishopAttacks(to, occ) & (Bits(BW | side) | Bits(QW | side)); att |= RookAttacks(to, occ) & (Bits(RW | side) | Bits(QW | side)); return att; }
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::GenAllMoves(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; 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) { Add(from, to, piece); to = static_cast<FLD>(to + fwd); if (!pos[to]) Add(from, to, piece); } else if (row == seventh) { 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 Add(from, to, piece); } y = BB_PAWN_ATTACKS[from][side] & pos.BitsAll(opp); 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; 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; 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; 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; 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); captured = pos[to]; Add(from, to, piece, captured); } if (from == E1 && side == WHITE) { if (!pos[F1] && !pos[G1] && (pos.Castlings() & WHITE_O_O)) if (!pos.IsAttacked(E1, BLACK) && !pos.IsAttacked(F1, BLACK) && !pos.IsAttacked(G1, BLACK)) Add(E1, G1, KW); if (!pos[D1] && !pos[C1] && !pos[B1] && (pos.Castlings() & WHITE_O_O_O)) if (!pos.IsAttacked(E1, BLACK) && !pos.IsAttacked(D1, BLACK) && !pos.IsAttacked(C1, BLACK)) Add(E1, C1, KW); } else if (from == E8 && side == BLACK) { if (!pos[F8] && !pos[G8] && (pos.Castlings() & BLACK_O_O)) if (!pos.IsAttacked(E8, WHITE) && !pos.IsAttacked(F8, WHITE) && !pos.IsAttacked(G8, WHITE)) Add(E8, G8, KB); if (!pos[D8] && !pos[C8] && !pos[B8] && (pos.Castlings() & BLACK_O_O_O)) if (!pos.IsAttacked(E8, WHITE) && !pos.IsAttacked(D8, WHITE) && !pos.IsAttacked(C8, WHITE)) Add(E8, C8, KB); } } }
void MoveList::GenCaptures(const Position& pos, bool genChecks) { Clear(); COLOR side = pos.Side(); COLOR opp = side ^ 1; U64 targets = pos.BitsAll(opp); U64 occ = pos.BitsAll(); U64 free = ~occ; U64 checksN = 0, checksB = 0, checksR = 0, checksQ = 0; FLD Kopp = pos.King(opp); if (genChecks) { checksN = BB_KNIGHT_ATTACKS[Kopp] & free; checksB = BishopAttacks(Kopp, occ) & free; checksR = RookAttacks(Kopp, occ) & free; checksQ = checksB | checksR; } U64 x, y; FLD from, to; PIECE piece, captured; int fwd = -8 + 16 * 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 == seventh) { 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); } } y = BB_PAWN_ATTACKS[from][side] & pos.BitsAll(opp); 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] & (targets | checksN); 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) & (targets | checksB); 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) & (targets | checksR); 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) & (targets | checksQ); 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] & targets; while (y) { to = PopLSB(y); captured = pos[to]; Add(from, to, piece, captured); } } }