Value refine_eval(const TTEntry* tte, Value defaultEval, int ply);
void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount);
void update_killers(Move m, SearchStack& ss);
+ void update_gains(const Position& pos, Move move, Value before, Value after);
bool fail_high_ply_1();
int current_search_time();
tte = TT.retrieve(pos.get_key());
}
- // Evaluate the position statically
isCheck = pos.is_check();
- EvalInfo ei;
if (!isCheck)
{
+ // Update gain statistics of the previous move that lead
+ // us in this position.
+ EvalInfo ei;
ss[ply].eval = evaluate(pos, ei, threadID);
-
- // Store gain statistics
- Move m = ss[ply - 1].currentMove;
- if ( m != MOVE_NULL
- && pos.captured_piece() == NO_PIECE_TYPE
- && !move_is_castle(m)
- && !move_is_promotion(m))
- MG.store(pos.piece_on(move_to(m)), move_from(m), move_to(m), ss[ply - 1].eval, -ss[ply].eval);
-
+ update_gains(pos, ss[ply - 1].currentMove, ss[ply - 1].eval, ss[ply].eval);
}
// Initialize a MovePicker object for the current position, and prepare
ss[ply].eval = staticValue;
futilityValue = staticValue + PostFutilityValueMargin; //FIXME: Remove me, only for split
staticValue = refine_eval(tte, staticValue, ply); // Enhance accuracy with TT value if possible
-
- // Store gain statistics
- Move m = ss[ply - 1].currentMove;
- if ( m != MOVE_NULL
- && pos.captured_piece() == NO_PIECE_TYPE
- && !move_is_castle(m)
- && !move_is_promotion(m))
- MG.store(pos.piece_on(move_to(m)), move_from(m), move_to(m), ss[ply - 1].eval, -ss[ply].eval);
+ update_gains(pos, ss[ply - 1].currentMove, ss[ply - 1].eval, ss[ply].eval);
}
// Post futility pruning
if (!isCheck)
{
ss[ply].eval = staticValue;
- // Store gain statistics
- Move m = ss[ply - 1].currentMove;
- if ( m != MOVE_NULL
- && pos.captured_piece() == NO_PIECE_TYPE
- && !move_is_castle(m)
- && !move_is_promotion(m))
- MG.store(pos.piece_on(move_to(m)), move_from(m), move_to(m), ss[ply - 1].eval, -ss[ply].eval);
+ update_gains(pos, ss[ply - 1].currentMove, ss[ply - 1].eval, ss[ply].eval);
}
-
// Initialize "stand pat score", and return it immediately if it is
// at least beta.
bestValue = staticValue;
}
+ // update_gains() updates the gains table of a non-capture move given
+ // the static position evaluation before and after the move.
+
+ void update_gains(const Position& pos, Move m, Value before, Value after) {
+
+ if ( m != MOVE_NULL
+ && before != VALUE_NONE
+ && after != VALUE_NONE
+ && pos.captured_piece() == NO_PIECE_TYPE
+ && !move_is_castle(m)
+ && !move_is_promotion(m))
+ MG.store(pos.piece_on(move_to(m)), move_from(m), move_to(m), -(before + after));
+ }
+
+
// fail_high_ply_1() checks if some thread is currently resolving a fail
// high at ply 1 at the node below the first root node. This information
// is used for time management.