Welcome to my dev-blog series on writing a chess engine. This is part 3. Like always, suggestions are welcome!
Hyperbola quintessence?
This is the definition from chessprogramming.org:
Hyperbola Quintessence applies the o^(o-2r)-trick also for vertical or diagonal negative Rays - by reversing the bit-order of up to one bit per rank or byte with a vertical flip aka x86-64 bswap.
Why did I go for this approach? Because I thought magic bitboards were too hard for me.
Implementation
|
|
Where sq
is the square the piece is in, occ
is the occupancy bitboard, and mask
is the attack mask. Why use wrapping_sub()
instead of the -=
operator? I found that the code sometimes panics if the variable is out of bounds.
As I already covered in my previous blog:
|
|
Square is an enum. The occupancy bitboard gives us the occupied squares (where the rays are blocked). As for the mask, here’s an example:
Let’s say we wish to get the attacks in one file. For this, let’s assume a rook is on E4:
|
|
And C4 and G4 are occupied:
|
|
Now the mask for generating attack on this specific rank would be a bitboard of the 4th rank. That is,
|
|
Now if we execute the hyperbola quintessence function on this, we get all possible attacks for the rook on the 4th rank.
|
|
|
|
This is the intended bitboard denoting all possible rank-attacks of a rook on E4 with respect to the occupancy bitboard. Note that we also generate an attack on the blocked bits, as they can be captures (unless they’re friendly pieces).
We can do the same for generating rook attacks both vertically and horizontally.
|
|
Where tr
is the target rank, and tf
is the target file (for getting the value of file/rank mask).
|
|
For bishops, we can do the same but with diagonal and anti-diagonal masks.
|
|
|
|
And for generating queen attacks, it’s even easier since we can take the union of the bishop and rook attack bitboards:
|
|
That’s it for this blog, see you soon!