protected static Hashcode nextZobrist() { #if CryptoServiceProvider ZobristRNG.GetBytes(ZobristBuffer); #else ZobristRandom.NextBytes(ZobristBuffer); #endif var qHash = BitConverter.ToUInt64(ZobristBuffer, 0); #if TestZobrist Zobrists.Add(qHash); #endif return(qHash); }
protected static void loadZobrist() { ZobristTurn = nextZobrist(); // For En Passant File: for (var n = 0; n < ZobristFile.Length; n++) { ZobristFile[n] = nextZobrist(); } // For Castling Abilities: for (var n = 0; n < ZobristRights.Length; n++) { ZobristRights[n] = nextZobrist(); } // For Pieces that can be held by each Square: for (var nPiece = 0; nPiece < nPieces; nPiece++) { var bPawn = nPiece == vP6; //[Speed]Pawns cannot appear on their First or Last Rank: var nMin = (Int32)(bPawn ? sq.a2 : sq.a1); var nMax = (Int32)(bPawn ? sq.h7 : sq.h8); for (var n = nMin; n <= nMax; n++) { // White Piece: ZobristWhite[nPiece][n] = nextZobrist(); // Black Piece: ZobristBlack[nPiece][n] = nextZobrist(); } } // Distinguish actual Draws as well as Draw2: for (var n = 0; n < ZobristDraw.Length; n++) { ZobristDraw[n] = nextZobrist(); } // For Excluded Moves for (var n = 0; n < nSquares; n++) { ZobristExcludedFrom[n] = nextZobrist(); ZobristExcludedTo[n] = nextZobrist(); } for (var n = 0; n < ZobristExcludedPromotion.Length; n++) { ZobristExcludedPromotion[n] = nextZobrist(); } ZobristExcludedCastles = nextZobrist(); #if RNGStatistics var nCount = Zobrists.Count; var decSum = 0M; LogLine($"\nHashcodes = {Zobrists.Count}"); foreach (var qHash in Zobrists) { decSum += qHash; #if DumpZobrist LogLine(formatHash(qHash)); #endif } var dMean = (Double)decSum / nCount; var dRange = Pow(2, 64); var dMeanIdeal = dRange / 2; var dMeanError = dMean / dMeanIdeal - 1; LogLine($"Mean = {dMean:e} {100 * dMeanError:n2}%"); if (nCount > 1) { var dSquareSum = 0.0; foreach (var qHash in Zobrists) { var dDelta = qHash - dMean; dSquareSum += dDelta * dDelta; } var dVariance = dSquareSum / (nCount - 1); var dDeviation = Sqrt(dVariance); var dDeviationIdeal = dRange / Sqrt(12.0); var dDeviationError = dDeviation / dDeviationIdeal - 1; LogLine($"s.d. = {dDeviation:e} {100 * dDeviationError:n2}%"); } #endif #if TestZobrist Zobrists.Sort(); var qLastCode = default(Hashcode); foreach (var qHash in Zobrists) { if (qHash == qLastCode) { Trace.Assert(qHash != qLastCode, "Duplicate Hashcode Found"); break; } qLastCode = qHash; } #endif }