leanchess wrote: ↑Tue Dec 21, 2021 7:37 pm
It seems that key entropy can be further reduced thanks to piece indices:
Code: Select all
uint64_t GetKey(Color color, Type type, uint8_t index, bool isMoved, Square square) const {
switch (type) {
case Type_None:
return 0;
case Type_King:
return isMoved
&& square == GetKingSquare(color)
? GetMovedKingKey(color)
: GetBaseKey(color, type, square);
case Type_Rook:
return isMoved
&& square == GetRookSquare(color, index)
? GetBaseKey(color, type, square)
^ GetBaseKey(color, Type_King, GetKingSquare(color))
^ GetMovedKingKey(color)
: GetBaseKey(color, type, square);
default:
return GetBaseKey(color, type, square);
}
}
- GetRookSquare() returns the starting square for the respective rook (a1 for (White,0), h1 for (White,1), a8 for (Black, 0), h8 for (Black, 1) (in orthodox), an illegal square for a higher index).
Your solution seems very verbose. If you were to define all 13 pieces as simple integers it would make this "switch if if complex" code a lot impler.
So just make a well defined enum with: BPawn, BKnight, BBishop, BRook, BQueen, BKing, WPawn, WKnight, WBishop, WRook, WQueen, WKing, Empty
Then you can use these together with the square as a direct lookup into an array. So all switch / if stuff goes away.
Then your whole method above becomes this:
which is probably 35x faster.
If you also add WSpecial and BSpecial, as well as WKing_Wmove then you have also encoded all enpassant and castling possibilities in your hash. (special on left right = rook side that can castle) if special is on the middle ranks then its an enpassant pawn. WKing_Wmove is the same as the wking but its white to move.
With this encoding you can encode the whole FEN information (except movecount) into 4 bits per square.
Which is faster yet again:
Code: Select all
Hash ^= Zobrist[(sq << 4) | piece]