/// <summary> /// Return true if this object is more valuable than the other, false otherwise. /// </summary> /// <param name="other"></param> /// <param name="currGen"></param> /// <returns></returns> public bool betterThan(TTEntry other, int currGen) { if ((generation == currGen) != (other.generation == currGen)) { return(generation == currGen); // Old entries are less valuable } if ((type == T_EXACT) != (other.type == T_EXACT)) { return(type == T_EXACT); // Exact score more valuable than lower/upper bound } if (getDepth() != other.getDepth()) { return(getDepth() > other.getDepth()); // Larger depth is more valuable } return(false); // Otherwise, pretty much equally valuable }
/// <summary> /// Print hash table statistics. /// </summary> public void printStats() { int unused = 0; int thisGen = 0; List <int> depHist = new List <int>(); int maxDepth = 20; for (int i = 0; i < maxDepth; i++) { depHist.Add(0); } for (int i = 0; i < table.Length; i++) { TTEntry ent = table[i]; if (ent.type == TTEntry.T_EMPTY) { unused++; } else { if (ent.generation == generation) { thisGen++; } int dp = ent.getDepth(); if (dp < maxDepth) { depHist[dp]++; } } } SystemHelper.println("Hash stats: unused:" + unused.ToString() + " thisGen:" + thisGen.ToString()); for (int i = 0; i < maxDepth; i++) { SystemHelper.println(i.ToString("##") + " " + depHist[i].ToString()); } }
public byte type; // exact score, lower bound, upper bound #endregion Fields #region Methods /** Return true if this object is more valuable than the other, false otherwise. */ public bool betterThan(TTEntry other, int currGen) { if ((generation == currGen) != (other.generation == currGen)) { return generation == currGen; // Old entries are less valuable } if ((type == T_EXACT) != (other.type == T_EXACT)) { return type == T_EXACT; // Exact score more valuable than lower/upper bound } if (getDepth() != other.getDepth()) { return getDepth() > other.getDepth(); // Larger depth is more valuable } return false; // Otherwise, pretty much equally valuable }
public void Insert(ulong key, Move sm, int type, int ply, int depth, int evalScore) { if (depth < 0) { depth = 0; } int idx0 = h0(key); int idx1 = h1(key); TTEntry ent = table[idx0]; byte hashSlot = 0; if (ent.key != key) { ent = table[idx1]; hashSlot = 1; } if (ent.key != key) { if (table[idx1].betterThan(table[idx0], generation)) { ent = table[idx0]; hashSlot = 0; } if (ent.valuable(generation)) { int altEntIdx = (ent.getHashSlot() == 0) ? h1(ent.key) : h0(ent.key); if (ent.betterThan(table[altEntIdx], generation)) { TTEntry altEnt = table[altEntIdx]; altEnt.key = ent.key; altEnt.move = ent.move; altEnt.score = ent.score; altEnt.depthSlot = ent.depthSlot; altEnt.generation = (byte)ent.generation; altEnt.type = ent.type; altEnt.setHashSlot(1 - ent.getHashSlot()); altEnt.evalScore = ent.evalScore; } } } bool doStore = true; if ((ent.key == key) && (ent.getDepth() > depth) && (ent.type == type)) { if (type == TTEntry.T_EXACT) { doStore = false; } else if ((type == TTEntry.T_GE) && (sm.score <= ent.score)) { doStore = false; } else if ((type == TTEntry.T_LE) && (sm.score >= ent.score)) { doStore = false; } } if (doStore) { if ((ent.key != key) || (sm.from != sm.to)) { ent.setMove(sm); } ent.key = key; ent.setScore(sm.score, ply); ent.setDepth(depth); ent.generation = (byte)generation; ent.type = (byte)type; ent.setHashSlot(hashSlot); ent.evalScore = (short)evalScore; } }