////
#include <cassert>
+#include <cmath>
#include <cstring>
#include <fstream>
#include <iostream>
/// Variables initialized by UCI options
- // Minimum number of full depth (i.e. non-reduced) moves at PV and non-PV nodes
- int LMRPVMoves, LMRNonPVMoves;
-
// Depth limit for use of dynamic threat detection
Depth ThreatDepth;
bool UseLogFile;
std::ofstream LogFile;
+ // Natural logarithmic lookup table and its getter function
+ double lnArray[512];
+ inline double ln(int i) { return lnArray[i]; }
+
// MP related variables
int ActiveThreads = 1;
Depth MinimumSplitDepth;
//// Functions
////
-//FIXME: HACK
-static double lnArray[512];
-
-inline double ln(int i)
-{
- return lnArray[i];
-}
/// perft() is our utility to verify move generation is bug free. All the legal
/// moves up to given depth are generated and counted and the sum returned.
MateThreatExtension[1] = Depth(get_option_value_int("Mate Threat Extension (PV nodes)"));
MateThreatExtension[0] = Depth(get_option_value_int("Mate Threat Extension (non-PV nodes)"));
- LMRPVMoves = get_option_value_int("Full Depth Moves (PV nodes)") + 1;
- LMRNonPVMoves = get_option_value_int("Full Depth Moves (non-PV nodes)") + 1;
ThreatDepth = get_option_value_int("Threat Depth") * OnePly;
Chess960 = get_option_value_bool("UCI_Chess960");
/// and initializes the split point stack and the global locks and condition
/// objects.
-#include <cmath> //FIXME: HACK
-
void init_threads() {
- // FIXME: HACK!!
- for (int i = 0; i < 512; i++)
- lnArray[i] = log(double(i));
-
volatile int i;
#if !defined(_MSC_VER)
pthread_t pthread[1];
#endif
+ // Init our logarithmic lookup table
+ for (i = 0; i < 512; i++)
+ lnArray[i] = log(double(i)); // log() returns base-e logarithm
+
for (i = 0; i < THREAD_MAX; i++)
Threads[i].activeSplitPoints = 0;
Value root_search(Position& pos, SearchStack ss[], RootMoveList& rml, Value alpha, Value beta) {
Value oldAlpha = alpha;
- Value value;
+ Value value = -VALUE_INFINITE;
CheckInfo ci(pos);
// Loop through all the moves in the root move list
Value oldAlpha, value;
bool isCheck, mateThreat, singleEvasion, moveIsCheck, captureOrPromotion, dangerous;
int moveCount = 0;
- Value bestValue = -VALUE_INFINITE;
+ Value bestValue = value = -VALUE_INFINITE;
if (depth < OnePly)
return qsearch(pos, ss, alpha, beta, Depth(0), ply, threadID);
bool isCheck, useFutilityPruning, singleEvasion, moveIsCheck, captureOrPromotion, dangerous;
bool mateThreat = false;
int moveCount = 0;
- futilityValue = staticValue = bestValue = -VALUE_INFINITE;
+ futilityValue = staticValue = bestValue = value = -VALUE_INFINITE;
if (depth < OnePly)
return qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
if (bestValue > alpha)
alpha = bestValue;
+ // If we are near beta then try to get a cutoff pushing checks a bit further
+ bool deepChecks = depth == -OnePly && staticValue >= beta - PawnValueMidgame / 8;
+
// Initialize a MovePicker object for the current position, and prepare
- // to search the moves. Because the depth is <= 0 here, only captures,
- // queen promotions and checks (only if depth == 0) will be generated.
- MovePicker mp = MovePicker(pos, ttMove, depth, H);
+ // to search the moves. Because the depth is <= 0 here, only captures,
+ // queen promotions and checks (only if depth == 0 or depth == -OnePly
+ // and we are near beta) will be generated.
+ MovePicker mp = MovePicker(pos, ttMove, deepChecks ? Depth(0) : depth, H);
CheckInfo ci(pos);
enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame;
futilityBase = staticValue + FutilityMarginQS + ei.futilityMargin;
Position pos = Position(sp->pos);
CheckInfo ci(pos);
SearchStack* ss = sp->sstack[threadID];
- Value value;
+ Value value = -VALUE_INFINITE;
Move move;
bool isCheck = pos.is_check();
bool useFutilityPruning = sp->depth < SelectiveDepth
Position pos = Position(sp->pos);
CheckInfo ci(pos);
SearchStack* ss = sp->sstack[threadID];
- Value value;
+ Value value = -VALUE_INFINITE;
Move move;
while ( sp->alpha < sp->beta