A simple but very effective extended encoding scheme for bitboards is this:
Each of the 64 squares are encoded in a Quadboard: (64 vertically encoded nibbles in 256bit)
Code: Select all
0000 : empty_0 | 1000 : wpawn
0001 : empty_1 | 1001 : wknight
0010 : bpawn | 1010 : wbishop
0011 : bknight | 1011 : wrook
0100 : bbishop | 1100 : wqueen
0101 : brook | 1101 : wking
0110 : bqueen | 1110 : wking_wmove
0111 : bking | 1111 : special
special on the corners of the board: Rook of the corresponding color - and equivalent to castling in that direction
special elsewhere: this is a pawn that just pushed (enpassant target)
This stores:
All pieces, color to move, castling rights, enpassant
Additional twist:
A chess position in any game must have at least 16 empty squares
The first 16 empty_0/1 squares: Empty + store 16 bits of extra data.
These 16bits can be picked freely and may be (repetition, eval, 50 move counter or anything else).
Comparing this to QBBEngine for example means that all the information below (with change) can be packed into a single Quadboard.
Code: Select all
/*
Board structure definition
PM,P0,P1,P2 are the 4 bitboards that contain the whole board
PM is the bitboard with the side to move pieces
P0,P1 and P2: with these bitboards you can obtain every type of pieces and every pieces combinations.
*/
typedef struct
{
TBB PM;
TBB P0;
TBB P1;
TBB P2;
uint8_t CastleFlags; /* ..sl..SL short long opponent SHORT LONG side to move */
uint8_t EnPassant; /* enpassant column, =8 if not set */
uint8_t Count50; /* 50 move rule counter */
uint8_t Rep; /* 0 if it's not a repetition, 1 if it is */
uint8_t STM; /* side to move */
} TBoard;
Now a question: What board structure do you use - and why?