Exemple #1
0
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);
    }
  }
}