diff --git a/millgame.vcxproj b/millgame.vcxproj
index f0c37d6c..86ba55a2 100644
--- a/millgame.vcxproj
+++ b/millgame.vcxproj
@@ -456,7 +456,6 @@
-
@@ -720,7 +719,6 @@
-
diff --git a/millgame.vcxproj.filters b/millgame.vcxproj.filters
index 0b735fbf..b46fddfe 100644
--- a/millgame.vcxproj.filters
+++ b/millgame.vcxproj.filters
@@ -120,9 +120,6 @@
Header Files
-
- Header Files
-
Qt Files
@@ -356,9 +353,6 @@
Source Files
-
- Source Files
-
Source Files
diff --git a/src/evaluate.cpp b/src/evaluate.cpp
index 7db64294..518a8675 100644
--- a/src/evaluate.cpp
+++ b/src/evaluate.cpp
@@ -35,11 +35,6 @@ enum Tracing
NO_TRACE, TRACE
};
-double to_cp(Value v)
-{
- return double(v) / StoneValue;
-}
-
}
using namespace Trace;
@@ -176,37 +171,15 @@ Value Eval::evaluate(Position &pos)
/// a string (suitable for outputting to stdout) that contains the detailed
/// descriptions and values of each evaluation term. Useful for debugging.
-std::string Eval::trace(const Position &pos)
+std::string Eval::trace(Position &pos)
{
-#if 0
- std::memset(scores, 0, sizeof(scores));
+ Value v = Evaluation(pos).value();
- // TODO
- //pos.this_thread()->contempt = 0 // TODO: SCORE_ZERO; // Reset any dynamic contempt
-
- Value v = Evaluation(pos)->value();
-
- v = pos.side_to_move() == WHITE ? v : -v; // Trace scores are from white's point of view
+ v = pos.side_to_move() == BLACK ? v : -v; // Trace scores are from black's point of view
std::stringstream ss;
- ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
- << " Term | White | Black | Total \n"
- << " | MG EG | MG EG | MG EG \n"
- << " ------------+-------------+-------------+------------\n"
- << " Material | " << Term(MATERIAL)
- << " Imbalance | " << Term(IMBALANCE)
- << " Mobility | " << Term(MOBILITY)
- << " Threats | " << Term(THREAT)
- << " Passed | " << Term(PASSED)
- << " Space | " << Term(SPACE)
- << " Initiative | " << Term(INITIATIVE)
- << " ------------+-------------+-------------+------------\n"
- << " Total | " << Term(TOTAL);
- ss << "\nTotal evaluation: " << to_cp(v) << " (white side)\n";
+ ss << "\nTotal evaluation: " << v << " (black side)\n";
return ss.str();
-#endif
- //pos = pos;
- return "";
-}
\ No newline at end of file
+}
diff --git a/src/evaluate.h b/src/evaluate.h
index b33cfa81..c33d834c 100644
--- a/src/evaluate.h
+++ b/src/evaluate.h
@@ -28,7 +28,7 @@ class Position;
namespace Eval {
-std::string trace(const Position &pos);
+std::string trace(Position &pos);
Value evaluate(Position &pos);
};
diff --git a/src/movegen.cpp b/src/movegen.cpp
index 71129096..43dabb64 100644
--- a/src/movegen.cpp
+++ b/src/movegen.cpp
@@ -133,7 +133,6 @@ template<>
void MoveList::create()
{
// Note: Not follow order of MoveDirection array
-#if 1
const int moveTable_obliqueLine[SQUARE_NB][MD_NB] = {
/* 0 */ {0, 0, 0, 0},
/* 1 */ {0, 0, 0, 0},
@@ -227,101 +226,6 @@ void MoveList::create()
/* 38 */ {0, 0, 0, 0},
/* 39 */ {0, 0, 0, 0},
};
-#else
- const int moveTable_obliqueLine[Position::N_LOCATIONS][MD_NB] = {
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
-
- {9, 15, 0, 16},
- {10, 8, 0, 17},
- {11, 9, 0, 18},
- {12, 10, 0, 19},
- {13, 11, 0, 20},
- {14, 12, 0, 21},
- {15, 13, 0, 22},
- {8, 14, 0, 23},
-
- {17, 23, 8, 24},
- {18, 16, 9, 25},
- {19, 17, 10, 26},
- {20, 18, 11, 27},
- {21, 19, 12, 28},
- {22, 20, 13, 29},
- {23, 21, 14, 30},
- {16, 22, 15, 31},
-
- {25, 31, 16, 0},
- {26, 24, 17, 0},
- {27, 25, 18, 0},
- {28, 26, 19, 0},
- {29, 27, 20, 0},
- {30, 28, 21, 0},
- {31, 29, 22, 0},
- {24, 30, 23, 0},
-
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0}
- };
-
- const int moveTable_noObliqueLine[Position::N_LOCATIONS][MD_NB] = {
- /* 0 */ {0, 0, 0, 0},
- /* 1 */ {0, 0, 0, 0},
- /* 2 */ {0, 0, 0, 0},
- /* 3 */ {0, 0, 0, 0},
- /* 4 */ {0, 0, 0, 0},
- /* 5 */ {0, 0, 0, 0},
- /* 6 */ {0, 0, 0, 0},
- /* 7 */ {0, 0, 0, 0},
-
- /* 8 */ {9, 15, 0, 16},
- /* 9 */ {10, 8, 0, 0},
- /* 10 */ {11, 9, 0, 18},
- /* 11 */ {12, 10, 0, 0},
- /* 12 */ {13, 11, 0, 20},
- /* 13 */ {14, 12, 0, 0},
- /* 14 */ {15, 13, 0, 22},
- /* 15 */ {8, 14, 0, 0},
-
- /* 16 */ {17, 23, 8, 24},
- /* 17 */ {18, 16, 0, 0},
- /* 18 */ {19, 17, 10, 26},
- /* 19 */ {20, 18, 0, 0},
- /* 20 */ {21, 19, 12, 28},
- /* 21 */ {22, 20, 0, 0},
- /* 22 */ {23, 21, 14, 30},
- /* 23 */ {16, 22, 0, 0},
-
- /* 24 */ {25, 31, 16, 0},
- /* 25 */ {26, 24, 0, 0},
- /* 26 */ {27, 25, 18, 0},
- /* 27 */ {28, 26, 0, 0},
- /* 28 */ {29, 27, 20, 0},
- /* 29 */ {30, 28, 0, 0},
- /* 30 */ {31, 29, 22, 0},
- /* 31 */ {24, 30, 0, 0},
-
- /* 32 */ {0, 0, 0, 0},
- /* 33 */ {0, 0, 0, 0},
- /* 34 */ {0, 0, 0, 0},
- /* 35 */ {0, 0, 0, 0},
- /* 36 */ {0, 0, 0, 0},
- /* 37 */ {0, 0, 0, 0},
- /* 38 */ {0, 0, 0, 0},
- /* 39 */ {0, 0, 0, 0},
- };
-#endif
if (rule->hasObliqueLines) {
memcpy(moveTable, moveTable_obliqueLine, sizeof(moveTable));
diff --git a/src/movepick.cpp b/src/movepick.cpp
index 36acf273..1b9aa729 100644
--- a/src/movepick.cpp
+++ b/src/movepick.cpp
@@ -21,9 +21,6 @@
#include "movepick.h"
-// namespace
-// {
-
// partial_insertion_sort() sorts moves in descending order up to and including
// a given limit. The order of moves smaller than the limit is left unspecified.
void partial_insertion_sort(ExtMove *begin, ExtMove *end, int limit)
@@ -38,9 +35,6 @@ void partial_insertion_sort(ExtMove *begin, ExtMove *end, int limit)
}
}
-//}
-
-
/// Constructors of the MovePicker class. As arguments we pass information
/// to help it to return the (presumably) good moves first, to decide which
/// moves to return (in the quiescence search, for instance, we only want to
@@ -180,7 +174,7 @@ Move MovePicker::select(Pred filter)
Move MovePicker::next_move()
{
endMoves = generate(pos, moves);
- moveCount = endMoves - moves;
+ moveCount = int(endMoves - moves);
score();
partial_insertion_sort(moves, endMoves, -100); // TODO: limit = -3000 * depth
diff --git a/src/movepick.h b/src/movepick.h
index c6c70c77..eaffb7a9 100644
--- a/src/movepick.h
+++ b/src/movepick.h
@@ -107,34 +107,6 @@ enum StatsType
NoCaptures, Captures
};
-/// ButterflyHistory records how often quiet moves have been successful or
-/// unsuccessful during the current search, and is used for reduction and move
-/// ordering decisions. It uses 2 tables (one for each color) indexed by
-/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
-typedef Stats ButterflyHistory;
-
-/// LowPlyHistory at higher depths records successful quiet moves on plies 0 to 3
-/// and quiet moves which are/were in the PV (ttPv)
-/// It get cleared with each new search and get filled during iterative deepening
-constexpr int MAX_LPH = 4;
-typedef Stats LowPlyHistory;
-
-/// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous
-/// move, see www.chessprogramming.org/Countermove_Heuristic
-typedef Stats CounterMoveHistory;
-
-/// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
-typedef Stats CapturePieceToHistory;
-
-/// PieceToHistory is like ButterflyHistory but is addressed by a move's [piece][to]
-typedef Stats PieceToHistory;
-
-/// ContinuationHistory is the combined history of a given pair of moves, usually
-/// the current one given a previous one. The nested history table is based on
-/// PieceToHistory instead of ButterflyBoards.
-typedef Stats ContinuationHistory;
-
-
/// MovePicker class is used to pick one pseudo legal move at a time from the
/// current position. The most important method is next_move(), which returns a
/// new pseudo legal move each time it is called, until there are no moves left,
@@ -155,7 +127,6 @@ public:
Move next_move();
-//private:
template Move select(Pred);
template void score();
ExtMove *begin()
diff --git a/src/option.cpp b/src/option.cpp
index 7f0e0b6e..2e1c8b13 100644
--- a/src/option.cpp
+++ b/src/option.cpp
@@ -112,4 +112,3 @@ bool GameOptions::getOpeningBook()
{
return openingBook;
}
-
diff --git a/src/position.cpp b/src/position.cpp
index 2952d87c..80684bbe 100644
--- a/src/position.cpp
+++ b/src/position.cpp
@@ -125,25 +125,6 @@ std::ostream &operator<<(std::ostream &os, const Position &pos)
}
-// Marcel van Kervinck's cuckoo algorithm for fast detection of "upcoming repetition"
-// situations. Description of the algorithm in the following paper:
-// https://marcelk.net/2013-04-06/paper/upcoming-rep-v2.pdf
-
-// First and second hash functions for indexing the cuckoo tables
-inline int H1(Key h)
-{
- return h & 0x1fff;
-}
-inline int H2(Key h)
-{
- return (h >> 16) & 0x1fff;
-}
-
-// Cuckoo tables with Zobrist hashes of valid reversible moves, and the moves themselves
-Key cuckoo[8192];
-Move cuckooMove[8192];
-
-
/// Position::init() initializes at startup the various arrays used to compute
/// hash keys.
@@ -157,18 +138,11 @@ void Position::init()
Zobrist::side = rng.rand() << Zobrist::KEY_MISC_BIT >> Zobrist::KEY_MISC_BIT;
- // Prepare the cuckoo tables
- std::memset(cuckoo, 0, sizeof(cuckoo));
- std::memset(cuckooMove, 0, sizeof(cuckooMove));
-
return;
}
Position::Position()
{
- // TODO
- //st = &tmpSt;
-
construct_key();
if (rule == nullptr) {
@@ -187,7 +161,7 @@ Position::Position()
/// This function is not very robust - make sure that input FENs are correct,
/// this is assumed to be the responsibility of the GUI.
-Position &Position::set(const string &fenStr, StateInfo *si, Thread *th)
+Position &Position::set(const string &fenStr, Thread *th)
{
/*
A FEN string defines a particular position using only the ASCII character set.
@@ -220,7 +194,6 @@ Position &Position::set(const string &fenStr, StateInfo *si, Thread *th)
*/
unsigned char token;
- size_t idx;
Square sq = SQ_A1;
std::istringstream ss(fenStr);
@@ -229,9 +202,6 @@ Position &Position::set(const string &fenStr, StateInfo *si, Thread *th)
}
std::memset(this, 0, sizeof(Position));
- //std::memset(si, 0, sizeof(StateInfo));
- //std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
- //st = si;
ss >> std::noskipws;
@@ -302,7 +272,6 @@ Position &Position::set(const string &fenStr, StateInfo *si, Thread *th)
gamePly = std::max(2 * (gamePly - 1), 0) + (sideToMove == WHITE);
thisThread = th;
- //set_state(st);
assert(pos_is_ok());
out:
@@ -310,55 +279,6 @@ out:
}
-/// Position::set_state() computes the hash keys of the position, and other
-/// data that once computed is updated incrementally as moves are made.
-/// The function is only used when a new position is set up, and to verify
-/// the correctness of the StateInfo data when running in debug mode.
-
-void Position::set_state(StateInfo *si) const
-{
- // TODO
-#if 0
- si->key = 0;
-
- for (Bitboard b = pieces(); b; ) {
- Square s = pop_lsb(&b);
- Piece pc = piece_on(s);
- si->key ^= Zobrist::psq[pc][s];
- }
-
- if (sideToMove == BLACK)
- si->key ^= Zobrist::side;
-#endif
-}
-
-
- // TODO
-#if 0
-/// Position::set() is an overload to initialize the position object with
-/// the given endgame code string like "KBPKN". It is mainly a helper to
-/// get the material key out of an endgame code.
-
-Position &Position::set(const string &code, Color c, StateInfo *si)
-{
- assert(code[0] == 'K');
-
- string sides[] = { code.substr(code.find('K', 1)), // Weak
- code.substr(0, std::min(code.find('v'), code.find('K', 1))) }; // Strong
-
- assert(sides[0].length() > 0 && sides[0].length() < 8);
- assert(sides[1].length() > 0 && sides[1].length() < 8);
-
- std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
-
- string fenStr = "8/" + sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/"
- + sides[1] + char(8 - sides[1].length() + '0') + "/8 w - - 0 10";
-
- return set(fenStr, si, nullptr);
-}
-#endif
-
-
/// Position::fen() returns a FEN representation of the position. In case of
/// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
@@ -477,7 +397,7 @@ bool Position::pseudo_legal(const Move m) const
/// to a StateInfo object. The move is assumed to be legal. Pseudo-legal
/// moves should be filtered out before this function is called.
-void Position::do_move(Move m, StateInfo &newSt)
+void Position::do_move(Move m)
{
#if 0
assert(is_ok(m));
@@ -1204,27 +1124,24 @@ inline void Position::set_gameover(Color w, GameOverReason reason)
winner = w;
}
-int Position::update()
+void Position::update()
{
- int ret = -1;
int timePoint = -1;
time_t *ourSeconds = &elapsedSeconds[sideToMove];
time_t theirSeconds = elapsedSeconds[them];
if (!(phase & PHASE_PLAYING)) {
- return -1;
+ return;
}
currentTime = time(NULL);
if (timePoint >= *ourSeconds) {
- *ourSeconds = ret = timePoint;
+ *ourSeconds = timePoint;
startTime = currentTime - (elapsedSeconds[BLACK] + elapsedSeconds[WHITE]);
} else {
- *ourSeconds = ret = currentTime - startTime - theirSeconds;
+ *ourSeconds = currentTime - startTime - theirSeconds;
}
-
- return ret;
}
void Position::update_score()
diff --git a/src/position.h b/src/position.h
index fd6c8e37..a59d589b 100644
--- a/src/position.h
+++ b/src/position.h
@@ -42,17 +42,8 @@ struct StateInfo
// Not copied when making a move (will be recomputed anyhow)
Key key;
- Piece capturedPiece;
- StateInfo *previous;
- int repetition;
};
-/// A list to keep track of the position states along the setup moves (from the
-/// start position to the position just before the search starts). Needed by
-/// 'draw by repetition' detection. Use a std::deque because pointers to
-/// elements are not invalidated upon list resizing.
-typedef std::unique_ptr> StateListPtr;
-
/// Position class stores information regarding the board representation as
/// pieces, side to move, hash keys, castling info, etc. Important methods are
@@ -71,8 +62,7 @@ public:
Position &operator=(const Position &) = delete;
// FEN string input/output
- Position &set(const std::string &fenStr, StateInfo *si, Thread *th);
- Position &set(const std::string &code, Color c, StateInfo *si);
+ Position &set(const std::string &fenStr, Thread *th);
const std::string fen() const;
// Position representation
@@ -87,7 +77,7 @@ public:
Piece moved_piece(Move m) const;
// Doing and undoing moves
- void do_move(Move m, StateInfo &newSt);
+ void do_move(Move m);
void undo_move(Move m);
void undo_move(Sanmill::Stack &ss);
void do_null_move();
@@ -124,7 +114,6 @@ public:
Piece *get_board() const;
Square current_square() const;
- int get_step() const;
enum Phase get_phase() const;
enum Action get_action() const;
const char *cmd_line() const;
@@ -135,7 +124,7 @@ public:
bool start();
bool resign(Color loser);
bool command(const char *cmd);
- int update();
+ void update();
void update_score();
bool check_gameover_condition();
void remove_ban_stones();
@@ -181,11 +170,9 @@ public:
void put_piece(Piece pc, Square s);
bool put_piece(File file, Rank rank);
bool put_piece(Square s, bool updateCmdlist = false);
- bool undo_put_piece(Square s);
bool remove_piece(File file, Rank rank);
bool remove_piece(Square s, bool updateCmdlist = false);
- bool undo_remove_piece(Square s);
bool move_piece(File f1, Rank r1, File f2, Rank r2);
bool move_piece(Square from, Square to);
@@ -323,10 +310,11 @@ inline bool Position::select_piece(File f, Rank r)
return select_piece(make_square(f, r));
}
+#if 0
inline void Position::put_piece(Piece pc, Square s)
{
// TODO: put_piece
-#if 0
+
board[s] = pc;
byTypeBB[ALL_PIECES] |= s;
byTypeBB[type_of(pc)] |= s;
@@ -334,8 +322,8 @@ inline void Position::put_piece(Piece pc, Square s)
index[s] = pieceCount[pc]++;
pieceList[pc][index[s]] = s;
pieceCount[make_piece(color_of(pc), ALL_PIECES)]++;
-#endif
}
+#endif
inline bool Position::put_piece(File f, Rank r)
{
diff --git a/src/rule.h b/src/rule.h
index e3ee539b..09d82009 100644
--- a/src/rule.h
+++ b/src/rule.h
@@ -44,4 +44,3 @@ extern const struct Rule RULES[N_RULES];
extern const struct Rule *rule;
#endif /* RULE_H */
-
diff --git a/src/search.cpp b/src/search.cpp
index 00eeaeee..b6bb0e40 100644
--- a/src/search.cpp
+++ b/src/search.cpp
@@ -31,7 +31,6 @@
#include "position.h"
#include "search.h"
#include "thread.h"
-#include "timeman.h"
#include "tt.h"
#include "uci.h"
@@ -39,21 +38,6 @@
#include "types.h"
#include "option.h"
-namespace Search
-{
-LimitsType Limits;
-}
-
-namespace Tablebases
-{
-int Cardinality;
-bool RootInTB;
-bool UseRule50;
-Depth ProbeDepth;
-}
-
-namespace TB = Tablebases;
-
using std::string;
using Eval::evaluate;
using namespace Search;
@@ -69,100 +53,6 @@ enum NodeType
NonPV, PV
};
-// Skill structure is used to implement strength limit
-struct Skill
-{
- explicit Skill(int l) : level(l)
- {
- }
- bool enabled() const
- {
- return level < 20;
- }
- bool time_to_pick(Depth depth) const
- {
- return depth == 1 + level;
- }
- Move pick_best(size_t multiPV);
-
- int level;
- Move best = MOVE_NONE;
-};
-
-// Breadcrumbs are used to mark nodes as being searched by a given thread
-struct Breadcrumb
-{
- std::atomic thread;
- std::atomic key;
-};
-std::array breadcrumbs;
-
-// ThreadHolding structure keeps track of which thread left breadcrumbs at the given
-// node for potential reductions. A free node will be marked upon entering the moves
-// loop by the constructor, and unmarked upon leaving that loop by the destructor.
-struct ThreadHolding
-{
- explicit ThreadHolding(Thread *thisThread, Key posKey, int ply)
- {
- location = ply < 8 ? &breadcrumbs[posKey & (breadcrumbs.size() - 1)] : nullptr;
- otherThread = false;
- owning = false;
- if (location) {
- // See if another already marked this location, if not, mark it ourselves
- Thread *tmp = (*location).thread.load(std::memory_order_relaxed);
- if (tmp == nullptr) {
- (*location).thread.store(thisThread, std::memory_order_relaxed);
- (*location).key.store(posKey, std::memory_order_relaxed);
- owning = true;
- } else if (tmp != thisThread
- && (*location).key.load(std::memory_order_relaxed) == posKey)
- otherThread = true;
- }
- }
-
- ~ThreadHolding()
- {
- if (owning) // Free the marked location
- (*location).thread.store(nullptr, std::memory_order_relaxed);
- }
-
- bool marked()
- {
- return otherThread;
- }
-
-private:
- Breadcrumb *location;
- bool otherThread, owning;
-};
-
-template
-Value search(Position &pos, Stack *ss, Value alpha, Value beta, Depth depth, bool cutNode);
-
-// perft() is our utility to verify move generation. All the leaf nodes up
-// to the given depth are generated and counted, and the sum is returned.
-template
-uint64_t perft(Position &pos, Depth depth)
-{
- StateInfo st;
- uint64_t cnt, nodes = 0;
- const bool leaf = (depth == 2);
-
- for (const auto &m : MoveList(pos)) {
- if (Root && depth <= 1)
- cnt = 1, nodes++;
- else {
- pos.do_move(m, st);
- cnt = leaf ? MoveList(pos).size() : perft(pos, depth - 1);
- nodes += cnt;
- pos.undo_move(m);
- }
- if (Root)
- sync_cout << UCI::move(m) << ": " << cnt << sync_endl;
- }
- return nodes;
-}
-
} // namespace
@@ -180,7 +70,6 @@ void Search::clear()
{
Threads.main()->wait_for_search_finished();
- Time.availableNodes = 0;
#ifdef TRANSPOSITION_TABLE_ENABLE
TT.clear();
#endif
@@ -188,106 +77,6 @@ void Search::clear()
}
-/// MainThread::search() is started when the program receives the UCI 'go'
-/// command. It searches from the root position and outputs the "bestmove".
-
-int MainThread::search()
-{
- if (Limits.perft) {
- nodes = perft(*rootPos, Limits.perft);
- sync_cout << "\nNodes searched: " << nodes << "\n" << sync_endl;
- return 0;
- }
-
- Color us = rootPos->side_to_move();
- Time.init(Limits, us, rootPos->game_ply());
- //TT.new_search();
-
- if (rootMoves.empty()) {
- rootMoves.emplace_back(MOVE_NONE);
- sync_cout << "info depth 0 score "
- << UCI::value(rootPos->get_phase() == PHASE_GAMEOVER ? -VALUE_MATE : VALUE_DRAW) // TODO
- << sync_endl;
- } else {
- for (Thread *th : Threads) {
- th->bestMoveChanges = 0;
- if (th != this)
- th->start_searching();
- }
-
- Thread::search(); // Let's start searching!
- }
-
- // When we reach the maximum depth, we can arrive here without a raise of
- // Threads.stop. However, if we are pondering or in an infinite search,
- // the UCI protocol states that we shouldn't print the best move before the
- // GUI sends a "stop" or "ponderhit" command. We therefore simply wait here
- // until the GUI sends one of those commands.
-
- while (!Threads.stop && (ponder || Limits.infinite)) {
- } // Busy wait for a stop or a ponder reset
-
- // Stop the threads if not already stopped (also raise the stop if
- // "ponderhit" just reset Threads.ponder).
- Threads.stop = true;
-
- // Wait until all threads have finished
- for (Thread *th : Threads)
- if (th != this)
- th->wait_for_search_finished();
-
- // When playing in 'nodes as time' mode, subtract the searched nodes from
- // the available ones before exiting.
- if (Limits.npmsec)
- Time.availableNodes += Limits.inc[us] - Threads.nodes_searched();
-
- Thread *bestThread = this;
-
- // Check if there are threads with a better score than main thread
- if (Options["MultiPV"] == 1
- && !Limits.depth
- && !(Skill((int)Options["Skill Level"]).enabled() || Options["UCI_LimitStrength"])
- && rootMoves[0].pv[0] != MOVE_NONE) {
- std::map votes;
- Value minScore = this->rootMoves[0].score;
-
- // Find minimum score
- for (Thread *th : Threads)
- minScore = std::min(minScore, th->rootMoves[0].score);
-
- // Vote according to score and depth, and select the best thread
- for (Thread *th : Threads) {
- votes[th->rootMoves[0].pv[0]] +=
- (th->rootMoves[0].score - minScore + 14) * int(th->completedDepth);
-
- if (abs(bestThread->rootMoves[0].score) >= VALUE_TB_WIN_IN_MAX_PLY) {
- // Make sure we pick the shortest mate / TB conversion or stave off mate the longest
- if (th->rootMoves[0].score > bestThread->rootMoves[0].score)
- bestThread = th;
- } else if (th->rootMoves[0].score >= VALUE_TB_WIN_IN_MAX_PLY
- || (th->rootMoves[0].score > VALUE_TB_LOSS_IN_MAX_PLY
- && votes[th->rootMoves[0].pv[0]] > votes[bestThread->rootMoves[0].pv[0]]))
- bestThread = th;
- }
- }
-
- bestPreviousScore = bestThread->rootMoves[0].score;
-
- // Send again PV info if we have a new best thread
- if (bestThread != this)
- sync_cout << UCI::pv(bestThread->rootPos, bestThread->completedDepth, -VALUE_INFINITE, VALUE_INFINITE) << sync_endl;
-
- sync_cout << "bestmove " << UCI::move(bestThread->rootMoves[0].pv[0]);
-
- if (bestThread->rootMoves[0].pv.size() > 1 /* || bestThread->rootMoves[0].extract_ponder_from_tt(rootPos) */)
- std::cout << " ponder " << UCI::move(bestThread->rootMoves[0].pv[1]);
-
- std::cout << sync_endl;
-
- return 0;
-}
-
-
/// Thread::search() is the main iterative deepening loop. It calls search()
/// repeatedly with increasing depth until the allocated thinking time has been
/// consumed, the user stops the search, or the maximum search depth is reached.
@@ -405,158 +194,17 @@ int Thread::search()
}
-namespace
-{
-
-// search<>() is the main search function for both PV and non-PV nodes
-
-template
-Value search(Position &pos, Stack *ss, Value alpha, Value beta, Depth depth, bool cutNode)
-{
- //return MTDF(rootPos, ss, value, i, adjustedDepth, bestMove); // TODO;
- return VALUE_DRAW;
-}
-
-
-// When playing with strength handicap, choose best move among a set of RootMoves
-// using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.
-
-Move Skill::pick_best(size_t multiPV)
-{
-
- const RootMoves &rootMoves = Threads.main()->rootMoves;
- static PRNG rng(now()); // PRNG sequence should be non-deterministic
-
- // RootMoves are already sorted by score in descending order
- Value topScore = rootMoves[0].score;
- //int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValueMg);
- int delta = std::min(topScore - rootMoves[multiPV - 1].score, StoneValue);
- int weakness = 120 - 2 * level;
- int maxScore = -VALUE_INFINITE;
-
- // Choose best move. For each move score we add two terms, both dependent on
- // weakness. One is deterministic and bigger for weaker levels, and one is
- // random. Then we choose the move with the resulting highest score.
- for (size_t i = 0; i < multiPV; ++i) {
- // This is our magic formula
- int push = (weakness * int(topScore - rootMoves[i].score)
- + delta * (rng.rand() % weakness)) / 128;
-
- if (rootMoves[i].score + push >= maxScore) {
- maxScore = rootMoves[i].score + push;
- best = rootMoves[i].pv[0];
- }
- }
-
- return best;
-}
-
-} // namespace
-
-/// MainThread::check_time() is used to print debug info and, more importantly,
-/// to detect when we are out of available time and thus stop the search.
-
-void MainThread::check_time()
-{
- if (--callsCnt > 0)
- return;
-
- // When using nodes, ensure checking rate is not lower than 0.1% of nodes
- callsCnt = Limits.nodes ? std::min(1024, int(Limits.nodes / 1024)) : 1024;
-
- static TimePoint lastInfoTime = now();
-
- TimePoint elapsed = Time.elapsed();
- TimePoint tick = Limits.startTime + elapsed;
-
- if (tick - lastInfoTime >= 1000) {
- lastInfoTime = tick;
- dbg_print();
- }
-
- // We should not stop pondering until told so by the GUI
- if (ponder)
- return;
-
- if ((Limits.use_time_management() && (elapsed > Time.maximum() - 10 || stopOnPonderhit))
- || (Limits.movetime && elapsed >= Limits.movetime)
- || (Limits.nodes && Threads.nodes_searched() >= (uint64_t)Limits.nodes))
- Threads.stop = true;
-}
-
-
-/// UCI::pv() formats PV information according to the UCI protocol. UCI requires
-/// that all (if any) unsearched PV lines are sent using a previous search score.
-
-string UCI::pv(const Position *pos, Depth depth, Value alpha, Value beta)
-{
-
- std::stringstream ss;
- TimePoint elapsed = Time.elapsed() + 1;
- const RootMoves &rootMoves = pos->this_thread()->rootMoves;
- size_t pvIdx = pos->this_thread()->pvIdx;
- size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size());
- uint64_t nodesSearched = Threads.nodes_searched();
- uint64_t tbHits = Threads.tb_hits() + (TB::RootInTB ? rootMoves.size() : 0);
-
- for (size_t i = 0; i < multiPV; ++i) {
- bool updated = rootMoves[i].score != -VALUE_INFINITE;
-
- if (depth == 1 && !updated)
- continue;
-
- Depth d = updated ? depth : depth - 1;
- Value v = updated ? rootMoves[i].score : rootMoves[i].previousScore;
-
- bool tb = TB::RootInTB && abs(v) < VALUE_MATE_IN_MAX_PLY;
- v = tb ? rootMoves[i].tbScore : v;
-
- if (ss.rdbuf()->in_avail()) // Not at first line
- ss << "\n";
-
- ss << "info"
- << " depth " << d
- << " seldepth " << rootMoves[i].selDepth
- << " multipv " << i + 1
- << " score " << UCI::value(v);
-
- if (!tb && i == pvIdx)
- ss << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
-
- ss << " nodes " << nodesSearched
- << " nps " << nodesSearched * 1000 / elapsed;
-
-#if 0
- if (elapsed > 1000) // Earlier makes little sense
- ss << " hashfull " << TT.hashfull();
-#endif
-
- ss << " tbhits " << tbHits
- << " time " << elapsed
- << " pv";
-
- for (Move m : rootMoves[i].pv)
- ss << " " << UCI::move(m);
- }
-
- return ss.str();
-}
-
-
///////////////////////////////////////////////////////////////////////////////
extern ThreadPool Threads;
vector moveHistory;
-
Value search(Position *pos, Sanmill::Stack &ss, Depth depth, Depth originDepth, Value alpha, Value beta, Move &bestMove)
{
Value value;
Value bestValue = -VALUE_INFINITE;
- StateInfo st; // TODO
-
Depth epsilon;
#ifdef TT_MOVE_ENABLE
@@ -690,7 +338,7 @@ Value search(Position *pos, Sanmill::Stack &ss, Depth depth, Depth ori
ss.push(*(pos));
Color before = pos->sideToMove;
Move move = mp.moves[i].move;
- pos->do_move(move, st);
+ pos->do_move(move);
Color after = pos->sideToMove;
if (gameOptions.getDepthExtension() == true && moveCount == 1) {
diff --git a/src/search.h b/src/search.h
index 0398e9e6..0dd3ca05 100644
--- a/src/search.h
+++ b/src/search.h
@@ -32,94 +32,10 @@
#include "stopwatch.h"
#endif
-class AIAlgorithm;
-class Node;
-class Position;
-class MovePicker;
-
using namespace std;
-using namespace CTSL;
namespace Search
{
-/// Threshold used for countermoves based pruning
-constexpr int CounterMovePruneThreshold = 0;
-
-
-/// Stack struct keeps track of the information we need to remember from nodes
-/// shallower and deeper in the tree during the search. Each search thread has
-/// its own array of Stack objects, indexed by the current ply.
-
-struct Stack
-{
- Move *pv;
- PieceToHistory *continuationHistory;
- int ply;
- Move currentMove;
- Move excludedMove;
- Move killers[2];
- Value staticEval;
- int statScore;
- int moveCount;
-};
-
-
-/// RootMove struct is used for moves at the root of the tree. For each root move
-/// we store a score and a PV (really a refutation in the case of moves which
-/// fail low). Score is normally set at -VALUE_INFINITE for all non-pv moves.
-
-struct RootMove
-{
- explicit RootMove(Move m) : pv(1, m)
- {
- }
- bool operator==(const Move &m) const
- {
- return pv[0] == m;
- }
- bool operator<(const RootMove &m) const
- { // Sort in descending order
- return m.score != score ? m.score < score
- : m.previousScore < previousScore;
- }
-
- Value score = -VALUE_INFINITE;
- Value previousScore = -VALUE_INFINITE;
- int selDepth = 0;
- int tbRank = 0;
- int bestMoveCount = 0;
- Value tbScore;
- std::vector pv;
-};
-
-typedef std::vector RootMoves;
-
-
-/// LimitsType struct stores information sent by GUI about available time to
-/// search the current move, maximum depth/time, or if we are in analysis mode.
-
-struct LimitsType
-{
- LimitsType()
- {
- // Init explicitly due to broken value-initialization of non POD in MSVC
- time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] = npmsec = movetime = TimePoint(0);
- movestogo = depth = mate = perft = infinite = 0;
- nodes = 0;
- }
-
- bool use_time_management() const
- {
- return !(mate | movetime | depth | nodes | perft | infinite);
- }
-
- std::vector searchmoves;
- TimePoint time[COLOR_NB], inc[COLOR_NB], npmsec, movetime, startTime;
- int movestogo, depth, mate, perft, infinite;
- int64_t nodes;
-};
-
-extern LimitsType Limits;
void init();
void clear();
diff --git a/src/thread.cpp b/src/thread.cpp
index 0f72afce..ac077989 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -53,8 +53,6 @@ Thread::Thread(size_t n
#endif
timeLimit(3600)
{
- //this->us = color;
-
wait_for_search_finished();
}
@@ -63,27 +61,17 @@ Thread::Thread(size_t n
/// for its termination. Thread should be already waiting.
Thread::~Thread()
-{
- //delete server;
- //delete client
-
+{
assert(!searching);
exit = true;
+#ifdef HOSTORY_HEURISTIC
clearHistoryScore();
+#endif // HOSTORY_HEURISTIC
start_searching();
stdThread.join();
}
-/// Thread::bestMoveCount(Move move) return best move counter for the given root move
-
-int Thread::best_move_count(Move move) const
-{
- // TODO
-
- return 0;
-}
-
/// Thread::clear() reset histories, usually before a new game
void Thread::clear()
@@ -125,24 +113,8 @@ void Thread::wait_for_search_finished()
void Thread::idle_loop()
{
-#ifdef DEBUG_MODE
- int iTemp = 0;
-#endif
-
- loggerDebug("Thread %d start\n", us);
-
bestvalue = lastvalue = VALUE_ZERO;
-#if 0
- // If OS already scheduled us on a different group than 0 then don't overwrite
- // the choice, eventually we are one of many one-threaded processes running on
- // some Windows NUMA hardware, for instance in fishtest. To make it simple,
- // just check if running threads are below a threshold, in this case all this
- // NUMA machinery is not needed.
- if (Options["Threads"] > 8)
- WinProcGroup::bindThisThread(idx);
-#endif
-
while (true) {
std::unique_lock lk(mutex);
searching = false;
@@ -183,20 +155,16 @@ void Thread::idle_loop()
strCommand = nextMove();
if (strCommand != "" && strCommand != "error!") {
emitCommand();
- } else {
- int err = 1;
}
}
#ifdef OPENING_BOOK
}
#endif
}
-
- loggerDebug("Thread %d quit\n", us);
}
-///////////////
+////////////////////////////////////////////////////////////////////////////
void Thread::setAi(Position *p)
{
@@ -517,9 +485,6 @@ void Thread::clearTT()
}
}
-
-
-
string Thread::nextMove()
{
#if 0
@@ -676,42 +641,18 @@ void ThreadPool::clear()
{
for (Thread *th : *this)
th->clear();
-
- main()->callsCnt = 0;
- main()->bestPreviousScore = VALUE_INFINITE;
- main()->previousTimeReduction = 1.0;
}
/// ThreadPool::start_thinking() wakes up main thread waiting in idle_loop() and
/// returns immediately. Main thread will wake up other threads and start the search.
-void ThreadPool::start_thinking(Position *pos, StateListPtr &states,
- const Search::LimitsType &limits, bool ponderMode)
+void ThreadPool::start_thinking(Position *pos, bool ponderMode)
{
main()->wait_for_search_finished();
-// main()->stopOnPonderhit = stop = false;
-// increaseDepth = true;
-// main()->ponder = ponderMode;
-// Search::Limits = limits;
-// Search::RootMoves rootMoves;
-
-// for (const auto &m : MoveList(*pos))
-// if (limits.searchmoves.empty()
-// || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m))
-// rootMoves.emplace_back(m);
-
-#ifdef TBPROBE
- if (!rootMoves.empty())
- Tablebases::rank_root_moves(pos, rootMoves);
-#endif
-
- // After ownership transfer 'states' becomes empty, so if we stop the search
- // and call 'go' again without setting a new position states.get() == NULL.
- //assert(states.get() || setupStates.get());
-
- //if (states.get())
- // setupStates = std::move(states); // Ownership transfer, states is now empty
+ main()->stopOnPonderhit = stop = false;
+ increaseDepth = true;
+ main()->ponder = ponderMode;
// We use Position::set() to set root position across threads. But there are
// some StateInfo fields (previous, pliesFromNull, capturedPiece) that cannot
@@ -721,14 +662,10 @@ void ThreadPool::start_thinking(Position *pos, StateListPtr &states,
//StateInfo tmp = setupStates->back();
for (Thread *th : *this) {
- //th->nodes = th->tbHits = th->nmpMinPly = 0;
- //th->rootDepth = th->completedDepth = 0;
- //th->rootMoves = rootMoves;
+ // TODO
//th->rootPos->set(pos->fen(), &setupStates->back(), th);
th->rootPos = pos;
}
- //setupStates->back() = tmp;
-
main()->start_searching();
}
diff --git a/src/thread.h b/src/thread.h
index b9a7f340..5be1fc3e 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -64,17 +64,8 @@ public:
void idle_loop();
void start_searching();
void wait_for_search_finished();
- int best_move_count(Move move) const;
-
- size_t pvIdx, pvLast;
- uint64_t ttHitAverage;
- int selDepth, nmpMinPly;
- Color nmpColor;
- std::atomic nodes, tbHits, bestMoveChanges;
Position *rootPos { nullptr };
- Search::RootMoves rootMoves;
- Depth rootDepth, completedDepth;
// Mill Game
@@ -167,12 +158,6 @@ struct MainThread : public Thread
{
using Thread::Thread;
- int search() /* override */;
- void check_time();
-
- double previousTimeReduction;
- Value bestPreviousScore;
- Value iterValue[4];
int callsCnt;
bool stopOnPonderhit;
std::atomic_bool ponder;
@@ -185,7 +170,7 @@ struct MainThread : public Thread
struct ThreadPool : public std::vector
{
- void start_thinking(Position *, StateListPtr &, const Search::LimitsType &, bool = false);
+ void start_thinking(Position *, bool = false);
void clear();
void set(size_t);
@@ -193,20 +178,10 @@ struct ThreadPool : public std::vector
{
return static_cast(front());
}
- uint64_t nodes_searched() const
- {
- return accumulate(&Thread::nodes);
- }
- uint64_t tb_hits() const
- {
- return accumulate(&Thread::tbHits);
- }
std::atomic_bool stop, increaseDepth;
private:
- StateListPtr setupStates;
-
uint64_t accumulate(std::atomic Thread:: *member) const
{
uint64_t sum = 0;
diff --git a/src/timeman.cpp b/src/timeman.cpp
deleted file mode 100644
index d6aed47e..00000000
--- a/src/timeman.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- Fishmill, a UCI Mill Game playing engine derived from Stockfish
- Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
- Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad (Stockfish author)
- Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad (Stockfish author)
- Copyright (C) 2020 Calcitem
-
- Fishmill 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.
-
- Fishmill 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.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#include
-#include
-#include
-
-#include "search.h"
-#include "timeman.h"
-#include "uci.h"
-
-TimeManagement Time; // Our global time management object
-
-namespace
-{
-
-enum TimeType
-{
- OptimumTime, MaxTime
-};
-
-constexpr int MoveHorizon = 50; // Plan time management at most this many moves ahead
-constexpr double MaxRatio = 7.3; // When in trouble, we can step over reserved time with this ratio
-constexpr double StealRatio = 0.34; // However we must not steal time from remaining moves over this ratio
-
-
-// move_importance() is a skew-logistic function based on naive statistical
-// analysis of "how many games are still undecided after n half-moves". Game
-// is considered "undecided" as long as neither side has >275cp advantage.
-// Data was extracted from the CCRL game database with some simple filtering criteria.
-
-double move_importance(int ply)
-{
- constexpr double XScale = 6.85;
- constexpr double XShift = 64.5;
- constexpr double Skew = 0.171;
-
- return pow((1 + exp((ply - XShift) / XScale)), -Skew) + DBL_MIN; // Ensure non-zero
-}
-
-template
-TimePoint remaining(TimePoint myTime, int movesToGo, int ply, TimePoint slowMover)
-{
- constexpr double TMaxRatio = (T == OptimumTime ? 1.0 : MaxRatio);
- constexpr double TStealRatio = (T == OptimumTime ? 0.0 : StealRatio);
-
- double moveImportance = (move_importance(ply) * slowMover) / 100.0;
- double otherMovesImportance = 0.0;
-
- for (int i = 1; i < movesToGo; ++i)
- otherMovesImportance += move_importance(ply + 2 * i);
-
- double ratio1 = (TMaxRatio * moveImportance) / (TMaxRatio * moveImportance + otherMovesImportance);
- double ratio2 = (moveImportance + TStealRatio * otherMovesImportance) / (moveImportance + otherMovesImportance);
-
- return TimePoint(myTime * std::min(ratio1, ratio2)); // Intel C++ asks for an explicit cast
-}
-
-} // namespace
-
-
-/// init() is called at the beginning of the search and calculates the allowed
-/// thinking time out of the time control and current game ply. We support four
-/// different kinds of time controls, passed in 'limits':
-///
-/// inc == 0 && movestogo == 0 means: x basetime [sudden death!]
-/// inc == 0 && movestogo != 0 means: x moves in y minutes
-/// inc > 0 && movestogo == 0 means: x basetime + z increment
-/// inc > 0 && movestogo != 0 means: x moves in y minutes + z increment
-
-void TimeManagement::init(Search::LimitsType &limits, Color us, int ply)
-{
- TimePoint minThinkingTime = (TimePoint)Options["Minimum Thinking Time"];
- TimePoint moveOverhead = (TimePoint)Options["Move Overhead"];
- TimePoint slowMover = (TimePoint)Options["Slow Mover"];
- TimePoint npmsec = (TimePoint)Options["nodestime"];
- TimePoint hypMyTime;
-
- // If we have to play in 'nodes as time' mode, then convert from time
- // to nodes, and use resulting values in time management formulas.
- // WARNING: to avoid time losses, the given npmsec (nodes per millisecond)
- // must be much lower than the real engine speed.
- if (npmsec) {
- if (!availableNodes) // Only once at game start
- availableNodes = npmsec * limits.time[us]; // Time is in msec
-
- // Convert from milliseconds to nodes
- limits.time[us] = TimePoint(availableNodes);
- limits.inc[us] *= npmsec;
- limits.npmsec = npmsec;
- }
-
- startTime = limits.startTime;
- optimumTime = maximumTime = std::max(limits.time[us], minThinkingTime);
-
- const int maxMTG = limits.movestogo ? std::min(limits.movestogo, MoveHorizon) : MoveHorizon;
-
- // We calculate optimum time usage for different hypothetical "moves to go" values
- // and choose the minimum of calculated search time values. Usually the greatest
- // hypMTG gives the minimum values.
- for (int hypMTG = 1; hypMTG <= maxMTG; ++hypMTG) {
- // Calculate thinking time for hypothetical "moves to go"-value
- hypMyTime = limits.time[us]
- + limits.inc[us] * (hypMTG - 1)
- - moveOverhead * (2 + std::min(hypMTG, 40));
-
- hypMyTime = std::max(hypMyTime, TimePoint(0));
-
- TimePoint t1 = minThinkingTime + remaining(hypMyTime, hypMTG, ply, slowMover);
- TimePoint t2 = minThinkingTime + remaining(hypMyTime, hypMTG, ply, slowMover);
-
- optimumTime = std::min(t1, optimumTime);
- maximumTime = std::min(t2, maximumTime);
- }
-
- if (Options["Ponder"])
- optimumTime += optimumTime / 4;
-}
diff --git a/src/timeman.h b/src/timeman.h
deleted file mode 100644
index e44a3732..00000000
--- a/src/timeman.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Fishmill, a UCI Mill Game playing engine derived from Stockfish
- Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
- Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad (Stockfish author)
- Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad (Stockfish author)
- Copyright (C) 2020 Calcitem
-
- Fishmill 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.
-
- Fishmill 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.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef TIMEMAN_H_INCLUDED
-#define TIMEMAN_H_INCLUDED
-
-#include "misc.h"
-#include "search.h"
-#include "thread.h"
-
-/// The TimeManagement class computes the optimal time to think depending on
-/// the maximum available time, the game move number and other parameters.
-
-class TimeManagement {
-public:
- void init(Search::LimitsType& limits, Color us, int ply);
- TimePoint optimum() const { return optimumTime; }
- TimePoint maximum() const { return maximumTime; }
- TimePoint elapsed() const { return Search::Limits.npmsec ?
- TimePoint(Threads.nodes_searched()) : now() - startTime; }
-
- int64_t availableNodes; // When in 'nodes as time' mode
-
-private:
- TimePoint startTime;
- TimePoint optimumTime;
- TimePoint maximumTime;
-};
-
-extern TimeManagement Time;
-
-#endif // #ifndef TIMEMAN_H_INCLUDED
diff --git a/src/tt.cpp b/src/tt.cpp
index 551ab7e1..1424e2d3 100644
--- a/src/tt.cpp
+++ b/src/tt.cpp
@@ -67,7 +67,7 @@ Value TranspositionTable::probe(const Key &key,
break;
case BOUND_UPPER:
if (tte.value8 <= alpha) {
- return alpha; // TODO: https://github.com/calcitem/NineChess/issues/25
+ return alpha; // TODO: https://github.com/calcitem/Sanmill/issues/25
}
break;
case BOUND_LOWER:
diff --git a/src/uci.cpp b/src/uci.cpp
index 2f859788..cee51c8d 100644
--- a/src/uci.cpp
+++ b/src/uci.cpp
@@ -29,7 +29,6 @@
#include "position.h"
#include "search.h"
#include "thread.h"
-#include "timeman.h"
#include "tt.h"
#include "uci.h"
@@ -41,7 +40,7 @@ namespace
{
// FEN string of the initial position, normal mill game
-const char *StartFEN = "********/********/******** b p p 0 12 0 12 0 0 1"; // Chess: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
+const char *StartFEN = "********/********/******** b p p 0 12 0 12 0 0 1";
// position() is called when engine receives the "position" UCI command.
@@ -49,7 +48,7 @@ const char *StartFEN = "********/********/******** b p p 0 12 0 12 0 0 1"; // Ch
// or the starting position ("startpos") and then makes the moves given in the
// following move list ("moves").
-void position(Position *pos, istringstream &is, StateListPtr &states)
+void position(Position *pos, istringstream &is)
{
Move m;
string token, fen;
@@ -65,13 +64,11 @@ void position(Position *pos, istringstream &is, StateListPtr &states)
else
return;
- states = StateListPtr(new std::deque(1)); // Drop old and create a new one
- pos->set(fen, &states->back(), Threads.main());
+ pos->set(fen, Threads.main());
// Parse move list (if any)
while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE) {
- states->emplace_back();
- pos->do_move(m, states->back());
+ pos->do_move(m);
}
}
@@ -104,34 +101,10 @@ void setoption(istringstream &is)
// the thinking time and other parameters from the input string, then starts
// the search.
-void go(Position *pos, istringstream &is, StateListPtr &states)
+void go(Position *pos)
{
begin:
- Search::LimitsType limits;
- string token;
- bool ponderMode = false;
-
- limits.startTime = now(); // As early as possible!
-
- while (is >> token)
- if (token == "searchmoves") // Needs to be the last command on the line
- while (is >> token)
- limits.searchmoves.push_back(UCI::to_move(pos, token));
-
- else if (token == "wtime") is >> limits.time[WHITE];
- else if (token == "btime") is >> limits.time[BLACK];
- else if (token == "winc") is >> limits.inc[WHITE];
- else if (token == "binc") is >> limits.inc[BLACK];
- else if (token == "movestogo") is >> limits.movestogo;
- else if (token == "depth") is >> limits.depth;
- else if (token == "nodes") is >> limits.nodes;
- else if (token == "movetime") is >> limits.movetime;
- else if (token == "mate") is >> limits.mate;
- else if (token == "perft") is >> limits.perft;
- else if (token == "infinite") limits.infinite = 1;
- else if (token == "ponder") ponderMode = true;
-
- Threads.start_thinking(pos, states, limits, ponderMode);
+ Threads.start_thinking(pos);
if (pos->get_phase() == PHASE_GAMEOVER)
{
@@ -140,7 +113,7 @@ begin:
{
}
- pos->set(StartFEN, &states->back(), Threads.main());
+ pos->set(StartFEN, Threads.main());
}
goto begin;
@@ -151,10 +124,10 @@ begin:
// a list of UCI commands is setup according to bench parameters, then
// it is run one by one printing a summary at the end.
-void bench(Position *pos, istream &args, StateListPtr &states)
+void bench(Position *pos, istream &args)
{
string token;
- uint64_t num, nodes = 0, cnt = 1;
+ uint64_t num, cnt = 1;
vector list = setup_bench(pos, args);
num = count_if(list.begin(), list.end(), [](string s) { return s.find("go ") == 0 || s.find("eval") == 0; });
@@ -168,13 +141,12 @@ void bench(Position *pos, istream &args, StateListPtr &states)
if (token == "go" || token == "eval") {
cerr << "\nPosition: " << cnt++ << '/' << num << endl;
if (token == "go") {
- go(pos, is, states);
+ go(pos);
Threads.main()->wait_for_search_finished();
- nodes += Threads.nodes_searched();
} else
sync_cout << "\n" << Eval::trace(*pos) << sync_endl;
} else if (token == "setoption") setoption(is);
- else if (token == "position") position(pos, is, states);
+ else if (token == "position") position(pos, is);
else if (token == "ucinewgame") {
Search::clear(); elapsed = now();
} // Search::clear() may take some while
@@ -186,8 +158,7 @@ void bench(Position *pos, istream &args, StateListPtr &states)
cerr << "\n==========================="
<< "\nTotal time (ms) : " << elapsed
- << "\nNodes searched : " << nodes
- << "\nNodes/second : " << 1000 * nodes / elapsed << endl;
+ << endl;
}
} // namespace
@@ -204,9 +175,8 @@ void UCI::loop(int argc, char *argv[])
Position *pos = new Position;
string token, cmd;
- StateListPtr states(new std::deque(1));
- pos->set(StartFEN, &states->back(), Threads.main());
+ pos->set(StartFEN, Threads.main());
for (int i = 1; i < argc; ++i)
cmd += std::string(argv[i]) + " ";
@@ -237,15 +207,15 @@ void UCI::loop(int argc, char *argv[])
<< "\nuciok" << sync_endl;
else if (token == "setoption") setoption(is);
- else if (token == "go") go(pos, is, states);
- else if (token == "position") position(pos, is, states);
+ else if (token == "go") go(pos);
+ else if (token == "position") position(pos, is);
else if (token == "ucinewgame") Search::clear();
else if (token == "isready") sync_cout << "readyok" << sync_endl;
// Additional custom non-UCI commands, mainly for debugging.
// Do not use these commands during a search!
else if (token == "flip") pos->flip();
- else if (token == "bench") bench(pos, is, states);
+ else if (token == "bench") bench(pos, is);
else if (token == "d") sync_cout << &pos << sync_endl;
else if (token == "eval") sync_cout << Eval::trace(*pos) << sync_endl;
else if (token == "compiler") sync_cout << compiler_info() << sync_endl;
diff --git a/src/uci.h b/src/uci.h
index b750c2f1..a8e835e1 100644
--- a/src/uci.h
+++ b/src/uci.h
@@ -73,7 +73,6 @@ void loop(int argc, char* argv[]);
std::string value(Value v);
std::string square(Square s);
std::string move(Move m);
-std::string pv(const Position* pos, Depth depth, Value alpha, Value beta);
Move to_move(Position* pos, std::string& str);
} // namespace UCI
diff --git a/src/ucioption.cpp b/src/ucioption.cpp
index 332fb3b7..40c55591 100644
--- a/src/ucioption.cpp
+++ b/src/ucioption.cpp
@@ -29,7 +29,6 @@
#include "thread.h"
#include "tt.h"
#include "uci.h"
-//#include "syzygy/tbprobe.h"
using std::string;
@@ -57,12 +56,6 @@ void on_threads(const Option &o)
{
Threads.set((size_t)o);
}
-#ifdef TBPROBE
-void on_tb_path(const Option &o)
-{
- Tablebases::init(o);
-}
-#endif
/// Our case insensitive less() function as required by UCI protocol
@@ -97,12 +90,6 @@ void init(OptionsMap &o)
o["UCI_AnalyseMode"] << Option(false);
o["UCI_LimitStrength"] << Option(false);
o["UCI_Elo"] << Option(1350, 1350, 2850);
-#ifdef TBPROBE
- o["SyzygyPath"] << Option("", on_tb_path);
- o["SyzygyProbeDepth"] << Option(1, 1, 100);
- o["Syzygy50MoveRule"] << Option(true);
- o["SyzygyProbeLimit"] << Option(7, 0, 7);
-#endif
}
diff --git a/src/ui/qt/gamecontroller.cpp b/src/ui/qt/gamecontroller.cpp
index 593570d5..dfa0d4fe 100644
--- a/src/ui/qt/gamecontroller.cpp
+++ b/src/ui/qt/gamecontroller.cpp
@@ -1048,7 +1048,7 @@ bool GameController::command(const string &cmd, bool update /* = true */)
loggerDebug("Game Duration Time: %lldms\n", gameDurationTime);
#ifdef TIME_STAT
- loggerDebug("Sort Time: %ld + %ld = %ldms\n",
+ loggerDebug("Sort Time: %I64d + %I64d = %I64dms\n",
aiThread[BLACK]->sortTime, aiThread[WHITE]->sortTime,
(aiThread[BLACK]->sortTime + aiThread[WHITE]->sortTime));
aiThread[BLACK]->sortTime = aiThread[WHITE]->sortTime = 0;