/*
- Glaurung, a UCI chess playing engine.
- Copyright (C) 2004-2008 Tord Romstad
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008 Marco Costalba
- Glaurung is free software: you can redistribute it and/or modify
+ Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
- Glaurung is distributed in the hope that it will be useful,
+ Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
public:
RootMoveList(Position &pos, Move searchMoves[]);
- Move get_move(int moveNum) const;
- Value get_move_score(int moveNum) const;
- void set_move_score(int moveNum, Value score);
- void set_move_nodes(int moveNum, int64_t nodes);
+ inline Move get_move(int moveNum) const;
+ inline Value get_move_score(int moveNum) const;
+ inline void set_move_score(int moveNum, Value score);
+ inline void set_move_nodes(int moveNum, int64_t nodes);
void set_move_pv(int moveNum, const Move pv[]);
- Move get_move_pv(int moveNum, int i) const;
- int64_t get_move_cumulative_nodes(int moveNum) const;
- int move_count() const;
+ inline Move get_move_pv(int moveNum, int i) const;
+ inline int64_t get_move_cumulative_nodes(int moveNum) const;
+ inline int move_count() const;
Move scan_for_easy_move() const;
- void sort();
+ inline void sort();
void sort_multipv(int n);
private:
Depth RazorDepth = 4*OnePly;
Value RazorMargin = Value(0x300);
+ // Last seconds noise filtering (LSN)
+ bool UseLSNFiltering = false;
+ bool looseOnTime = false;
+ int LSNTime = 4 * 1000; // In milliseconds
+ Value LSNValue = Value(0x200);
+
// Extensions. Array index 0 is used at non-PV nodes, index 1 at PV nodes.
Depth CheckExtension[2] = {OnePly, OnePly};
Depth SingleReplyExtension[2] = {OnePly / 2, OnePly / 2};
/// Functions
- void id_loop(const Position &pos, Move searchMoves[]);
+ Value id_loop(const Position &pos, Move searchMoves[]);
Value root_search(Position &pos, SearchStack ss[], RootMoveList &rml);
Value search_pv(Position &pos, SearchStack ss[], Value alpha, Value beta,
Depth depth, int ply, int threadID);
//// Functions
////
-/// think() is the external interface to Glaurung's search, and is called when
+/// think() is the external interface to Stockfish's search, and is called when
/// the program receives the UCI 'go' command. It initializes various
/// search-related global variables, and calls root_search()
RazorDepth = (get_option_value_int("Maximum Razoring Depth") + 1) * OnePly;
RazorMargin = value_from_centipawns(get_option_value_int("Razoring Margin"));
+ UseLSNFiltering = get_option_value_bool("LSN filtering");
+ LSNTime = get_option_value_int("LSN Time Margin (sec)") * 1000;
+ LSNValue = value_from_centipawns(get_option_value_int("LSN Value Margin"));
+
MinimumSplitDepth = get_option_value_int("Minimum Split Depth") * OnePly;
MaxThreadsPerSplitPoint =
get_option_value_int("Maximum Number of Threads per Split Point");
int myTime = time[side_to_move];
int myIncrement = increment[side_to_move];
int oppTime = time[1 - side_to_move];
-
+
TimeAdvantage = myTime - oppTime;
if(!movesToGo) { // Sudden death time control
// We're ready to start thinking. Call the iterative deepening loop
// function:
- id_loop(pos, searchMoves);
+ if (!looseOnTime)
+ {
+ Value v = id_loop(pos, searchMoves);
+ looseOnTime = ( UseLSNFiltering
+ && myTime < LSNTime
+ && myIncrement == 0
+ && v < -LSNValue);
+ }
+ else
+ {
+ looseOnTime = false; // reset for next match
+ while (SearchStartTime + myTime + 1000 > get_system_time())
+ ; // wait here
+ id_loop(pos, searchMoves); // to fail gracefully
+ }
if(UseLogFile)
LogFile.close();
// been consumed, the user stops the search, or the maximum search depth is
// reached.
- void id_loop(const Position &pos, Move searchMoves[]) {
+ Value id_loop(const Position &pos, Move searchMoves[]) {
Position p(pos);
SearchStack ss[PLY_MAX_PLUS_2];
LogFile << "Ponder move: " << move_to_san(p, ss[0].pv[1]) << '\n';
LogFile << std::endl;
}
+ return rml.get_move_score(0);
}
}
}
// Null move search not allowed, try razoring
- else if (depth < RazorDepth && approximateEval < beta - RazorMargin)
+ else if ( (approximateEval < beta - RazorMargin && depth < RazorDepth)
+ ||(approximateEval < beta - PawnValueMidgame && depth <= OnePly))
{
Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
if (v < beta)
{
lastInfoTime = t;
lock_grab(&IOLock);
+ if (dbg_show_mean)
+ dbg_print_mean();
+
+ if (dbg_show_hit_rate)
+ dbg_print_hit_rate();
+
std::cout << "info nodes " << nodes_searched() << " nps " << nps()
<< " time " << t << " hashfull " << TT.full() << std::endl;
lock_release(&IOLock);
bool overTime = t > AbsoluteMaxSearchTime
|| (RootMoveNumber == 1 && t > MaxSearchTime + ExtraSearchTime)
- || ( !FailHigh && !fail_high_ply_1() && !Problem
+ || ( !FailHigh && !fail_high_ply_1() && !Problem
&& t > 6*(MaxSearchTime + ExtraSearchTime));
if ( (Iteration >= 2 && (!InfiniteSearch && overTime))