#include <cassert>
#include <cmath>
#include <cstring>
-#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
TimeManager TimeMgr;
SearchLimits Limits;
- // Log file
- std::ofstream LogFile;
-
// Skill level adjustment
int SkillLevel;
bool SkillLevelEnabled;
if ( captureOrPromotion
&& type_of(pos.piece_on(move_to(m))) != PAWN
&& ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK)
- - piece_value_midgame(pos.piece_on(move_to(m))) == VALUE_ZERO)
+ - PieceValueMidgame[pos.piece_on(move_to(m))] == VALUE_ZERO)
&& !is_special(m))
{
result += PawnEndgameExtension[PvNode];
// Write to log file and keep it open to be accessed during the search
if (Options["Use Search Log"].value<bool>())
{
- string name = Options["Search Log Filename"].value<string>();
- LogFile.open(name.c_str(), std::ios::out | std::ios::app);
-
- if (LogFile.is_open())
- LogFile << "\nSearching: " << pos.to_fen()
- << "\ninfinite: " << Limits.infinite
- << " ponder: " << Limits.ponder
- << " time: " << Limits.time
- << " increment: " << Limits.increment
- << " moves to go: " << Limits.movesToGo
- << endl;
+ Log log(Options["Search Log Filename"].value<string>());
+ log << "\nSearching: " << pos.to_fen()
+ << "\ninfinite: " << Limits.infinite
+ << " ponder: " << Limits.ponder
+ << " time: " << Limits.time
+ << " increment: " << Limits.increment
+ << " moves to go: " << Limits.movesToGo
+ << endl;
}
// We're ready to start thinking. Call the iterative deepening loop function
Move bestMove = id_loop(pos, searchMoves, &ponderMove);
// Write final search statistics and close log file
- if (LogFile.is_open())
+ if (Options["Use Search Log"].value<bool>())
{
int t = current_search_time();
- LogFile << "Nodes: " << pos.nodes_searched()
- << "\nNodes/second: " << (t > 0 ? pos.nodes_searched() * 1000 / t : 0)
- << "\nBest move: " << move_to_san(pos, bestMove);
+ Log log(Options["Search Log Filename"].value<string>());
+ log << "Nodes: " << pos.nodes_searched()
+ << "\nNodes/second: " << (t > 0 ? pos.nodes_searched() * 1000 / t : 0)
+ << "\nBest move: " << move_to_san(pos, bestMove);
StateInfo st;
pos.do_move(bestMove, st);
- LogFile << "\nPonder move: " << move_to_san(pos, ponderMove) << endl;
+ log << "\nPonder move: " << move_to_san(pos, ponderMove) << endl;
pos.undo_move(bestMove); // Return from think() with unchanged position
- LogFile.close();
}
// This makes all the threads to go to sleep
if (SkillLevelEnabled && depth == 1 + SkillLevel)
do_skill_level(&skillBest, &skillPonder);
- if (LogFile.is_open())
- LogFile << pretty_pv(pos, depth, value, current_search_time(), &Rml[0].pv[0]) << endl;
+ if (Options["Use Search Log"].value<bool>())
+ {
+ Log log(Options["Search Log Filename"].value<string>());
+ log << pretty_pv(pos, depth, value, current_search_time(), &Rml[0].pv[0]) << endl;
+ }
// Init easyMove at first iteration or drop it if differs from the best move
if (depth == 1 && (Rml.size() == 1 || Rml[0].score > Rml[1].score + EasyMoveMargin))
if (refinedValue - PawnValueMidgame > beta)
R++;
- pos.do_null_move(st);
+ pos.do_null_move<true>(st);
(ss+1)->skipNullMove = true;
nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
: - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY);
(ss+1)->skipNullMove = false;
- pos.undo_null_move();
+ pos.do_null_move<false>(st);
if (nullValue >= beta)
{
}
// Step 20. Check for mate and stalemate
- // All legal moves have been searched and if there are
- // no legal moves, it must be mate or stalemate.
- // If one move was excluded return fail low score.
+ // All legal moves have been searched and if there are no legal moves, it
+ // must be mate or stalemate. Note that we can have a false positive in
+ // case of StopRequest or thread.cutoff_occurred() are set, but this is
+ // harmless because return value is discarded anyhow in the parent nodes.
+ // If we are in a singular extension search then return a fail low score.
if (!SpNode && !moveCount)
return excludedMove ? oldAlpha : inCheck ? value_mated_in(ss->ply) : VALUE_DRAW;
&& !pos.is_passed_pawn_push(move))
{
futilityValue = futilityBase
- + piece_value_endgame(pos.piece_on(move_to(move)))
+ + PieceValueEndgame[pos.piece_on(move_to(move))]
+ (is_enpassant(move) ? PawnValueEndgame : VALUE_ZERO);
if (futilityValue < beta)
while (b)
{
victimSq = pop_1st_bit(&b);
- futilityValue = futilityBase + piece_value_endgame(pos.piece_on(victimSq));
+ futilityValue = futilityBase + PieceValueEndgame[pos.piece_on(victimSq)];
// Note that here we generate illegal "double move"!
if ( futilityValue >= beta
// Case 2: If the threatened piece has value less than or equal to the
// value of the threatening piece, don't prune moves which defend it.
if ( pos.is_capture(threat)
- && ( piece_value_midgame(pos.piece_on(tfrom)) >= piece_value_midgame(pos.piece_on(tto))
+ && ( PieceValueMidgame[pos.piece_on(tfrom)] >= PieceValueMidgame[pos.piece_on(tto)]
|| type_of(pos.piece_on(tfrom)) == KING)
&& pos.move_attacks_square(m, tto))
return true;