AttacksTo() bitboard

Discussion of chess software programming and technical issues.

Moderator: Ras

tttony
Posts: 276
Joined: Sun Apr 24, 2011 12:33 am

AttacksTo() bitboard

Post by tttony »

Hi all!

Im trying to add AttacksTo() function using bitboards but has became a headache and Im sorry for the stupid question :oops:

Im using this example: https://chessprogramming.wikispaces.com ... l%20Pieces

The problem that Im facing it's how it works?, I store each piece bb in the variable:

Code: Select all

U64 pieceBB[COLOR][PIECE_TYPE]
The attacks are stored in arrays like in the CPW example:

Code: Select all

U64 arrPawnAttacks[COLOR][SQUARE]

Code: Select all

U64 arrKnightAttacks[BOTH][SQUARE]
Following this: https://chessprogramming.wikispaces.com ... tboards%29

Im testing using this example position:

[d]8/8/6k1/4pnp1/8/5PPP/6K1/8 w - - 0 37

The occupied pieces bb is: 70849795211264

I use A1 = 0, H8 = 63 bitboard, so Im looking if there is an attacker in the G3 = 22 that is the KNIGH in the F5 square

Now this is the problem, in the variable:

Code: Select all

U64 arrKnightAttacks[BOTH][22]
Gives 0 (zero) because there is no KNIGHT in that square, so my question is:

Do I have to set one bit in each square attaked? for example:

Pseudo code:

Code: Select all

U64 attack_squares = KnightsAttacks(1ULL << sq)
while (attack_squares) {
    POP(&attack_squares)
    if (arrKnightAttacks[BOTH][attack_squares] == 0ULL)
       arrKnightAttacks[BOTH][attack_squares] = 1ULL << sq
}
Thanks!
syzygy
Posts: 5869
Joined: Tue Feb 28, 2012 11:56 pm

Re: AttacksTo() bitboard

Post by syzygy »

tttony wrote:Now this is the problem, in the variable:

Code: Select all

U64 arrKnightAttacks[BOTH][22]
Gives 0 (zero) because there is no KNIGHT in that square, so my question is:

Do I have to set one bit in each square attaked?
If you did not initialise the arrKnightAttacks array (or just set it to 0), I'm not sure why you would think it would work.

arrKnightsAttacks for G3 must have a 1-bit for each square that is attacked by a knight on G3.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: AttacksTo() bitboard

Post by bob »

tttony wrote:Hi all!

Im trying to add AttacksTo() function using bitboards but has became a headache and Im sorry for the stupid question :oops:

Im using this example: https://chessprogramming.wikispaces.com ... l%20Pieces

The problem that Im facing it's how it works?, I store each piece bb in the variable:

Code: Select all

U64 pieceBB[COLOR][PIECE_TYPE]
The attacks are stored in arrays like in the CPW example:

Code: Select all

U64 arrPawnAttacks[COLOR][SQUARE]

Code: Select all

U64 arrKnightAttacks[BOTH][SQUARE]
Following this: https://chessprogramming.wikispaces.com ... tboards%29

Im testing using this example position:

[d]8/8/6k1/4pnp1/8/5PPP/6K1/8 w - - 0 37

The occupied pieces bb is: 70849795211264

I use A1 = 0, H8 = 63 bitboard, so Im looking if there is an attacker in the G3 = 22 that is the KNIGH in the F5 square

Now this is the problem, in the variable:

Code: Select all

U64 arrKnightAttacks[BOTH][22]
Gives 0 (zero) because there is no KNIGHT in that square, so my question is:

Do I have to set one bit in each square attaked? for example:

Pseudo code:

Code: Select all

U64 attack_squares = KnightsAttacks(1ULL << sq)
while (attack_squares) {
    POP(&attack_squares)
    if (arrKnightAttacks[BOTH][attack_squares] == 0ULL)
       arrKnightAttacks[BOTH][attack_squares] = 1ULL << sq
}
Thanks!
This is a fairly expensive operation. AttacksFrom is easy enough, it produces a bitmap showing all the squares that the piece on a particular square attacks.

