New bitboard move generator
Posted: 14 Sep 2006, 10:36
I am starting a new topic, because, I should not have intruded into the Compact Bitboards thread with this new idea.
The basic idea as I have come to understand it is this:
The idea behind this is that it uses mostly 32bit values, has no shifts or multiply instructions, smaller dependency chains, one lookup to get all bits (even for queens), only one dimentional indexing and requires a relativly small hash table.
The downside of not finding the correct bitboard in the hash is minimized by the fact that it should not happen that often. This is because, most blocking combinations are not possible at any given time. As the game progresses different blocking combinations then become possible and old ones become not possible and the changes to the hash is gradual. In the end game the change should become negligible or non existant.
An improvement would be that if a perfect (no collisions) hash of reasonable size can be generated then the above given downside disapears. No signature is needed and the end result would be even faster!
An alternative method would be:
No hash table needed. Some advantages gone. May be quite all right for 64bit machines. Can be modified to just get the queen bits and then modify the result for the rook or bishop (Zach Wegner).
Well thats it as the idea stands now. I am going to make some test and then report back.
Mike
Edit: I added the row numbers at the end of each possibleBits array (also per Zach Wegner). Also Zach said that the hash method could just return the bits for the queen and then modified for rook or bishop as well.
The basic idea as I have come to understand it is this:
- Code: Select all
blockers.union = queenBits[sq];
signature = row1hash[blockers.row1]
^ row2hash[blockers.row2]
^ row3hash[blockers.row3]
^ row4hash[blockers.row4]
^ row5hash[blockers.row5]
^ row6hash[blockers.row6]
^ row7hash[blockers.row7]
^ row8hash[blockers.row8];
key = signature & MASK;
if(hashTbl[key].signature == signature) {
moveBits = hashTbl[key].bits ^ friendlies;
} else {
// generate using classic non rotated bitboards
// or Gerds compact 1.5kb bitboards
// get mobility
// and store both in the hash for future use
}
The idea behind this is that it uses mostly 32bit values, has no shifts or multiply instructions, smaller dependency chains, one lookup to get all bits (even for queens), only one dimentional indexing and requires a relativly small hash table.
The downside of not finding the correct bitboard in the hash is minimized by the fact that it should not happen that often. This is because, most blocking combinations are not possible at any given time. As the game progresses different blocking combinations then become possible and old ones become not possible and the changes to the hash is gradual. In the end game the change should become negligible or non existant.
An improvement would be that if a perfect (no collisions) hash of reasonable size can be generated then the above given downside disapears. No signature is needed and the end result would be even faster!
An alternative method would be:
- Code: Select all
moveBits = bishopBits[sq];
blockers.u = moveBits & allPieces & noEdge;
moveBits &= possibleBits2[sq][blockers.row2];
moveBits &= possibleBits3[sq][blockers.row3];
moveBits &= possibleBits4[sq][blockers.row4];
moveBits &= possibleBits5[sq][blockers.row5];
moveBits &= possibleBits6[sq][blockers.row6];
moveBits &= possibleBits7[sq][blockers.row7];
moveBits ^= friendlies;
No hash table needed. Some advantages gone. May be quite all right for 64bit machines. Can be modified to just get the queen bits and then modify the result for the rook or bishop (Zach Wegner).
Well thats it as the idea stands now. I am going to make some test and then report back.
Mike
Edit: I added the row numbers at the end of each possibleBits array (also per Zach Wegner). Also Zach said that the hash method could just return the bits for the queen and then modified for rook or bishop as well.