if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
{
// Refresh tte entry to avoid aging
- TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove);
+ TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove, tte->static_value(), tte->king_danger());
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
return value_from_tt(tte->value(), ply);
isCheck = pos.is_check();
if (!isCheck)
{
- if (tte && (tte->type() & VALUE_TYPE_EVAL))
- ss[ply].eval = value_from_tt(tte->value(), ply);
+ if (tte && tte->static_value() != VALUE_NONE)
+ {
+ ss[ply].eval = tte->static_value();
+ ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+ }
else
ss[ply].eval = evaluate(pos, ei, threadID);
return bestValue;
if (bestValue <= oldAlpha)
- TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE);
+ TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
else if (bestValue >= beta)
{
TM.incrementBetaCounter(pos.side_to_move(), depth, threadID);
move = ss[ply].pv[ply];
- TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move);
+ TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
if (!pos.move_is_capture_or_promotion(move))
{
update_history(pos, move, depth, movesSearched, moveCount);
}
}
else
- TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply]);
+ TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
{
- assert(tte->type() != VALUE_TYPE_EVAL);
-
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
return value_from_tt(tte->value(), ply);
}
// Evaluate the position statically
if (isCheck)
staticValue = -VALUE_INFINITE;
- else if (tte && (tte->type() & VALUE_TYPE_EVAL))
- staticValue = value_from_tt(tte->value(), ply);
+ else if (tte && tte->static_value() != VALUE_NONE)
+ {
+ staticValue = tte->static_value();
+ ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+ }
else
staticValue = evaluate(pos, ei, threadID);
{
// Store the score to avoid a future costly evaluation() call
if (!isCheck && !tte && ei.kingDanger[pos.side_to_move()] == 0)
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EV_LO, Depth(-127*OnePly), MOVE_NONE);
+ TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, Depth(-127*OnePly), MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
return bestValue;
}
{
// If bestValue isn't changed it means it is still the static evaluation
// of the node, so keep this info to avoid a future evaluation() call.
- ValueType type = (bestValue == staticValue && !ei.kingDanger[pos.side_to_move()] ? VALUE_TYPE_EV_UP : VALUE_TYPE_UPPER);
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
+ TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, d, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
}
else if (bestValue >= beta)
{
move = ss[ply].pv[ply];
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move);
+ TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
// Update killers only for good checking moves
if (!pos.move_is_capture_or_promotion(move))
update_killers(move, ss[ply]);
}
else
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply]);
+ TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
/// is bigger than the depth of t2. A TTEntry of type VALUE_TYPE_EVAL
/// never replaces another entry for the same position.
-void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m) {
+void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m, Value statV, Value kingD) {
TTEntry *tte, *replace;
uint32_t posKey32 = posKey >> 32; // Use the high 32 bits as key
if (m == MOVE_NONE)
m = tte->move();
- *tte = TTEntry(posKey32, v, t, d, m, generation);
+ *tte = TTEntry(posKey32, v, t, d, m, generation, statV, kingD);
return;
}
else if (i == 0) // replace would be a no-op in this common case
if (c1 + c2 + c3 > 0)
replace = tte;
}
- *replace = TTEntry(posKey32, v, t, d, m, generation);
+ *replace = TTEntry(posKey32, v, t, d, m, generation, statV, kingD);
writes++;
}
{
TTEntry *tte = retrieve(p.get_key());
if (!tte || tte->move() != pv[i])
- store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, Depth(-127*OnePly), pv[i]);
+ store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, Depth(-127*OnePly), pv[i], VALUE_NONE, VALUE_NONE);
p.do_move(pv[i], st);
}
}
public:
TTEntry() {}
- TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation)
+ TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation,
+ Value statV, Value kingD)
: key_ (k), data((m & 0x1FFFF) | (t << 20) | (generation << 23)),
- value_(int16_t(v)), depth_(int16_t(d)) {}
+ value_(int16_t(v)), depth_(int16_t(d)),
+ staticValue_(int16_t(statV)), kingDanger_(int16_t(kingD)) {}
uint32_t key() const { return key_; }
Depth depth() const { return Depth(depth_); }
Value value() const { return Value(value_); }
ValueType type() const { return ValueType((data >> 20) & 7); }
int generation() const { return (data >> 23); }
+ Value static_value() const { return Value(staticValue_); }
+ Value king_danger() const { return Value(kingDanger_); }
private:
uint32_t key_;
uint32_t data;
int16_t value_;
int16_t depth_;
+ int16_t staticValue_;
+ int16_t kingDanger_;
};
~TranspositionTable();
void set_size(size_t mbSize);
void clear();
- void store(const Key posKey, Value v, ValueType type, Depth d, Move m);
+ void store(const Key posKey, Value v, ValueType type, Depth d, Move m, Value statV, Value kingD);
TTEntry* retrieve(const Key posKey) const;
void prefetch(const Key posKey) const;
void new_search();