AttacksTo is the inverse. It should have a one bit set for any square that has a piece that attacks the target square, no matter which piece it is (you can use the various occupied square bit boards to figure out which piece or pieces are doing the attacking. Here is a very simple AttacksTo() function as used in Crafty:

Code: Select all

uint64_t AttacksTo(TREE * RESTRICT tree, int square) {
  uint64_t attacks =
      (pawn_attacks[white][square] & Pawns(black)) |
      (pawn_attacks[black][square] & Pawns(white));
  uint64_t bsliders =
      Bishops(white) | Bishops(black) | Queens(white) | Queens(black);
  uint64_t rsliders =
      Rooks(white) | Rooks(black) | Queens(white) | Queens(black);
  attacks |= knight_attacks[square] & (Knights(black) | Knights(white));
  if (bishop_attacks[square] & bsliders)
    attacks |= AttacksBishop(square, OccupiedSquares) & bsliders;
  if (rook_attacks[square] & rsliders)
    attacks |= AttacksRook(square, OccupiedSquares) & rsliders;
  attacks |= king_attacks[square] & (Kings(black) | Kings(white));
  return (attacks);
}
The basic idea is for each piece type, generate moves from the square of interest, then AND that with the bit boards containing enemy or friendly pieces of that type. OR the entire mess together and you are done.

I primarily use this function in my SEE() code, and to a lesser extent, in the code that generates just legal moves when in check...
tttony
Posts: 276
Joined: Sun Apr 24, 2011 12:33 am

Re: AttacksTo() bitboard

Post by tttony »

syzygy wrote:
tttony wrote:Now this is the problem, in the variable:

Code: Select all

U64 arrKnightAttacks[BOTH][22]
Gives 0 (zero) because there is no KNIGHT in that square, so my question is:

Do I have to set one bit in each square attaked?
If you did not initialise the arrKnightAttacks array (or just set it to 0), I'm not sure why you would think it would work.

arrKnightsAttacks for G3 must have a 1-bit for each square that is attacked by a knight on G3.
I was just following the examples from CPW and after some tests I realized that is not how it should work, I was just asking to confirm it

wow I didn't know that working with bitboard and magic bitboard will be so hard

Thanks Bob for the code, I was thinking in doing something like that, now I have some clues in how it works the AttacksTo() function

I have some questions about Magic Bitboard but I will create a new thread

Thanks and Happy New Year!!
Gerd Isenberg
Posts: 2251
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: AttacksTo() bitboard

Post by Gerd Isenberg »

tttony wrote: I was just following the examples from CPW and after some tests I realized that is not how it should work, I was just asking to confirm it

wow I didn't know that working with bitboard and magic bitboard will be so hard

Thanks Bob for the code, I was thinking in doing something like that, now I have some clues in how it works the AttacksTo() function

I have some questions about Magic Bitboard but I will create a new thread

Thanks and Happy New Year!!
Happy New Year to you as well!

What is wrong with the cpw sample of attacksTo?
tttony
Posts: 276
Joined: Sun Apr 24, 2011 12:33 am

Re: AttacksTo() bitboard

Post by tttony »

There is nothing wrong with the example, I just over-understood the example on CPW because of Pawn Attacks example:

Code: Select all

arrPawnAttacks[white][d4]
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . 1 . 1 . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
I thought that each array save the bitboard attacked square(s) and after some tests is not how it sould be, in the array you must asign the bitoard to the attacked square, in the above example will be like this:

arrPawnAttacks attacks C5 and E5, so:

Code: Select all

arrPawnAttacks[white][c5] = bb
arrPawnAttacks[white][e5] = bb
Thanks Gerd! Now I'm going fo the magics! :D
syzygy
Posts: 5869
Joined: Tue Feb 28, 2012 11:56 pm

Re: AttacksTo() bitboard

Post by syzygy »

tttony wrote:There is nothing wrong with the example, I just over-understood the example on CPW because of Pawn Attacks example:

Code: Select all

arrPawnAttacks[white][d4]
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . 1 . 1 . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
I thought that each array save the bitboard attacked square(s)
It does...

As I already wrote:
syzygy wrote:arrKnightsAttacks for G3 must have a 1-bit for each square that is attacked by a knight on G3.
Same for all other squares and for pawns and kings.

You have to initialise these arrays yourself. If you have the value 0 in arrKnightAttacks[G3], which seemed to be what you wrote, then you did not initialise this array properly.
Gerd Isenberg
Posts: 2251
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: AttacksTo() bitboard

Post by Gerd Isenberg »

tttony wrote:There is nothing wrong with the example, I just over-understood the example on CPW because of Pawn Attacks example:

Code: Select all

arrPawnAttacks[white][d4]
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . 1 . 1 . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
I thought that each array save the bitboard attacked square(s) and after some tests is not how it sould be, in the array you must asign the bitoard to the attacked square, in the above example will be like this:

arrPawnAttacks attacks C5 and E5, so:

Code: Select all

arrPawnAttacks[white][c5] = bb
arrPawnAttacks[white][e5] = bb
Thanks Gerd! Now I'm going fo the magics! :D
Ok - as Ronald mentioned, proper initialization of the none-sliding from-attacks is required, that is

Code: Select all

arrPawnAttacks[white][d4] = {c5, e5}
arrPawnAttacks[black][d4] = {c3, e3}
and

Code: Select all

arrPawnAttacks[black][c5] = {b4, d4}
arrPawnAttacks[black][e5] = {d4, f4}
Now, for attacks-to, looking if black pawns attacking d4, you intersect ...

Code: Select all

attacksto |= arrPawnAttacks[white][d4] & blackPawns; // subset of {c5, e5}
and for white pawns attacking d4 ...

Code: Select all

attacksto |= arrPawnAttacks[black][d4] & whitePawns; // subset of {c3, e3}
Bob's attacks-to proposal has preconditions to look whether there are relevant sliders on the relevant rays at all before getting the sliding attacks sets - which pays off in late endings, but is a bit slower otherwise.

Good luck and fun,
Gerd
tttony
Posts: 276
Joined: Sun Apr 24, 2011 12:33 am

Re: AttacksTo() bitboard

Post by tttony »

Alright, alright, now I'm getting in how it works, the array:

Code: Select all

arrPawnAttacks[white][64] 
Will be the same always, it does not depend of the current position, it just a pattern of each square that attack the pawns

I see that bishopAttacks() and rookAttacks() are not arrays, that's what I'm working right now with magic bitboards, thanks to Pradyumna Kannan for the files in magicmoves.zip, it's the only magic bitboard that worked fine, I've tried like 3 or 4

Thanks Ronald and Gerd!! Maybe in these days you will see some questions here :D