#include "book.h"
#include "evaluate.h"
#include "history.h"
+#include "maxgain.h"
#include "misc.h"
#include "movegen.h"
#include "movepick.h"
// History table
History H;
+ // MaxGain table
+ MaxGain MG;
/// Functions
// If we are pondering or in infinite search, we shouldn't print the
// best move before we are told to do so.
- if (!AbortSearch && !ExactMaxTime && (PonderSearch || InfiniteSearch))
+ if (!AbortSearch && (PonderSearch || InfiniteSearch))
wait_for_stop_or_ponderhit();
else
// Print final search statistics
Value oldAlpha = alpha;
Value value = -VALUE_INFINITE;
CheckInfo ci(pos);
+ bool isCheck = pos.is_check();
+
+ // Evaluate the position statically
+ EvalInfo ei;
+ if (!isCheck)
+ ss[0].eval = evaluate(pos, ei, 0);
+ else
+ ss[0].eval = VALUE_NONE;
// Loop through all the moves in the root move list
for (int i = 0; i < rml.move_count() && !AbortSearch; i++)
tte = TT.retrieve(pos.get_key());
}
+ // Evaluate the position statically
+ isCheck = pos.is_check();
+ EvalInfo ei;
+ if (!isCheck)
+ {
+ 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);
+
+ }
+
// Initialize a MovePicker object for the current position, and prepare
// to search all moves
- isCheck = pos.is_check();
mateThreat = pos.has_mate_threat(opposite_color(pos.side_to_move()));
CheckInfo ci(pos);
MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply]);
ss[ply].eval = staticValue;
futilityValue = staticValue + FutilityValueMargin;
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);
}
// Null move search
else
staticValue = evaluate(pos, ei, threadID);
+ 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);
+ }
+
+
// Initialize "stand pat score", and return it immediately if it is
// at least beta.
bestValue = staticValue;
break;
// New best move?
- lock_grab(&(sp->lock));
- if (value > sp->bestValue && !thread_should_stop(threadID))
+ if (value > sp->bestValue) // Less then 2% of cases
{
- sp->bestValue = value;
- if (value > sp->alpha)
+ lock_grab(&(sp->lock));
+ if (value > sp->bestValue && !thread_should_stop(threadID))
{
- // Ask threads to stop before to modify sp->alpha
- if (value >= sp->beta)
+ sp->bestValue = value;
+ if (value > sp->alpha)
{
- for (int i = 0; i < ActiveThreads; i++)
- if (i != threadID && (i == sp->master || sp->slaves[i]))
- Threads[i].stop = true;
+ // Ask threads to stop before to modify sp->alpha
+ if (value >= sp->beta)
+ {
+ for (int i = 0; i < ActiveThreads; i++)
+ if (i != threadID && (i == sp->master || sp->slaves[i]))
+ Threads[i].stop = true;
- sp->finished = true;
- }
+ sp->finished = true;
+ }
- sp->alpha = value;
+ sp->alpha = value;
- sp_update_pv(sp->parentSstack, ss, sp->ply);
- if (value == value_mate_in(sp->ply + 1))
- ss[sp->ply].mateKiller = move;
- }
- // If we are at ply 1, and we are searching the first root move at
- // ply 0, set the 'Problem' variable if the score has dropped a lot
- // (from the computer's point of view) since the previous iteration.
- if ( sp->ply == 1
- && Iteration >= 2
- && -value <= IterationInfo[Iteration-1].value - ProblemMargin)
- Problem = true;
+ sp_update_pv(sp->parentSstack, ss, sp->ply);
+ if (value == value_mate_in(sp->ply + 1))
+ ss[sp->ply].mateKiller = move;
+ }
+ // If we are at ply 1, and we are searching the first root move at
+ // ply 0, set the 'Problem' variable if the score has dropped a lot
+ // (from the computer's point of view) since the previous iteration.
+ if ( sp->ply == 1
+ && Iteration >= 2
+ && -value <= IterationInfo[Iteration-1].value - ProblemMargin)
+ Problem = true;
+ }
+ lock_release(&(sp->lock));
}
- lock_release(&(sp->lock));
}
lock_grab(&(sp->lock));