// and near frontier nodes.
const Value FutilityMarginQS = Value(0x80);
+ // Each move futility margin is decreased
+ const Value IncrementalFutilityMargin = Value(0xA);
+
// Remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply
const Value FutilityMargins[12] = { Value(0x100), Value(0x120), Value(0x200), Value(0x220), Value(0x250), Value(0x270),
// 4 ply 4.5 ply 5 ply 5.5 ply 6 ply 6.5 ply
int perft(Position& pos, Depth depth)
{
Move move;
- MovePicker mp = MovePicker(pos, MOVE_NONE, depth, H);
int sum = 0;
+ MovePicker mp = MovePicker(pos, MOVE_NONE, depth, H);
// If we are at the last ply we don't need to do and undo
// the moves, just to count them.
if (depth <= OnePly) // Replace with '<' to test also qsearch
{
- while ((move = mp.get_next_move()) != MOVE_NONE) sum++;
+ while (mp.get_next_move()) sum++;
return sum;
}
CheckInfo ci(pos);
while ((move = mp.get_next_move()) != MOVE_NONE)
{
- StateInfo st;
- pos.do_move(move, st, ci, pos.move_is_check(move, ci));
- sum += perft(pos, depth - OnePly);
- pos.undo_move(move);
+ StateInfo st;
+ pos.do_move(move, st, ci, pos.move_is_check(move, ci));
+ sum += perft(pos, depth - OnePly);
+ pos.undo_move(move);
}
return sum;
}
const TTEntry* tte;
Move ttMove, move;
Depth ext, newDepth;
- Value approximateEval, nullValue, value, futilityValue;
+ Value approximateEval, nullValue, value, futilityValue, futilityValueScaled;
bool isCheck, useFutilityPruning, singleReply, moveIsCheck, captureOrPromotion, dangerous;
bool mateThreat = false;
int moveCount = 0;
ss[ply].currentMove = MOVE_NULL;
pos.do_null_move(st);
- int R = (depth >= 5 * OnePly ? 4 : 3); // Null move dynamic reduction
+
+ // Null move dynamic reduction based on depth
+ int R = (depth >= 5 * OnePly ? 4 : 3);
+
+ // Null move dynamic reduction based on value
+ if (approximateEval - beta > PawnValueMidgame)
+ R++;
nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID);
&& ttMove == MOVE_NONE
&& !pos.has_pawn_on_7th(pos.side_to_move()))
{
- Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
- if (v < beta - RazorMargins[int(depth) - 2])
+ Value rbeta = beta - RazorMargins[int(depth) - 2];
+ Value v = qsearch(pos, ss, rbeta-1, rbeta, Depth(0), ply, threadID);
+ if (v < rbeta)
return v;
}
if (tte && (tte->type() & VALUE_TYPE_EVAL))
futilityValue = value_from_tt(tte->value(), ply) + FutilityMargins[int(depth) - 2];
+ // Move count pruning limit
+ const int MCLimit = 3 + (1 << (3*int(depth)/8));
+
// Loop through all legal moves until no moves remain or a beta cutoff
// occurs.
while ( bestValue < beta
&& !captureOrPromotion
&& move != ttMove)
{
+ //std::cout << std::endl;
+ //for (int d = 2; d < 14; d++)
+ // std::cout << d << ", " << 64*(1+bitScanReverse32(d*d)) << std::endl;
+
+ //std::cout << std::endl;
+/*
+ 64*(1+bitScanReverse32(d*d))
+
+ 2 -> 256 - 256
+ 3 -> 288 - 320
+ 4 -> 512 - 384
+ 5 -> 544 - 384
+ 6 -> 592 - 448
+ 7 -> 624 - 448
+ 8 -> 672 - 512
+ 9 -> 704 - 512
+ 10 -> 832 - 512
+ 11 -> 864 - 512
+ 12 -> 928 - 576
+ 13 -> 960 - 576
+
+ 300 + 2*(1 << (3*d/4))
+
+ 2 -> 256 - 304
+ 3 -> 288 - 308
+ 4 -> 512 - 316
+ 5 -> 544 - 316
+ 6 -> 592 - 332
+ 7 -> 624 - 364
+ 8 -> 672 - 428
+ 9 -> 704 - 428
+ 10 -> 832 - 556
+ 11 -> 864 - 812
+ 12 -> 928 - 1324
+ 13 -> 960 - 1324
+
+
+ 3 + (1 << (3*int(depth)/8))
+
+ 1 * onePly - > moveCount >= 4
+ 2 * onePly - > moveCount >= 5
+ 3 * onePly - > moveCount >= 7
+ 4 * onePly - > moveCount >= 11
+ 5 * onePly - > moveCount >= 11
+ 6 * onePly - > moveCount >= 19
+ 7 * onePly - > moveCount >= 35
+*/
// History pruning. See ok_to_prune() definition
- if ( moveCount >= 2 + int(depth)
+ if ( moveCount >= MCLimit
&& ok_to_prune(pos, move, ss[ply].threatMove, depth)
&& bestValue > value_mated_in(PLY_MAX))
continue;
{
if (futilityValue == VALUE_NONE)
futilityValue = evaluate(pos, ei, threadID)
- + FutilityMargins[int(depth) - 2];
+ + 64*(1+bitScanReverse32(int(depth) * int(depth)));
+
+ futilityValueScaled = futilityValue - moveCount * IncrementalFutilityMargin;
- if (futilityValue < beta)
+ if (futilityValueScaled < beta)
{
- if (futilityValue > bestValue)
- bestValue = futilityValue;
+ if (futilityValueScaled > bestValue)
+ bestValue = futilityValueScaled;
continue;
}
}