int drawScore = TB::UseRule50 ? 1 : 0;
- // use the range VALUE_MATE_IN_MAX_PLY to VALUE_TB_WIN_IN_MAX_PLY to score
- value = wdl < -drawScore ? VALUE_MATED_IN_MAX_PLY + ss->ply + 1
- : wdl > drawScore ? VALUE_MATE_IN_MAX_PLY - ss->ply - 1
+ Value tbValue = VALUE_TB - ss->ply;
+
+ // use the range VALUE_TB to VALUE_TB_WIN_IN_MAX_PLY to score
+ value = wdl < -drawScore ? -tbValue
+ : wdl > drawScore ? tbValue
: VALUE_DRAW + 2 * wdl * drawScore;
Bound b = wdl < -drawScore ? BOUND_UPPER
ss->inCheck = pos.checkers();
moveCount = 0;
+ // Used to send selDepth info to GUI (selDepth counts from 1, ply from 0)
+ if (PvNode && thisThread->selDepth < ss->ply + 1)
+ thisThread->selDepth = ss->ply + 1;
+
// Step 2. Check for an immediate draw or maximum ply reached
if (pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
return (ss->ply >= MAX_PLY && !ss->inCheck) ? evaluate(pos) : VALUE_DRAW;
ss->staticEval = bestValue =
(ss - 1)->currentMove != MOVE_NULL ? evaluate(pos) : -(ss - 1)->staticEval;
- // Stand pat. Return immediately if static value is at least beta
+ // Stand pat. Return immediately if bestValue is at least beta at non-Pv nodes.
+ // At PvNodes set bestValue between alpha and beta instead
if (bestValue >= beta)
{
- if (!ss->ttHit)
- tte->save(posKey, value_to_tt(bestValue, ss->ply), false, BOUND_LOWER, DEPTH_NONE,
- MOVE_NONE, ss->staticEval);
+ if (!PvNode || abs(bestValue) >= VALUE_TB_WIN_IN_MAX_PLY)
+ {
+ if (!ss->ttHit)
+ tte->save(posKey, value_to_tt(bestValue, ss->ply), false, BOUND_LOWER,
+ DEPTH_NONE, MOVE_NONE, ss->staticEval);
- return bestValue;
+ return bestValue;
+ }
+ bestValue = std::min((alpha + beta) / 2, beta - 1);
}
if (bestValue > alpha)
// Inverse of value_to_tt(): it adjusts a mate or TB score
// from the transposition table (which refers to the plies to mate/be mated from
// current position) to "plies to mate/be mated (TB win/loss) from the root".
-// However, to avoid potentially false mate scores related to the 50 moves rule
-// and the graph history interaction problem, we return an optimal TB score instead.
+// However, to avoid potentially false mate or TB scores related to the 50 moves rule
+// and the graph history interaction, we return highest non-TB score instead.
+
Value value_from_tt(Value v, int ply, int r50c) {
if (v == VALUE_NONE)
return VALUE_NONE;
- if (v >= VALUE_TB_WIN_IN_MAX_PLY) // TB win or better
+ // handle TB win or better
+ if (v >= VALUE_TB_WIN_IN_MAX_PLY)
{
- if (v >= VALUE_MATE_IN_MAX_PLY && VALUE_MATE - v > 99 - r50c)
- return VALUE_MATE_IN_MAX_PLY - 1; // do not return a potentially false mate score
+ // Downgrade a potentially false mate score
+ if (v >= VALUE_MATE_IN_MAX_PLY && VALUE_MATE - v > 100 - r50c)
+ return VALUE_TB_WIN_IN_MAX_PLY - 1;
+
+ // Downgrade a potentially false TB score.
+ if (VALUE_TB - v > 100 - r50c)
+ return VALUE_TB_WIN_IN_MAX_PLY - 1;
return v - ply;
}
- if (v <= VALUE_TB_LOSS_IN_MAX_PLY) // TB loss or worse
+ // handle TB loss or worse
+ if (v <= VALUE_TB_LOSS_IN_MAX_PLY)
{
- if (v <= VALUE_MATED_IN_MAX_PLY && VALUE_MATE + v > 99 - r50c)
- return VALUE_MATED_IN_MAX_PLY + 1; // do not return a potentially false mate score
+ // Downgrade a potentially false mate score.
+ if (v <= VALUE_MATED_IN_MAX_PLY && VALUE_MATE + v > 100 - r50c)
+ return VALUE_TB_LOSS_IN_MAX_PLY + 1;
+
+ // Downgrade a potentially false TB score.
+ if (VALUE_TB + v > 100 - r50c)
+ return VALUE_TB_LOSS_IN_MAX_PLY + 1;
return v + ply;
}
if (v == -VALUE_INFINITE)
v = VALUE_ZERO;
- bool tb = TB::RootInTB && abs(v) < VALUE_MATE_IN_MAX_PLY;
+ bool tb = TB::RootInTB && abs(v) <= VALUE_TB;
v = tb ? rootMoves[i].tbScore : v;
if (ss.rdbuf()->in_avail()) // Not at first line