Caching Check in SharpChess
Posted: 06 Jan 2012, 21:26
To don't interfere too much with the Move Analysis Tree topic, I start a new thread ...
Ahh, I see, super safe 126-bit Zobrist signatures for each side. For usual TT, most would use 64 signatures, already incorporating side to move. Did you count number of probes and hits and is that caching a win for you?
Of course it depends on how expensive player.DetermineCheckStatus is, but check detection by last move is usually quite cheap with 0x88.
Gerd
peterhughes wrote:Hi Gerd, it's a hash table using http://chessprogramming.wikispaces.com/Zobrist+Hashing, modified by the player's colour, and indexed using the MOD of the hash key. I use double hash codes in all my hash tables, to reduce the chance of two chess positions resolving to the same hash. I'm not sure if double hash codes are really necessary, but there you go...
The code below is in C#. I use the C# "unsafe" modifier to enable use of pointer manipulation (like in C) which was/is considerably faster than using C# arrays.
- Code: Select all
/// <summary>
/// Checks is the player is in check for the specified position, and caches the result.
/// </summary>
/// <param name="hashCodeA">
/// Hash Code for Board position A
/// </param>
/// <param name="hashCodeB">
/// Hash Code for Board position B
/// </param>
/// <param name="player">
/// The player.
/// </param>
/// <returns>
/// Returns whether the player in check.
/// </returns>
public static unsafe bool QueryandCachePlayerInCheckStatusForPosition(ulong hashCodeA, ulong hashCodeB, Player player)
{
fixed (HashEntry* phashBase = &hashTableEntries[0])
{
if (player.Colour == Player.PlayerColourNames.Black)
{
hashCodeA |= 0x1;
hashCodeB |= 0x1;
}
else
{
hashCodeA &= 0xFFFFFFFFFFFFFFFE;
hashCodeB &= 0xFFFFFFFFFFFFFFFE;
}
HashEntry* phashEntry = phashBase;
phashEntry += (uint)(hashCodeA % hashTableSize);
if (phashEntry->HashCodeA != hashCodeA || phashEntry->HashCodeB != hashCodeB)
{
phashEntry->HashCodeA = hashCodeA;
phashEntry->HashCodeB = hashCodeB;
phashEntry->IsInCheck = player.DetermineCheckStatus();
}
return phashEntry->IsInCheck;
}
}
Ahh, I see, super safe 126-bit Zobrist signatures for each side. For usual TT, most would use 64 signatures, already incorporating side to move. Did you count number of probes and hits and is that caching a win for you?
Of course it depends on how expensive player.DetermineCheckStatus is, but check detection by last move is usually quite cheap with 0x88.
Gerd