mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-23 10:36:26 +08:00
Introduce dynamic contempt
Make contempt dependent on the current score of the root position.
The idea is that we now use a linear formula like the following to decide
on the contempt to use during a search :
contempt = x + y * eval
where x is the base contempt set by the user in the "Contempt" UCI option,
and y * eval is the dynamic part which adapts itself to the estimation of
the evaluation of the root position returned by the search. In this patch,
we use x = 18 centipawns by default, and the y * eval correction can go
from -20 centipawns if the root eval is less than -2.0 pawns, up to +20
centipawns when the root eval is more than 2.0 pawns.
To summarize, the new contempt goes from -0.02 to 0.38 pawns, depending if
Stockfish is losing or winning, with an average value of 0.18 pawns by default.
STC:
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 110052 W: 24614 L: 23938 D: 61500
http://tests.stockfishchess.org/tests/view/5a72e6020ebc590f2c86ea20
LTC:
LLR: 2.97 (-2.94,2.94) [0.00,5.00]
Total: 16470 W: 2896 L: 2705 D: 10869
http://tests.stockfishchess.org/tests/view/5a76c5b90ebc5902971a9830
A second match at LTC was organised against the current master:
ELO: 1.45 +-2.9 (95%) LOS: 84.0%
Total: 19369 W: 3350 L: 3269 D: 12750
http://tests.stockfishchess.org/tests/view/5a7acf980ebc5902971a9a2e
Finally, we checked that there is no apparent problem with multithreading,
despite the fact that some threads might have a slightly different contempt
level that the main thread.
Match of this version against master, both using 5 threads, time control 30+0.3:
ELO: 2.18 +-3.2 (95%) LOS: 90.8%
Total: 14840 W: 2502 L: 2409 D: 9929
http://tests.stockfishchess.org/tests/view/5a7bf3e80ebc5902971a9aa2
Include suggestions from Marco Costalba, Aram Tumanian, Ronald de Man, etc.
Bench: 5207156
This commit is contained in:
committed by
Stéphane Nicolet
parent
d71adc5bd9
commit
cb1324312d
@@ -191,11 +191,6 @@ void MainThread::search() {
|
||||
Time.init(Limits, us, rootPos.game_ply());
|
||||
TT.new_search();
|
||||
|
||||
int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
|
||||
|
||||
Eval::Contempt = (us == WHITE ? make_score(contempt, contempt / 2)
|
||||
: -make_score(contempt, contempt / 2));
|
||||
|
||||
if (rootMoves.empty())
|
||||
{
|
||||
rootMoves.emplace_back(MOVE_NONE);
|
||||
@@ -282,6 +277,7 @@ void Thread::search() {
|
||||
Depth lastBestMoveDepth = DEPTH_ZERO;
|
||||
MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
|
||||
double timeReduction = 1.0;
|
||||
Color us = rootPos.side_to_move();
|
||||
|
||||
std::memset(ss-4, 0, 7 * sizeof(Stack));
|
||||
for (int i = 4; i > 0; i--)
|
||||
@@ -306,6 +302,10 @@ void Thread::search() {
|
||||
|
||||
multiPV = std::min(multiPV, rootMoves.size());
|
||||
|
||||
int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
|
||||
Eval::Contempt = (us == WHITE ? make_score(contempt, contempt / 2)
|
||||
: -make_score(contempt, contempt / 2));
|
||||
|
||||
// Iterative deepening loop until requested to stop or the target depth is reached
|
||||
while ( (rootDepth += ONE_PLY) < DEPTH_MAX
|
||||
&& !Threads.stop
|
||||
@@ -340,6 +340,15 @@ void Thread::search() {
|
||||
delta = Value(18);
|
||||
alpha = std::max(rootMoves[PVIdx].previousScore - delta,-VALUE_INFINITE);
|
||||
beta = std::min(rootMoves[PVIdx].previousScore + delta, VALUE_INFINITE);
|
||||
|
||||
// Adjust contempt based on current situation
|
||||
contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
|
||||
contempt += bestValue > 500 ? 50: // Dynamic contempt
|
||||
bestValue < -500 ? -50:
|
||||
bestValue / 10;
|
||||
|
||||
Eval::Contempt = (us == WHITE ? make_score(contempt, contempt / 2)
|
||||
: -make_score(contempt, contempt / 2));
|
||||
}
|
||||
|
||||
// Start with a small aspiration window and, in the case of a fail
|
||||
|
||||
Reference in New Issue
Block a user