Introduction
Hello there! I haven’t posted in a while because I was working on my chess engine. Specifically, representing the pieces as bitboards. Now you may ask what a bitboard is. You can use bitboards to represent a chess board in a piece-centric manner. What is so special about bitboards then? Doesn’t a piece list do the same thing? Well, representing a bitboard only requires a single unsigned 64 bit integer!
As taken from the chessprogramming wiki:
To represent the board we typically need one bitboard for each piece-type and color - likely encapsulated inside a class or structure, or as an array of bitboards as part of a position object. A one-bit inside a bitboard implies the existence of a piece of this piece-type on a certain square - one to one associated by the bit-position.
For example, a bitboard containing all of white’s pawns in the starting position would look like this:
|
|
As you can observe, the squares containing the pawns have a value of 1 and others have a value of 0. A bitboard representing a particular piece will have 1 in the squares the piece occupies and 0 in all the other squares.
Before proceding further, I’d like to shed light on the fact that I’m fairly new to the chess engine development scene, so all suggestions are welcome!
Implementation
I decided to go with representing all the bitboards in a single position as a struct
.
|
|
BitBoard is a struct containing a u64.
|
|
Then I wrote a simple function to generate a bitboard from my piece list array (see fen-string-parsing-in-rust)
|
|
And another function to print out the bitboard:
|
|
And some other functions for convenience:
|
|
What fascinated me is the fact that how easy it was to perform actions on bitboards.
I also made an enum to represent the squares (just for convenience and better code readability).
|
|
Piece attack generation
I found this very interesting. I still haven’t finished working on move generation for sliding pieces at the time of writing this.
Anyways, for generating pawn attacks, you can shift the bitboard by 7 and 9 in specific directions to achieve the desired result. That is, capturing diagonally.
For example:
|
|
I also a made a function for convenience (lookup pawn attacks for a particular square):
|
|
And another one for all pawns:
|
|
Attacks can be generated in the same manner for knights and kings:
Knights
|
|
|
|
Result (knight on e4):
|
|
King
|
|
Result (king on e4):
|
|
That’s it for this blog, see you soon!