/// <summary> /// Probes the transposition table for a entry that matches the position key. /// </summary> /// <param name="key">The position key</param> /// <returns>(true, entry) if one was found, (false, empty) if not found</returns> public (bool, TranspositionTableEntry) Probe(ulong key) { var ttc = FindCluster(key); var keyH = (uint)(key >> 32); var g = _generation; // Probing the Table will automatically update the generation of the entry // in case the probing retrieves an element. TranspositionTableEntry e = default; var set = false; for (var i = 0; i < ttc.Cluster.Length; ++i) { if (ttc.Cluster[i].Key32 != 0 && ttc.Cluster[i].Key32 != keyH) { continue; } ttc.Cluster[i].Generation = g; e = ttc.Cluster[i]; set = true; break; } if (set) { Hits++; } return(set, e); }
public void Save(TranspositionTableEntry tte) { Key32 = tte.Key32; if (tte.Move != MoveExtensions.EmptyMove) { Move = tte.Move; } Depth = tte.Depth; Generation = tte.Generation; Value = tte.Value; StaticValue = tte.StaticValue; Type = tte.Type; }
/// <summary> /// Stores a move in the transposition table. /// It will automatically detect the best cluster location to store it in. /// If a similar move already is present, a simple check if done to make sure /// it actually is an improvement of the previous move. /// </summary> /// <param name="key">The position key</param> /// <param name="value">The value of the move</param> /// <param name="type">The bound type, e.i. did it exceed alpha or beta</param> /// <param name="depth">The depth of the move</param> /// <param name="move">The move it self</param> /// <param name="statValue">The static value of the move</param> public void Store(ulong key, int value, Bound type, sbyte depth, Move move, int statValue) { // Use the high 32 bits as key inside the cluster var e = new TranspositionTableEntry((uint)(key >> 32), move, depth, _generation, value, statValue, type); var ttc = FindCluster(key); var clusterIndex = 0; var found = false; for (var i = 0; i < ttc.Cluster.Length; ++i) { if (ttc.Cluster[i].Key32 == 0 || ttc.Cluster[i].Key32 == e.Key32) { clusterIndex = i; found = true; break; } } if (!found) { var index = 0; var candidate = ttc.Cluster[index]; var g = _generation; for (var i = 0; i < ttc.Cluster.Length; ++i) { var ttEntry = ttc.Cluster[i]; var(cc1, cc2, cc3, cc4) = (candidate.Generation == g, ttEntry.Generation == g, ttEntry.Type == Bound.Exact, ttEntry.Depth < candidate.Depth); if (cc1 && cc4 || !(cc2 || cc3) && (cc4 || cc1)) { index = i; candidate = ttEntry; } } clusterIndex = index; } ttc.Cluster[clusterIndex].Save(e); }
public void Refresh(TranspositionTableEntry tte) => tte.Generation = _generation;
public TTCluster() { Cluster = new TranspositionTableEntry[4]; Array.Copy(Defaults, Cluster, Defaults.Length); }
public TranspositionTableEntry(TranspositionTableEntry tte) { this = tte; }