+ // insert_pv_in_tt() is called at the end of a search iteration, and inserts
+ // the PV back into the TT. This makes sure the old PV moves are searched
+ // first, even if the old TT entries have been overwritten.
+
+ void insert_pv_in_tt(const Position& pos, Move pv[]) {
+
+ StateInfo st;
+ TTEntry* tte;
+ Position p(pos, pos.thread());
+ EvalInfo ei;
+ Value v;
+
+ for (int i = 0; pv[i] != MOVE_NONE; i++)
+ {
+ tte = TT.retrieve(p.get_key());
+ if (!tte || tte->move() != pv[i])
+ {
+ v = (p.is_check() ? VALUE_NONE : evaluate(p, ei));
+ TT.store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, pv[i], v, ei.kingDanger[pos.side_to_move()]);
+ }
+ p.do_move(pv[i], st);
+ }
+ }
+
+
+ // extract_pv_from_tt() builds a PV by adding moves from the transposition table.
+ // We consider also failing high nodes and not only VALUE_TYPE_EXACT nodes. This
+ // allow to always have a ponder move even when we fail high at root and also a
+ // long PV to print that is important for position analysis.
+
+ void extract_pv_from_tt(const Position& pos, Move bestMove, Move pv[]) {
+
+ StateInfo st;
+ TTEntry* tte;
+ Position p(pos, pos.thread());
+ int ply = 0;
+
+ assert(bestMove != MOVE_NONE);
+
+ pv[ply] = bestMove;
+ p.do_move(pv[ply++], st);
+
+ while ( (tte = TT.retrieve(p.get_key())) != NULL
+ && tte->move() != MOVE_NONE
+ && move_is_legal(p, tte->move())
+ && ply < PLY_MAX
+ && (!p.is_draw() || ply < 2))
+ {
+ pv[ply] = tte->move();
+ p.do_move(pv[ply++], st);
+ }
+ pv[ply] = MOVE_NONE;
+ }
+
+