mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 09:13:08 +00:00
Reintroduce gains
This seems a die hard idea :-) Passed both short TC LLR: 2.97 (-2.94,2.94) [-1.50,4.50] Total: 17485 W: 3307 L: 3156 D: 11022 And long TC LLR: 2.97 (-2.94,2.94) [0.00,6.00] Total: 38181 W: 6002 L: 5729 D: 26450 bench: 8659830
This commit is contained in:
parent
4ef6b2c32a
commit
b9768b8bc5
2 changed files with 31 additions and 14 deletions
|
@ -30,13 +30,14 @@
|
||||||
|
|
||||||
|
|
||||||
/// The Stats struct stores moves statistics. According to the template parameter
|
/// The Stats struct stores moves statistics. According to the template parameter
|
||||||
/// the class can store History and Countermoves. History records how often
|
/// the class can store History, Gains and Countermoves. History records how often
|
||||||
/// different moves have been successful or unsuccessful during the current search
|
/// different moves have been successful or unsuccessful during the current search
|
||||||
/// and is used for reduction and move ordering decisions.
|
/// and is used for reduction and move ordering decisions. Gains records the move's
|
||||||
|
/// best evaluation gain from one ply to the next and is used for pruning decisions.
|
||||||
/// Countermoves store the move that refute a previous one. Entries are stored
|
/// Countermoves store the move that refute a previous one. Entries are stored
|
||||||
/// according only to moving piece and destination square, hence two moves with
|
/// according only to moving piece and destination square, hence two moves with
|
||||||
/// different origin but same destination and piece will be considered identical.
|
/// different origin but same destination and piece will be considered identical.
|
||||||
template<typename T>
|
template<bool Gain, typename T>
|
||||||
struct Stats {
|
struct Stats {
|
||||||
|
|
||||||
static const Value Max = Value(2000);
|
static const Value Max = Value(2000);
|
||||||
|
@ -55,7 +56,10 @@ struct Stats {
|
||||||
|
|
||||||
void update(Piece p, Square to, Value v) {
|
void update(Piece p, Square to, Value v) {
|
||||||
|
|
||||||
if (abs(table[p][to] + v) < Max)
|
if (Gain)
|
||||||
|
table[p][to] = std::max(v, table[p][to] - 1);
|
||||||
|
|
||||||
|
else if (abs(table[p][to] + v) < Max)
|
||||||
table[p][to] += v;
|
table[p][to] += v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +67,9 @@ private:
|
||||||
T table[PIECE_NB][SQUARE_NB];
|
T table[PIECE_NB][SQUARE_NB];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Stats<Value> HistoryStats;
|
typedef Stats< true, Value> GainsStats;
|
||||||
typedef Stats<std::pair<Move, Move> > CountermovesStats;
|
typedef Stats<false, Value> HistoryStats;
|
||||||
|
typedef Stats<false, std::pair<Move, Move> > CountermovesStats;
|
||||||
|
|
||||||
|
|
||||||
/// MovePicker class is used to pick one pseudo legal move at a time from the
|
/// MovePicker class is used to pick one pseudo legal move at a time from the
|
||||||
|
|
|
@ -82,6 +82,7 @@ namespace {
|
||||||
double BestMoveChanges;
|
double BestMoveChanges;
|
||||||
Value DrawValue[COLOR_NB];
|
Value DrawValue[COLOR_NB];
|
||||||
HistoryStats History;
|
HistoryStats History;
|
||||||
|
GainsStats Gains;
|
||||||
CountermovesStats Countermoves;
|
CountermovesStats Countermoves;
|
||||||
|
|
||||||
template <NodeType NT>
|
template <NodeType NT>
|
||||||
|
@ -293,6 +294,7 @@ namespace {
|
||||||
Value bestValue, alpha, beta, delta;
|
Value bestValue, alpha, beta, delta;
|
||||||
|
|
||||||
std::memset(ss-2, 0, 5 * sizeof(Stack));
|
std::memset(ss-2, 0, 5 * sizeof(Stack));
|
||||||
|
(ss-1)->currentMove = MOVE_NULL; // Hack to skip update gains
|
||||||
|
|
||||||
depth = 0;
|
depth = 0;
|
||||||
BestMoveChanges = 0;
|
BestMoveChanges = 0;
|
||||||
|
@ -301,6 +303,7 @@ namespace {
|
||||||
|
|
||||||
TT.new_search();
|
TT.new_search();
|
||||||
History.clear();
|
History.clear();
|
||||||
|
Gains.clear();
|
||||||
Countermoves.clear();
|
Countermoves.clear();
|
||||||
|
|
||||||
PVSize = Options["MultiPV"];
|
PVSize = Options["MultiPV"];
|
||||||
|
@ -487,9 +490,8 @@ namespace {
|
||||||
SplitPoint* splitPoint;
|
SplitPoint* splitPoint;
|
||||||
Key posKey;
|
Key posKey;
|
||||||
Move ttMove, move, excludedMove, bestMove, threatMove;
|
Move ttMove, move, excludedMove, bestMove, threatMove;
|
||||||
Depth ext, newDepth;
|
Depth ext, newDepth, predictedDepth;
|
||||||
Value bestValue, value, ttValue;
|
Value bestValue, value, ttValue, eval, nullValue, futilityValue;
|
||||||
Value eval, nullValue;
|
|
||||||
bool inCheck, givesCheck, pvMove, singularExtensionNode, improving;
|
bool inCheck, givesCheck, pvMove, singularExtensionNode, improving;
|
||||||
bool captureOrPromotion, dangerous, doFullDepthSearch;
|
bool captureOrPromotion, dangerous, doFullDepthSearch;
|
||||||
int moveCount, quietCount;
|
int moveCount, quietCount;
|
||||||
|
@ -601,6 +603,16 @@ namespace {
|
||||||
TT.store(posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE, ss->staticEval);
|
TT.store(posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE, ss->staticEval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !pos.captured_piece_type()
|
||||||
|
&& ss->staticEval != VALUE_NONE
|
||||||
|
&& (ss-1)->staticEval != VALUE_NONE
|
||||||
|
&& (move = (ss-1)->currentMove) != MOVE_NULL
|
||||||
|
&& type_of(move) == NORMAL)
|
||||||
|
{
|
||||||
|
Square to = to_sq(move);
|
||||||
|
Gains.update(pos.piece_on(to), to, -(ss-1)->staticEval - ss->staticEval);
|
||||||
|
}
|
||||||
|
|
||||||
// Step 6. Razoring (skipped when in check)
|
// Step 6. Razoring (skipped when in check)
|
||||||
if ( !PvNode
|
if ( !PvNode
|
||||||
&& depth < 4 * ONE_PLY
|
&& depth < 4 * ONE_PLY
|
||||||
|
@ -847,12 +859,13 @@ moves_loop: // When in check and at SpNode search starts from here
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Depth predictedDepth = newDepth - reduction<PvNode>(improving, depth, moveCount);
|
predictedDepth = newDepth - reduction<PvNode>(improving, depth, moveCount);
|
||||||
|
|
||||||
// Futility pruning: parent node
|
// Futility pruning: parent node
|
||||||
if (predictedDepth < 7 * ONE_PLY)
|
if (predictedDepth < 7 * ONE_PLY)
|
||||||
{
|
{
|
||||||
Value futilityValue = ss->staticEval + futility_margin(predictedDepth) + Value(128);
|
futilityValue = ss->staticEval + futility_margin(predictedDepth)
|
||||||
|
+ Value(128) + Gains[pos.moved_piece(move)][to_sq(move)];
|
||||||
|
|
||||||
if (futilityValue <= alpha)
|
if (futilityValue <= alpha)
|
||||||
{
|
{
|
||||||
|
@ -869,8 +882,7 @@ moves_loop: // When in check and at SpNode search starts from here
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prune moves with negative SEE at low depths
|
// Prune moves with negative SEE at low depths
|
||||||
if ( predictedDepth < 4 * ONE_PLY
|
if (predictedDepth < 4 * ONE_PLY && pos.see_sign(move) < 0)
|
||||||
&& pos.see_sign(move) < 0)
|
|
||||||
{
|
{
|
||||||
if (SpNode)
|
if (SpNode)
|
||||||
splitPoint->mutex.lock();
|
splitPoint->mutex.lock();
|
||||||
|
@ -883,7 +895,7 @@ moves_loop: // When in check and at SpNode search starts from here
|
||||||
// Check for legality only before to do the move
|
// Check for legality only before to do the move
|
||||||
if (!RootNode && !SpNode && !pos.legal(move, ci.pinned))
|
if (!RootNode && !SpNode && !pos.legal(move, ci.pinned))
|
||||||
{
|
{
|
||||||
--moveCount;
|
moveCount--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue