<< std::endl;
}
- // Reset the threads, still sleeping: will be wake up at split time
+ // Reset the threads, still sleeping: will wake up at split time
for (size_t i = 0; i < Threads.size(); ++i)
Threads[i]->maxPly = 0;
// Bring the best move to the front. It is critical that sorting
// is done with a stable algorithm because all the values but the
// first and eventually the new best one are set to -VALUE_INFINITE
- // and we want to keep the same order for all the moves but the new
- // PV that goes to the front. Note that in case of MultiPV search
- // the already searched PV lines are preserved.
+ // and we want to keep the same order for all the moves except the
+ // new PV that goes to the front. Note that in case of MultiPV
+ // search the already searched PV lines are preserved.
std::stable_sort(RootMoves.begin() + PVIdx, RootMoves.end());
// Write PV back to transposition table in case the relevant
RootMoves[i].insert_pv_in_tt(pos);
// If search has been stopped break immediately. Sorting and
- // writing PV back to TT is safe becuase RootMoves is still
+ // writing PV back to TT is safe because RootMoves is still
// valid, although it refers to previous iteration.
if (Signals.stop)
break;
TT.refresh(tte);
ss->currentMove = ttMove; // Can be MOVE_NONE
+ // Update killers, history, and counter move on TT hit
if ( ttValue >= beta
&& ttMove
&& !pos.capture_or_promotion(ttMove)
{
ss->killers[1] = ss->killers[0];
ss->killers[0] = ttMove;
+
+ Value bonus = Value(int(depth) * int(depth));
+ History.update(pos.moved_piece(ttMove), to_sq(ttMove), bonus);
+
+ if (is_ok((ss-1)->currentMove))
+ {
+ Square prevMoveSq = to_sq((ss-1)->currentMove);
+ Countermoves.update(pos.piece_on(prevMoveSq), prevMoveSq, ttMove);
+ }
}
return ttValue;
}
continue;
// At root obey the "searchmoves" option and skip moves not listed in Root
- // Move List, as a consequence any illegal move is also skipped. In MultiPV
+ // Move List. As a consequence any illegal move is also skipped. In MultiPV
// mode we also skip PV moves which have been already searched.
if (RootNode && !std::count(RootMoves.begin() + PVIdx, RootMoves.end(), move))
continue;
captureOrPromotion = pos.capture_or_promotion(move);
givesCheck = pos.gives_check(move, ci);
dangerous = givesCheck
- || pos.passed_pawn_push(move)
- || type_of(move) == CASTLING;
+ || type_of(move) != NORMAL
+ || pos.advanced_pawn_push(move);
// Step 12. Extend checks
if (givesCheck && pos.see_sign(move) >= 0)
// Step 14. Make the move
pos.do_move(move, st, ci, givesCheck);
- // Step 15. Reduced depth search (LMR). If the move fails high will be
+ // Step 15. Reduced depth search (LMR). If the move fails high it will be
// re-searched at full depth.
if ( depth >= 3 * ONE_PLY
&& !pvMove
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
+ // Research at intermediate depth if reduction is very high
+ if (value > alpha && ss->reduction >= 4 * ONE_PLY)
+ {
+ Depth d2 = std::max(newDepth - 2 * ONE_PLY, ONE_PLY);
+ value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d2, true);
+ }
+
doFullDepthSearch = (value > alpha && ss->reduction != DEPTH_ZERO);
ss->reduction = DEPTH_ZERO;
}
&& !InCheck
&& !givesCheck
&& move != ttMove
- && type_of(move) != PROMOTION
&& futilityBase > -VALUE_KNOWN_WIN
- && !pos.passed_pawn_push(move))
+ && !pos.advanced_pawn_push(move))
{
- futilityValue = futilityBase
- + PieceValue[EG][pos.piece_on(to_sq(move))]
- + (type_of(move) == ENPASSANT ? PawnValueEg : VALUE_ZERO);
+ assert(type_of(move) != ENPASSANT); // Due to !pos.advanced_pawn_push
+
+ futilityValue = futilityBase + PieceValue[EG][pos.piece_on(to_sq(move))];
if (futilityValue < beta)
{
Bitboard xray = (attacks_bb< ROOK>(m2to, occ) & pos.pieces(color_of(pc), QUEEN, ROOK))
| (attacks_bb<BISHOP>(m2to, occ) & pos.pieces(color_of(pc), QUEEN, BISHOP));
- // Verify attackers are triggered by our move and not already exist
+ // Verify attackers are triggered by our move and not already existing
if (unlikely(xray) && (xray & ~pos.attacks_from<QUEEN>(m2to)))
return true;
}