uint8_t TTGet (uint8_t side, uint8_t depth, uint8_t ply, int *score, int *move) /***************************************************************************** * * Probe the transposition table. There are 2 entries to be looked at as * we are using a 2-tier transposition table. * *****************************************************************************/ { HashSlot *t; TotalGetHashCnt++; t = HashTab[side] + ((HashKey & TTHashMask) & ~1); if (HashKey != t->key && HashKey != (++t)->key) return (0); GoodGetHashCnt++; *move = t->move; *score = t->score; if (t->depth == 0) return (QUIESCENT); if (t->depth < depth && !MATESCORE (t->score)) return (POORDRAFT); if (MATESCORE(*score)) *score -= (*score > 0 ? ply : -ply); return (t->flag); }
short TTGetPV (uint8_t side, uint8_t ply, int score, int *move) /***************************************************************************** * * Probe the transposition table. There are 2 entries to be looked at as * we are using a 2-tier transposition table. This routine merely wants to * get the PV from the hash, nothing else. * *****************************************************************************/ { HashSlot *t; int s; t = HashTab[side] + ((HashKey & TTHashMask) & ~1); s = t->score; if (MATESCORE(s)) s -= (s > 0 ? ply : -ply); if (HashKey == t->key && ((ply & 1 && score == s)||(!(ply & 1) && score == -s))) { *move = t->move; return (1); } t++; s = t->score; if (MATESCORE(s)) s -= (s > 0 ? ply : -ply); if (HashKey == t->key && ((ply & 1 && score == s)||(!(ply & 1) && score == -s))) { *move = t->move; return (1); } return (0); }
void TTPut (uint8_t side, uint8_t depth, uint8_t ply, int alpha, int beta, int score, int move) /**************************************************************************** * * Uses a two-tier depth-based transposition table. The criteria for * replacement is as follows. * 1. The first element is replaced whenever we have a position with * at least the same depth. In that case the element is moved to * the second slot. * 2. The second slot is otherwise always replaced. * Problem may be that the first elements eventually get filled with * outdated entries. Might add an age counter later. * The & ~1 is a trick to clear the last bit making the offset even. * ****************************************************************************/ { HashSlot *t; t = HashTab[side] + ((HashKey & TTHashMask) & ~1); if (depth < t->depth) t++; else if (t->flag) *(t+1) = *t; if (t->flag) CollHashCnt++; TotalPutHashCnt++; t->move = move; t->key = HashKey; t->depth = depth; if (t->depth == 0) t->flag = QUIESCENT; else if (score >= beta) t->flag = LOWERBOUND; else if (score <= alpha) t->flag = UPPERBOUND; else t->flag = EXACTSCORE; if (MATESCORE(score)) t->score = score + ( score > 0 ? ply : -ply); else t->score = score; }
void ShowLine (int move __attribute__ ((unused)), int score, char c) /***************************************************************************** * * Print out the latest PV found during the search. * The only move we know is the root move. The rest of the PV is taken * from the hash table. This strategy avoids all the headaches associated * with returning the PV up from the leaf to the root. * *****************************************************************************/ { int i, len; int pvar[MAXPLYDEPTH]; /* SMC */ if (!(flags & POST)) return; if (NodeCnt < 500000 && (flags & SOLVE)) { /* printf("NodeCnt = %d\n",NodeCnt); getchar(); */ return; } if (Idepth == DEPTH && c == '&') return; if ((flags & XBOARD) && c == '&') return; if (rootscore == -INFINITY-1) return; GetElapsed (); /* * What is the reason for these different output formats, in * particular for et? */ if (flags & XBOARD) { if (score > MATE-255) { printf ("%d%c Mat%d %d %lu\t", Idepth/DEPTH, c, (int)(MATE+2-abs(score))/2, (int)(et*100), NodeCnt+QuiesCnt); if (ofp != stdout) fprintf (ofp,"%2d%c%7.2f Mat%02d%10lu\t", Idepth/DEPTH, c, et, (MATE+2-abs(score))/2, NodeCnt+QuiesCnt); } else if (score < -MATE+255) { printf ("%d%c -Mat%2d %d %lu\t", Idepth/DEPTH, c, (int)(MATE+2-abs(score))/2, (int)(et*100), NodeCnt+QuiesCnt); if (ofp != stdout) fprintf (ofp,"%2d%c%7.2f -Mat%02d%10lu\t", Idepth/DEPTH, c, et, (MATE+2-abs(score))/2, NodeCnt+QuiesCnt); } else { printf ("%d%c %d %d %lu\t", Idepth/DEPTH, c, (int)score, (int)(et*100), NodeCnt+QuiesCnt); if (ofp != stdout) fprintf (ofp,"%2d%c%7.2f%7d%10lu\t", Idepth/DEPTH, c, et, score, NodeCnt+QuiesCnt); } } else { if (score > MATE-255) { printf ("\r%2d%c%7.2f Mat%02d%10lu\t", Idepth/DEPTH, c, et, (MATE+2-abs(score))/2, NodeCnt+QuiesCnt); if (ofp != stdout) fprintf (ofp,"\r%2d%c%7.2f Mat%02d%10lu\t", Idepth/DEPTH, c, et, (MATE+2-abs(score))/2, NodeCnt+QuiesCnt); } else if (score < -MATE+255) { printf ("\r%2d%c%7.2f -Mat%02d%10lu\t", Idepth/DEPTH, c, et, (MATE+2-abs(score))/2, NodeCnt+QuiesCnt); if (ofp != stdout) fprintf (ofp,"\r%2d%c%7.2f -Mat%02d%10lu\t", Idepth/DEPTH, c, et, (MATE+2-abs(score))/2, NodeCnt+QuiesCnt); } else { printf ("\r%2d%c%7.2f%7d%10lu\t", Idepth/DEPTH, c, et, score, NodeCnt+QuiesCnt); if (ofp != stdout) fprintf (ofp,"\r%2d%c%7.2f%7d%10lu\t", Idepth/DEPTH, c, et, score, NodeCnt+QuiesCnt); } } if (c == '-') { printf ("\n"); if (ofp != stdout) fprintf(ofp, "\n"); return; } else if (c == '+') { SANMove (RootPV, 1); printf (" %s\n", SANmv); if (ofp != stdout) fprintf (ofp," %s\n", SANmv); return; } SANMove (RootPV, 1); printf (" %s", SANmv); if (ofp != stdout) fprintf (ofp," %s", SANmv); MakeMove (board.side, &RootPV); TreePtr[3] = TreePtr[2]; GenMoves (2); len = strlen (SANmv); i = 2; pvar[1] = RootPV; /* We fill the rest of the PV with moves from the hash table */ if ((flags & USEHASH)) { while (TTGetPV (board.side, i, rootscore, &pvar[i])) { if ((MATESCORE(score) && abs(score) == MATE+2-i) || Repeat ()) break; if (len >= 32) { printf ("\n\t\t\t\t"); if (ofp != stdout) fprintf (ofp,"\n\t\t\t\t"); len = 0; } SANMove (pvar[i], i); printf (" %s", SANmv); if (ofp != stdout) fprintf (ofp," %s", SANmv); MakeMove (board.side, &pvar[i]); TreePtr[i+2] = TreePtr[i+1]; GenMoves (++i); len += strlen (SANmv); } } printf ("\n"); if (ofp != stdout) fprintf(ofp,"\n"); for (--i; i; i--) UnmakeMove (board.side, &pvar[i]); fflush (stdout); if (ofp != stdout) fflush (ofp); }