/// move ordering is at the current node.
MovePicker::MovePicker(const Position& p, bool pv, Move ttm,
- const SearchStack& ss, Depth d, EvalInfo* ei) : pos(p) {
+ const SearchStack& ss, Depth d) : pos(p) {
pvNode = pv;
ttMove = ttm;
mateKiller = (ss.mateKiller == ttm)? MOVE_NONE : ss.mateKiller;
// generating them. So avoid generating in case we know are zero.
Color us = pos.side_to_move();
Color them = opposite_color(us);
- bool noCaptures = ei
- && (ei->attackedBy[us][0] & pos.pieces_of_color(them)) == 0
- && !ei->mi->specialized_eval_exists()
- && (pos.ep_square() == SQ_NONE)
- && !pos.has_pawn_on_7th(us);
if (p.is_check())
phaseIndex = EvasionsPhaseIndex;
else if (depth > Depth(0))
phaseIndex = MainSearchPhaseIndex;
else if (depth == Depth(0))
- phaseIndex = (noCaptures ? QsearchNoCapturesPhaseIndex : QsearchWithChecksPhaseIndex);
+ phaseIndex = QsearchWithChecksPhaseIndex;
else
- phaseIndex = (noCaptures ? NoMovesPhaseIndex : QsearchWithoutChecksPhaseIndex);
+ phaseIndex = QsearchWithoutChecksPhaseIndex;
dc = p.discovered_check_candidates(us);
pinned = p.pinned_pieces(us);
PH_STOP
};
- MovePicker(const Position& p, bool pvnode, Move ttm, const SearchStack& ss, Depth d, EvalInfo* ei = NULL);
+ MovePicker(const Position& p, bool pvnode, Move ttm, const SearchStack& ss, Depth d);
Move get_next_move();
Move get_next_move(Lock &lock);
int number_of_moves() const;
return VALUE_DRAW;
// Transposition table lookup, only when not in PV
+ TTEntry* tte = NULL;
bool pvNode = (beta - alpha != 1);
if (!pvNode)
{
- const TTEntry* tte = TT.retrieve(pos);
+ tte = TT.retrieve(pos);
if (tte && ok_to_use_TT(tte, depth, beta, ply))
+ {
+ assert(tte->type() != VALUE_TYPE_EVAL);
+
return value_from_tt(tte->value(), ply);
+ }
}
// Evaluate the position statically
EvalInfo ei;
+ Value staticValue;
bool isCheck = pos.is_check();
- Value staticValue = (isCheck ? -VALUE_INFINITE : evaluate(pos, ei, threadID));
+
+ if (isCheck)
+ staticValue = -VALUE_INFINITE;
+
+ else if (tte && tte->type() == VALUE_TYPE_EVAL)
+ {
+ // Use the cached evaluation score if possible
+ assert(tte->value() == evaluate(pos, ei, threadID));
+ assert(ei.futilityMargin == Value(0));
+
+ staticValue = tte->value();
+ ei.futilityMargin = Value(0); // manually initialize futilityMargin
+ }
+ else
+ staticValue = evaluate(pos, ei, threadID);
if (ply == PLY_MAX - 1)
return evaluate(pos, ei, threadID);
TT.store(pos, value_to_tt(bestValue, ply), depth, MOVE_NONE, VALUE_TYPE_EXACT);
return bestValue;
}
+ else if (!isCheck && !tte && ei.futilityMargin == 0)
+ {
+ // Store the score to avoid a future costly evaluation() call
+ TT.store(pos, value_to_tt(bestValue, ply), Depth(-127*OnePly), MOVE_NONE, VALUE_TYPE_EVAL);
+ }
if (bestValue > alpha)
alpha = bestValue;
// Initialize a MovePicker object for the current position, and prepare
// to search the moves. Because the depth is <= 0 here, only captures,
// queen promotions and checks (only if depth == 0) will be generated.
- MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth, isCheck ? NULL : &ei);
+ MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth);
Move move;
int moveCount = 0;
Bitboard dcCandidates = mp.discovered_check_candidates();
/// transposition table. Returns a pointer to the TTEntry or NULL
/// if position is not found.
-const TTEntry* TranspositionTable::retrieve(const Position &pos) const {
+TTEntry* TranspositionTable::retrieve(const Position &pos) const {
TTEntry *tte = first_entry(pos);
Depth depth() const { return Depth(depth_); }
Move move() const { return Move(data & 0x7FFFF); }
Value value() const { return Value(value_); }
- ValueType type() const { return ValueType((data >> 20) & 3); }
+ ValueType type() const { return ValueType((data >> 20) & 7); }
int generation() const { return (data >> 23); }
private:
void set_size(unsigned mbSize);
void clear();
void store(const Position &pos, Value v, Depth d, Move m, ValueType type);
- const TTEntry* retrieve(const Position &pos) const;
+ TTEntry* retrieve(const Position &pos) const;
void new_search();
void insert_pv(const Position &pos, Move pv[]);
int full();
VALUE_TYPE_NONE = 0,
VALUE_TYPE_UPPER = 1, // Upper bound
VALUE_TYPE_LOWER = 2, // Lower bound
- VALUE_TYPE_EXACT = 3 // Exact score
+ VALUE_TYPE_EXACT = 3, // Exact score
+ VALUE_TYPE_EVAL = 4 // Evaluation cache
};