queen attacks through rooks and bishops too

Discussion of chess software programming and technical issues.

Moderator: Ras

AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: queen attacks through rooks and bishops too

Post by AlvaroBegue »

lech wrote:

Code: Select all

// Find attacked squares, including x-ray attacks for bishops, rooks and queen
        if (Piece == ROOK)
            b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
        else if (Piece == BISHOP)
            b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
        else if (Piece == KNIGHT)
            b = pos.attacks_from<Piece>(s);
        else if (Piece==QUEEN)
           b= queen_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, BISHOP, Us));
        else
            assert(false);
If I were to try something like this, I would make bishops "transparent" only on diagonals and rooks only on rows and columns. This seems like a good thing to try, especially when evaluating king safety.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: queen attacks through rooks and bishops too

Post by mcostalba »

AlvaroBegue wrote: If I were to try something like this, I would make bishops "transparent" only on diagonals and rooks only on rows and columns. This seems like a good thing to try, especially when evaluating king safety.
Care to post the code ? I don't think I have understood what you mean.

Thanks.
AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: queen attacks through rooks and bishops too

Post by AlvaroBegue »

mcostalba wrote:Care to post the code ? I don't think I have understood what you mean.
Let me see if I can get it right without testing it:

Code: Select all

  // Find attacked squares, including x-ray attacks for bishops, rooks and queen
  if (Piece == ROOK)
    b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
  else if (Piece == BISHOP)
    b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
  else if (Piece == KNIGHT)
    b = pos.attacks_from<Piece>(s);
  else if (Piece==QUEEN) {
    b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, Us))
      | bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(BISHOP, Us));
  }
  else
    assert(false);
lech
Posts: 1169
Joined: Sun Feb 14, 2010 10:02 pm

Re: queen attacks through rooks and bishops too

Post by lech »

AlvaroBegue wrote:
mcostalba wrote:Care to post the code ? I don't think I have understood what you mean.
Let me see if I can get it right without testing it:

Code: Select all

  // Find attacked squares, including x-ray attacks for bishops, rooks and queen
  if (Piece == ROOK)
    b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
  else if (Piece == BISHOP)
    b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
  else if (Piece == KNIGHT)
    b = pos.attacks_from<Piece>(s);
  else if (Piece==QUEEN) {
    b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, Us))
      | bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(BISHOP, Us));
  }
  else
    assert(false);
Thanks Alvaro, it is the correct code. Now, x-ray works in both directions, correctly without interfaces. :D
Rather "should work" :lol:
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: queen attacks through rooks and bishops too

Post by mcostalba »

AlvaroBegue wrote: Let me see if I can get it right without testing it:
Thanks, now I have understood. It is an interesting tweak and surely deserves a test session.
Ralph Stoesser
Posts: 408
Joined: Sat Mar 06, 2010 9:28 am

Re: queen attacks through rooks and bishops too

Post by Ralph Stoesser »

lech wrote:
AlvaroBegue wrote:
mcostalba wrote:Care to post the code ? I don't think I have understood what you mean.
Let me see if I can get it right without testing it:

Code: Select all

  // Find attacked squares, including x-ray attacks for bishops, rooks and queen
  if (Piece == ROOK)
    b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
  else if (Piece == BISHOP)
    b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
  else if (Piece == KNIGHT)
    b = pos.attacks_from<Piece>(s);
  else if (Piece==QUEEN) {
    b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, Us))
      | bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(BISHOP, Us));
  }
  else
    assert(false);
Thanks Alvaro, it is the correct code. Now, x-ray works in both directions, correctly without interfaces. :D
Rather "should work" :lol:
Yes, I made the same error. :(

Now we should avoid to collect the queen safe contact check bonus for queen x-rays. Since the last index from

Bitboard attackedBy[2][8]

is not used, we could store the direct queen attacks there (cheap hack)

Code: Select all

else if (Piece == QUEEN)
{
    ei.attackedBy[Us][7] |= pos.attacks_from<QUEEN>(s);
    b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, Us))
      | bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(BISHOP, Us));
}
and use it in king safety eval

evaluate_king()

Code: Select all

// Analyse enemy's safe queen contact checks. First find undefended
// squares around the king attacked by enemy queen...
b = undefended & ei.attackedBy[Them][7] & ~pos.pieces_of_color(Them);
if (b)
{
    // ...then remove squares not supported by another enemy piece
    b &= (  ei.attacked_by(Them, PAWN)   | ei.attacked_by(Them, KNIGHT)
          | ei.attacked_by(Them, BISHOP) | ei.attacked_by(Them, ROOK));
    if (b)
        attackUnits += QueenContactCheckBonus * count_1s_max_15<HasPopCnt>(b) * (sente ? 2 : 1);
}
Something like that is possibly worth a retry.
lech
Posts: 1169
Joined: Sun Feb 14, 2010 10:02 pm

Re: queen attacks through rooks and bishops too

Post by lech »

mcostalba wrote: Marek, you may want to post ideas before to start test so to avoid spending time on something already done and discarded.
It is possible a similar "logical" change of this code too:

Code: Select all

 evaluate_passed_pawns<>()
// If there is an enemy rook or queen attacking the pawn from behind,
                // add all X-ray attacks by the rook or queen. Otherwise consider only
                // the squares in the pawn's path attacked or occupied by the enemy.
                if (   (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN, Them))
                    && (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<QUEEN>(s)))
                    unsafeSquares = squaresToQueen;
                else
                    unsafeSquares = squaresToQueen & (ei.attacked_by(Them) | pos.pieces_of_color(Them));
It is very simple to add x-ray attacks of "Us" queen or rooks.

Code: Select all

if (   (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN))
                    && (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
                    unsafeSquares = squaresToQueen;
                else
					{unsafeSquares = squaresToQueen & (ei.attacked_by(Them) | pos.pieces_of_color(Them));
					 set_bit(&defendedSquares, s + pawn_push(Us));
					}
Unfortunatelly, in this case it can turn out to be a too much waste of time.