Esempio n. 1
0
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);
      }
    }
  }
}
Esempio n. 2
0
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);
			}
		}
	}
}