Can't extract all relevant bits from rook attack mask

Discussion of chess software programming and technical issues.

Moderators: hgm, chrisw, Rebel

c5break
Posts: 3
Joined: Tue Dec 03, 2024 9:09 pm
Full name: Pera Zdera

Can't extract all relevant bits from rook attack mask

Post by c5break »

Hello everyone, thank you for taking some of your valuable time to read this post.
I am new user, joining here in desperate hope that this community can help me solve the problem I face.

I am trying to create a bitboard that represents the path between :
1.) sliding piece giving check to the king (not included in the path)
2.) king itself (included in the path)
3.) square behind king.
In below diagram, bitboard should have squares e3, e4, e5, e6, and e7 set:
[d]8/8/4k3/8/8/8/4R3/8 w - - 0 1

I am using Golang to code the chess engine. Bitboards use Little-Endian Rank-File Mapping. Slider attacks are calculated with magic bitboards, while knight, king and pawn attacks are precomputed. Below is the code that produces almost correct path, square behind king is missing:

Code: Select all

attacker := int(bitboard.ToSquare("e2"))
king := int(bitboard.ToSquare("e6"))

attackerBB := rook.RookAttacks(attacker, 1<<king) // RookAttack(square, occupancy) returns attack mask using magic bitboards
kingBB := rook.RookAttacks(king, 1<<attacker)

checkmask := kingBB&attackerBB | (1 << king)
I guess I could use if statements to add the square behind the king, but I thought there might be a more clever way, hence asking here for help.

One idea that came to my mind was to use precomputed attack mask for the king, for the square king stands on, and somehow cut off all the squares aside from one behind him. Then I could simply OR the square behind him into the existing path.

I apologize if I am sounding confusing, this is my first time posting here, and asking for an advice regarding chess programming.
If you need further info, or you have any questions, feel free to reach out. Thank you.
Spinojara
Posts: 2
Joined: Wed May 01, 2024 6:59 pm
Full name: Isak Ellmer

Re: Can't extract all relevant bits from rook attack mask

Post by Spinojara »

Why do you want to just include the square behind the king? To make sure that the king does not move into another square which is attacked? In that case I would just recommend always xoring out the king before generating your attacks. Let the rook attack all the way to the last square of the board (e8).
c5break
Posts: 3
Joined: Tue Dec 03, 2024 9:09 pm
Full name: Pera Zdera

Re: Can't extract all relevant bits from rook attack mask

Post by c5break »

Hi! Thank you for offering your help!

I need this bitboard for masking legal moves, which is why I can't just let the rook attacks go all the way to e8 :(
c5break
Posts: 3
Joined: Tue Dec 03, 2024 9:09 pm
Full name: Pera Zdera

Re: Can't extract all relevant bits from rook attack mask

Post by c5break »

I have managed to construct what looks like a promising algorithm, let me share the code because it might be useful to future visitors:

Code: Select all

checkmask := rook.RookAttacks(attacker, 1<<kingSquare) | pieces.KingAttackMask[kingSquare] 
checkmask &= rook.RookAttacks(attacker, 0)
checkmask &= rook.RookAttacks(kingSquare, 1<<attacker)
checkmask |= 1 << kingSquare
In first line we add precomputed king attacks to the path between rook and king (neither piece is included in the path).
This way we add square behind king into the checkmask bitboard.
Second and third line will clear vertical attacks from our example (look at FEN position I provided) since they are unnecessary.
Finally, we add king to the path (king attack mask, and rook attack masks did not set this bit).

Now we have our checkmask properly set to exclude attacker, include king in check, and a square behind him. It works for both vertical and horizontal lining up of attacker and king.

This is not ideal algorithm, but will be used to create precomputed table, that will be used in move generator.

If anyone has better approach, I will still be interested. I am leaving this post here because someone might need it in the future.