mirror of
https://github.com/sockspls/badfish
synced 2025-07-13 12:39:16 +00:00
Syzygy pull (#639)
* factorize repetitive code in calc_key() and calc_key_from_pcs() and do some cleanup while at it. * sync with master No functional change.
This commit is contained in:
parent
e8610fbe7c
commit
a037e20f28
13 changed files with 118 additions and 161 deletions
|
@ -144,10 +144,12 @@ void benchmark(const Position& current, istream& is) {
|
||||||
|
|
||||||
uint64_t nodes = 0;
|
uint64_t nodes = 0;
|
||||||
TimePoint elapsed = now();
|
TimePoint elapsed = now();
|
||||||
|
Position pos;
|
||||||
|
|
||||||
for (size_t i = 0; i < fens.size(); ++i)
|
for (size_t i = 0; i < fens.size(); ++i)
|
||||||
{
|
{
|
||||||
Position pos(fens[i], Options["UCI_Chess960"], Threads.main());
|
StateListPtr states(new std::vector<StateInfo>(1));
|
||||||
|
pos.set(fens[i], Options["UCI_Chess960"], &states->back(), Threads.main());
|
||||||
|
|
||||||
cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl;
|
cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl;
|
||||||
|
|
||||||
|
@ -156,9 +158,8 @@ void benchmark(const Position& current, istream& is) {
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Search::StateStackPtr st;
|
|
||||||
limits.startTime = now();
|
limits.startTime = now();
|
||||||
Threads.start_thinking(pos, limits, st);
|
Threads.start_thinking(pos, states, limits);
|
||||||
Threads.main()->wait_for_search_finished();
|
Threads.main()->wait_for_search_finished();
|
||||||
nodes += Threads.nodes_searched();
|
nodes += Threads.nodes_searched();
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,8 @@ namespace {
|
||||||
string fen = sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/8/8/"
|
string fen = sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/8/8/"
|
||||||
+ sides[1] + char(8 - sides[1].length() + '0') + " w - - 0 10";
|
+ sides[1] + char(8 - sides[1].length() + '0') + " w - - 0 10";
|
||||||
|
|
||||||
return Position(fen, false, nullptr).material_key();
|
StateInfo st;
|
||||||
|
return Position().set(fen, false, &st, nullptr).material_key();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -155,42 +155,11 @@ void Position::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Position::operator=() creates a copy of 'pos' but detaching the state pointer
|
|
||||||
/// from the source to be self-consistent and not depending on any external data.
|
|
||||||
|
|
||||||
Position& Position::operator=(const Position& pos) {
|
|
||||||
|
|
||||||
std::memcpy(this, &pos, sizeof(Position));
|
|
||||||
std::memcpy(&startState, st, sizeof(StateInfo));
|
|
||||||
st = &startState;
|
|
||||||
nodes = 0;
|
|
||||||
|
|
||||||
assert(pos_is_ok());
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Position::clear() erases the position object to a pristine state, with an
|
|
||||||
/// empty board, white to move, and no castling rights.
|
|
||||||
|
|
||||||
void Position::clear() {
|
|
||||||
|
|
||||||
std::memset(this, 0, sizeof(Position));
|
|
||||||
startState.epSquare = SQ_NONE;
|
|
||||||
st = &startState;
|
|
||||||
|
|
||||||
for (int i = 0; i < PIECE_TYPE_NB; ++i)
|
|
||||||
for (int j = 0; j < 16; ++j)
|
|
||||||
pieceList[WHITE][i][j] = pieceList[BLACK][i][j] = SQ_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Position::set() initializes the position object with the given FEN string.
|
/// Position::set() initializes the position object with the given FEN string.
|
||||||
/// This function is not very robust - make sure that input FENs are correct,
|
/// This function is not very robust - make sure that input FENs are correct,
|
||||||
/// this is assumed to be the responsibility of the GUI.
|
/// this is assumed to be the responsibility of the GUI.
|
||||||
|
|
||||||
void Position::set(const string& fenStr, bool isChess960, Thread* th) {
|
Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Thread* th) {
|
||||||
/*
|
/*
|
||||||
A FEN string defines a particular position using only the ASCII character set.
|
A FEN string defines a particular position using only the ASCII character set.
|
||||||
|
|
||||||
|
@ -230,7 +199,11 @@ void Position::set(const string& fenStr, bool isChess960, Thread* th) {
|
||||||
Square sq = SQ_A8;
|
Square sq = SQ_A8;
|
||||||
std::istringstream ss(fenStr);
|
std::istringstream ss(fenStr);
|
||||||
|
|
||||||
clear();
|
std::memset(this, 0, sizeof(Position));
|
||||||
|
std::memset(si, 0, sizeof(StateInfo));
|
||||||
|
std::fill_n(&pieceList[0][0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
|
||||||
|
st = si;
|
||||||
|
|
||||||
ss >> std::noskipws;
|
ss >> std::noskipws;
|
||||||
|
|
||||||
// 1. Piece placement
|
// 1. Piece placement
|
||||||
|
@ -291,6 +264,8 @@ void Position::set(const string& fenStr, bool isChess960, Thread* th) {
|
||||||
if (!(attackers_to(st->epSquare) & pieces(sideToMove, PAWN)))
|
if (!(attackers_to(st->epSquare) & pieces(sideToMove, PAWN)))
|
||||||
st->epSquare = SQ_NONE;
|
st->epSquare = SQ_NONE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
st->epSquare = SQ_NONE;
|
||||||
|
|
||||||
// 5-6. Halfmove clock and fullmove number
|
// 5-6. Halfmove clock and fullmove number
|
||||||
ss >> std::skipws >> st->rule50 >> gamePly;
|
ss >> std::skipws >> st->rule50 >> gamePly;
|
||||||
|
@ -304,6 +279,8 @@ void Position::set(const string& fenStr, bool isChess960, Thread* th) {
|
||||||
set_state(st);
|
set_state(st);
|
||||||
|
|
||||||
assert(pos_is_ok());
|
assert(pos_is_ok());
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1108,7 +1085,7 @@ void Position::flip() {
|
||||||
std::getline(ss, token); // Half and full moves
|
std::getline(ss, token); // Half and full moves
|
||||||
f += token;
|
f += token;
|
||||||
|
|
||||||
set(f, is_chess960(), this_thread());
|
set(f, is_chess960(), st, this_thread());
|
||||||
|
|
||||||
assert(pos_is_ok());
|
assert(pos_is_ok());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef> // For offsetof()
|
#include <cstddef> // For offsetof()
|
||||||
|
#include <memory> // For std::unique_ptr
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "bitboard.h"
|
#include "bitboard.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
@ -75,6 +77,8 @@ struct StateInfo {
|
||||||
StateInfo* previous;
|
StateInfo* previous;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::unique_ptr<std::vector<StateInfo>> StateListPtr;
|
||||||
|
|
||||||
|
|
||||||
/// Position class stores information regarding the board representation as
|
/// Position class stores information regarding the board representation as
|
||||||
/// pieces, side to move, hash keys, castling info, etc. Important methods are
|
/// pieces, side to move, hash keys, castling info, etc. Important methods are
|
||||||
|
@ -86,14 +90,12 @@ class Position {
|
||||||
public:
|
public:
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
Position() = default; // To define the global object RootPos
|
Position() = default;
|
||||||
Position(const Position&) = delete;
|
Position(const Position&) = delete;
|
||||||
Position(const Position& pos, Thread* th) { *this = pos; thisThread = th; }
|
Position& operator=(const Position&) = delete;
|
||||||
Position(const std::string& f, bool c960, Thread* th) { set(f, c960, th); }
|
|
||||||
Position& operator=(const Position&); // To assign RootPos from UCI
|
|
||||||
|
|
||||||
// FEN string input/output
|
// FEN string input/output
|
||||||
void set(const std::string& fenStr, bool isChess960, Thread* th);
|
Position& set(const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th);
|
||||||
const std::string fen() const;
|
const std::string fen() const;
|
||||||
|
|
||||||
// Position representation
|
// Position representation
|
||||||
|
@ -178,7 +180,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Initialization helpers (used while setting up a position)
|
// Initialization helpers (used while setting up a position)
|
||||||
void clear();
|
|
||||||
void set_castling_right(Color c, Square rfrom);
|
void set_castling_right(Color c, Square rfrom);
|
||||||
void set_state(StateInfo* si) const;
|
void set_state(StateInfo* si) const;
|
||||||
|
|
||||||
|
@ -200,7 +201,6 @@ private:
|
||||||
int castlingRightsMask[SQUARE_NB];
|
int castlingRightsMask[SQUARE_NB];
|
||||||
Square castlingRookSquare[CASTLING_RIGHT_NB];
|
Square castlingRookSquare[CASTLING_RIGHT_NB];
|
||||||
Bitboard castlingPath[CASTLING_RIGHT_NB];
|
Bitboard castlingPath[CASTLING_RIGHT_NB];
|
||||||
StateInfo startState;
|
|
||||||
uint64_t nodes;
|
uint64_t nodes;
|
||||||
int gamePly;
|
int gamePly;
|
||||||
Color sideToMove;
|
Color sideToMove;
|
||||||
|
|
|
@ -40,7 +40,6 @@ namespace Search {
|
||||||
|
|
||||||
SignalsType Signals;
|
SignalsType Signals;
|
||||||
LimitsType Limits;
|
LimitsType Limits;
|
||||||
StateStackPtr SetupStates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Tablebases {
|
namespace Tablebases {
|
||||||
|
@ -317,16 +316,8 @@ void MainThread::search() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Thread* th : Threads)
|
for (Thread* th : Threads)
|
||||||
{
|
|
||||||
th->maxPly = 0;
|
|
||||||
th->rootDepth = DEPTH_ZERO;
|
|
||||||
if (th != this)
|
if (th != this)
|
||||||
{
|
|
||||||
th->rootPos = Position(rootPos, th);
|
|
||||||
th->rootMoves = rootMoves;
|
|
||||||
th->start_searching();
|
th->start_searching();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread::search(); // Let's start searching!
|
Thread::search(); // Let's start searching!
|
||||||
}
|
}
|
||||||
|
@ -1488,7 +1479,7 @@ moves_loop: // When in check search starts from here
|
||||||
|
|
||||||
Move Skill::pick_best(size_t multiPV) {
|
Move Skill::pick_best(size_t multiPV) {
|
||||||
|
|
||||||
const Search::RootMoveVector& rootMoves = Threads.main()->rootMoves;
|
const RootMoves& rootMoves = Threads.main()->rootMoves;
|
||||||
static PRNG rng(now()); // PRNG sequence should be non-deterministic
|
static PRNG rng(now()); // PRNG sequence should be non-deterministic
|
||||||
|
|
||||||
// RootMoves are already sorted by score in descending order
|
// RootMoves are already sorted by score in descending order
|
||||||
|
@ -1553,7 +1544,7 @@ string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) {
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
int elapsed = Time.elapsed() + 1;
|
int elapsed = Time.elapsed() + 1;
|
||||||
const Search::RootMoveVector& rootMoves = pos.this_thread()->rootMoves;
|
const RootMoves& rootMoves = pos.this_thread()->rootMoves;
|
||||||
size_t PVIdx = pos.this_thread()->PVIdx;
|
size_t PVIdx = pos.this_thread()->PVIdx;
|
||||||
size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size());
|
size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size());
|
||||||
uint64_t nodes_searched = Threads.nodes_searched();
|
uint64_t nodes_searched = Threads.nodes_searched();
|
||||||
|
|
11
src/search.h
11
src/search.h
|
@ -22,8 +22,6 @@
|
||||||
#define SEARCH_H_INCLUDED
|
#define SEARCH_H_INCLUDED
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory> // For std::unique_ptr
|
|
||||||
#include <stack>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -65,7 +63,7 @@ struct RootMove {
|
||||||
std::vector<Move> pv;
|
std::vector<Move> pv;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<RootMove> RootMoveVector;
|
typedef std::vector<RootMove> RootMoves;
|
||||||
|
|
||||||
/// LimitsType struct stores information sent by GUI about available time to
|
/// LimitsType struct stores information sent by GUI about available time to
|
||||||
/// search the current move, maximum depth/time, if we are in analysis mode or
|
/// search the current move, maximum depth/time, if we are in analysis mode or
|
||||||
|
@ -74,8 +72,8 @@ typedef std::vector<RootMove> RootMoveVector;
|
||||||
struct LimitsType {
|
struct LimitsType {
|
||||||
|
|
||||||
LimitsType() { // Init explicitly due to broken value-initialization of non POD in MSVC
|
LimitsType() { // Init explicitly due to broken value-initialization of non POD in MSVC
|
||||||
nodes = time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] = npmsec = movestogo =
|
nodes = time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] =
|
||||||
depth = movetime = mate = infinite = ponder = 0;
|
npmsec = movestogo = depth = movetime = mate = infinite = ponder = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool use_time_management() const {
|
bool use_time_management() const {
|
||||||
|
@ -95,11 +93,8 @@ struct SignalsType {
|
||||||
std::atomic_bool stop, stopOnPonderhit;
|
std::atomic_bool stop, stopOnPonderhit;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unique_ptr<std::stack<StateInfo>> StateStackPtr;
|
|
||||||
|
|
||||||
extern SignalsType Signals;
|
extern SignalsType Signals;
|
||||||
extern LimitsType Limits;
|
extern LimitsType Limits;
|
||||||
extern StateStackPtr SetupStates;
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -95,8 +95,7 @@ static char *map_file(const std::string& name, const std::string& suffix, uint64
|
||||||
#else
|
#else
|
||||||
DWORD size_low, size_high;
|
DWORD size_low, size_high;
|
||||||
size_low = GetFileSize(fd, &size_high);
|
size_low = GetFileSize(fd, &size_high);
|
||||||
HANDLE map = CreateFileMapping(fd, NULL, PAGE_READONLY, size_high, size_low,
|
HANDLE map = CreateFileMapping(fd, NULL, PAGE_READONLY, size_high, size_low, NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (map == NULL) {
|
if (map == NULL) {
|
||||||
std::cerr << "CreateFileMapping() failed\n";
|
std::cerr << "CreateFileMapping() failed\n";
|
||||||
|
@ -481,8 +480,7 @@ void free_wdl_entry(TBEntry_pawn* entry)
|
||||||
{
|
{
|
||||||
unmap_file(entry->data, entry->mapping);
|
unmap_file(entry->data, entry->mapping);
|
||||||
|
|
||||||
for (int f = 0; f < 4; f++)
|
for (int f = 0; f < 4; f++) {
|
||||||
{
|
|
||||||
free(entry->file[f].precomp[0]);
|
free(entry->file[f].precomp[0]);
|
||||||
free(entry->file[f].precomp[1]);
|
free(entry->file[f].precomp[1]);
|
||||||
}
|
}
|
||||||
|
@ -510,8 +508,7 @@ void Tablebases::init(const std::string& path)
|
||||||
free_wdl_entry(&TB_pawn[i]);
|
free_wdl_entry(&TB_pawn[i]);
|
||||||
|
|
||||||
for (int i = 0; i < DTZ_ENTRIES; i++)
|
for (int i = 0; i < DTZ_ENTRIES; i++)
|
||||||
if (DTZ_table[i].entry)
|
if (DTZ_table[i].entry) {
|
||||||
{
|
|
||||||
free_dtz_entry(DTZ_table[i].entry);
|
free_dtz_entry(DTZ_table[i].entry);
|
||||||
DTZ_table[i].entry = nullptr;
|
DTZ_table[i].entry = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -526,8 +523,7 @@ void Tablebases::init(const std::string& path)
|
||||||
|
|
||||||
// Fill binomial[] with the Binomial Coefficents using pascal triangle
|
// Fill binomial[] with the Binomial Coefficents using pascal triangle
|
||||||
// so that binomial[k-1][n] = Binomial(n, k).
|
// so that binomial[k-1][n] = Binomial(n, k).
|
||||||
for (int k = 0; k < 5; k++)
|
for (int k = 0; k < 5; k++) {
|
||||||
{
|
|
||||||
binomial[k][0] = 0;
|
binomial[k][0] = 0;
|
||||||
|
|
||||||
for (int n = 1; n < 64; n++)
|
for (int n = 1; n < 64; n++)
|
||||||
|
@ -565,20 +561,17 @@ void Tablebases::init(const std::string& path)
|
||||||
|
|
||||||
const std::string K("K");
|
const std::string K("K");
|
||||||
|
|
||||||
for (PieceType p1 = PAWN; p1 < KING; ++p1)
|
for (PieceType p1 = PAWN; p1 < KING; ++p1) {
|
||||||
{
|
|
||||||
init_tb(K + pchr[p1] + "vK");
|
init_tb(K + pchr[p1] + "vK");
|
||||||
|
|
||||||
for (PieceType p2 = PAWN; p2 <= p1; ++p2)
|
for (PieceType p2 = PAWN; p2 <= p1; ++p2) {
|
||||||
{
|
|
||||||
init_tb(K + pchr[p1] + pchr[p2] + "vK");
|
init_tb(K + pchr[p1] + pchr[p2] + "vK");
|
||||||
init_tb(K + pchr[p1] + "vK" + pchr[p2]);
|
init_tb(K + pchr[p1] + "vK" + pchr[p2]);
|
||||||
|
|
||||||
for (PieceType p3 = PAWN; p3 < KING; ++p3)
|
for (PieceType p3 = PAWN; p3 < KING; ++p3)
|
||||||
init_tb(K + pchr[p1] + pchr[p2] + "vK" + pchr[p3]);
|
init_tb(K + pchr[p1] + pchr[p2] + "vK" + pchr[p3]);
|
||||||
|
|
||||||
for (PieceType p3 = PAWN; p3 <= p2; ++p3)
|
for (PieceType p3 = PAWN; p3 <= p2; ++p3) {
|
||||||
{
|
|
||||||
init_tb(K + pchr[p1] + pchr[p2] + pchr[p3] + "vK");
|
init_tb(K + pchr[p1] + pchr[p2] + pchr[p3] + "vK");
|
||||||
|
|
||||||
for (PieceType p4 = PAWN; p4 <= p3; ++p4)
|
for (PieceType p4 = PAWN; p4 <= p3; ++p4)
|
||||||
|
@ -603,9 +596,9 @@ static uint64_t encode_piece(TBEntry_piece *ptr, uint8_t *norm, int *pos, int *f
|
||||||
int i, j, k, m, l, p;
|
int i, j, k, m, l, p;
|
||||||
int n = ptr->num;
|
int n = ptr->num;
|
||||||
|
|
||||||
if (pos[0] & 0x04) {
|
if (pos[0] & 4) {
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
pos[i] ^= 0x07;
|
pos[i] ^= 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos[0] & 0x20) {
|
if (pos[0] & 0x20) {
|
||||||
|
@ -682,7 +675,7 @@ static uint64_t encode_piece(TBEntry_piece *ptr, uint8_t *norm, int *pos, int *f
|
||||||
s += binomial[m - i][p - j];
|
s += binomial[m - i][p - j];
|
||||||
}
|
}
|
||||||
|
|
||||||
idx += ((uint64_t)s) * ((uint64_t)factor[i]);
|
idx += (uint64_t)s * ((uint64_t)factor[i]);
|
||||||
i += t;
|
i += t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +691,7 @@ static int pawn_file(TBEntry_pawn *ptr, int *pos)
|
||||||
if (flap[pos[0]] > flap[pos[i]])
|
if (flap[pos[0]] > flap[pos[i]])
|
||||||
std::swap(pos[0], pos[i]);
|
std::swap(pos[0], pos[i]);
|
||||||
|
|
||||||
return file_to_file[pos[0] & 0x07];
|
return file_to_file[pos[0] & 7];
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t encode_pawn(TBEntry_pawn *ptr, uint8_t *norm, int *pos, int *factor)
|
static uint64_t encode_pawn(TBEntry_pawn *ptr, uint8_t *norm, int *pos, int *factor)
|
||||||
|
@ -707,9 +700,9 @@ static uint64_t encode_pawn(TBEntry_pawn *ptr, uint8_t *norm, int *pos, int *fac
|
||||||
int i, j, k, m, s, t;
|
int i, j, k, m, s, t;
|
||||||
int n = ptr->num;
|
int n = ptr->num;
|
||||||
|
|
||||||
if (pos[0] & 0x04)
|
if (pos[0] & 4)
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
pos[i] ^= 0x07;
|
pos[i] ^= 7;
|
||||||
|
|
||||||
for (i = 1; i < ptr->pawns[0]; i++)
|
for (i = 1; i < ptr->pawns[0]; i++)
|
||||||
for (j = i + 1; j < ptr->pawns[0]; j++)
|
for (j = i + 1; j < ptr->pawns[0]; j++)
|
||||||
|
@ -744,7 +737,7 @@ static uint64_t encode_pawn(TBEntry_pawn *ptr, uint8_t *norm, int *pos, int *fac
|
||||||
s += binomial[m - i][p - j - 8];
|
s += binomial[m - i][p - j - 8];
|
||||||
}
|
}
|
||||||
|
|
||||||
idx += ((uint64_t)s) * ((uint64_t)factor[i]);
|
idx += (uint64_t)s * ((uint64_t)factor[i]);
|
||||||
i = t;
|
i = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,7 +759,7 @@ static uint64_t encode_pawn(TBEntry_pawn *ptr, uint8_t *norm, int *pos, int *fac
|
||||||
s += binomial[m - i][p - j];
|
s += binomial[m - i][p - j];
|
||||||
}
|
}
|
||||||
|
|
||||||
idx += ((uint64_t)s) * ((uint64_t)factor[i]);
|
idx += (uint64_t)s * ((uint64_t)factor[i]);
|
||||||
i += t;
|
i += t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,8 +1081,8 @@ static int init_table_wdl(TBEntry *entry, const std::string& str)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int split = data[4] & 0x01;
|
int split = data[4] & 1;
|
||||||
int files = data[4] & 0x02 ? 4 : 1;
|
int files = data[4] & 2 ? 4 : 1;
|
||||||
|
|
||||||
data += 5;
|
data += 5;
|
||||||
|
|
||||||
|
@ -1097,7 +1090,7 @@ static int init_table_wdl(TBEntry *entry, const std::string& str)
|
||||||
TBEntry_piece *ptr = (TBEntry_piece *)entry;
|
TBEntry_piece *ptr = (TBEntry_piece *)entry;
|
||||||
setup_pieces_piece(ptr, data, &tb_size[0]);
|
setup_pieces_piece(ptr, data, &tb_size[0]);
|
||||||
data += ptr->num + 1;
|
data += ptr->num + 1;
|
||||||
data += ((uintptr_t)data) & 0x01;
|
data += (uintptr_t)data & 1;
|
||||||
|
|
||||||
ptr->precomp[0] = setup_pairs(data, tb_size[0], &size[0], &next, &flags, 1);
|
ptr->precomp[0] = setup_pairs(data, tb_size[0], &size[0], &next, &flags, 1);
|
||||||
data = next;
|
data = next;
|
||||||
|
@ -1124,12 +1117,12 @@ static int init_table_wdl(TBEntry *entry, const std::string& str)
|
||||||
data += size[4];
|
data += size[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (uint8_t *)((((uintptr_t)data) + 0x3f) & ~0x3f);
|
data = (uint8_t *)(((uintptr_t)data + 0x3f) & ~0x3f);
|
||||||
ptr->precomp[0]->data = data;
|
ptr->precomp[0]->data = data;
|
||||||
data += size[2];
|
data += size[2];
|
||||||
|
|
||||||
if (split) {
|
if (split) {
|
||||||
data = (uint8_t *)((((uintptr_t)data) + 0x3f) & ~0x3f);
|
data = (uint8_t *)(((uintptr_t)data + 0x3f) & ~0x3f);
|
||||||
ptr->precomp[1]->data = data;
|
ptr->precomp[1]->data = data;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1141,7 +1134,7 @@ static int init_table_wdl(TBEntry *entry, const std::string& str)
|
||||||
data += ptr->num + s;
|
data += ptr->num + s;
|
||||||
}
|
}
|
||||||
|
|
||||||
data += ((uintptr_t)data) & 0x01;
|
data += (uintptr_t)data & 1;
|
||||||
|
|
||||||
for (f = 0; f < files; f++) {
|
for (f = 0; f < files; f++) {
|
||||||
ptr->file[f].precomp[0] = setup_pairs(data, tb_size[2 * f], &size[6 * f], &next, &flags, 1);
|
ptr->file[f].precomp[0] = setup_pairs(data, tb_size[2 * f], &size[6 * f], &next, &flags, 1);
|
||||||
|
@ -1175,12 +1168,12 @@ static int init_table_wdl(TBEntry *entry, const std::string& str)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (f = 0; f < files; f++) {
|
for (f = 0; f < files; f++) {
|
||||||
data = (uint8_t *)((((uintptr_t)data) + 0x3f) & ~0x3f);
|
data = (uint8_t *)(((uintptr_t)data + 0x3f) & ~0x3f);
|
||||||
ptr->file[f].precomp[0]->data = data;
|
ptr->file[f].precomp[0]->data = data;
|
||||||
data += size[6 * f + 2];
|
data += size[6 * f + 2];
|
||||||
|
|
||||||
if (split) {
|
if (split) {
|
||||||
data = (uint8_t *)((((uintptr_t)data) + 0x3f) & ~0x3f);
|
data = (uint8_t *)(((uintptr_t)data + 0x3f) & ~0x3f);
|
||||||
ptr->file[f].precomp[1]->data = data;
|
ptr->file[f].precomp[1]->data = data;
|
||||||
data += size[6 * f + 5];
|
data += size[6 * f + 5];
|
||||||
}
|
}
|
||||||
|
@ -1209,7 +1202,7 @@ static int init_table_dtz(TBEntry *entry)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int files = data[4] & 0x02 ? 4 : 1;
|
int files = data[4] & 2 ? 4 : 1;
|
||||||
|
|
||||||
data += 5;
|
data += 5;
|
||||||
|
|
||||||
|
@ -1217,7 +1210,7 @@ static int init_table_dtz(TBEntry *entry)
|
||||||
DTZEntry_piece *ptr = (DTZEntry_piece *)entry;
|
DTZEntry_piece *ptr = (DTZEntry_piece *)entry;
|
||||||
setup_pieces_piece_dtz(ptr, data, &tb_size[0]);
|
setup_pieces_piece_dtz(ptr, data, &tb_size[0]);
|
||||||
data += ptr->num + 1;
|
data += ptr->num + 1;
|
||||||
data += ((uintptr_t)data) & 0x01;
|
data += (uintptr_t)data & 1;
|
||||||
|
|
||||||
ptr->precomp = setup_pairs(data, tb_size[0], &size[0], &next, &(ptr->flags), 0);
|
ptr->precomp = setup_pairs(data, tb_size[0], &size[0], &next, &(ptr->flags), 0);
|
||||||
data = next;
|
data = next;
|
||||||
|
@ -1232,7 +1225,7 @@ static int init_table_dtz(TBEntry *entry)
|
||||||
data += 1 + data[0];
|
data += 1 + data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
data += ((uintptr_t)data) & 0x01;
|
data += (uintptr_t)data & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr->precomp->indextable = (char *)data;
|
ptr->precomp->indextable = (char *)data;
|
||||||
|
@ -1241,7 +1234,7 @@ static int init_table_dtz(TBEntry *entry)
|
||||||
ptr->precomp->sizetable = (uint16_t *)data;
|
ptr->precomp->sizetable = (uint16_t *)data;
|
||||||
data += size[1];
|
data += size[1];
|
||||||
|
|
||||||
data = (uint8_t *)((((uintptr_t)data) + 0x3f) & ~0x3f);
|
data = (uint8_t *)(((uintptr_t)data + 0x3f) & ~0x3f);
|
||||||
ptr->precomp->data = data;
|
ptr->precomp->data = data;
|
||||||
data += size[2];
|
data += size[2];
|
||||||
} else {
|
} else {
|
||||||
|
@ -1253,7 +1246,7 @@ static int init_table_dtz(TBEntry *entry)
|
||||||
data += ptr->num + s;
|
data += ptr->num + s;
|
||||||
}
|
}
|
||||||
|
|
||||||
data += ((uintptr_t)data) & 0x01;
|
data += (uintptr_t)data & 1;
|
||||||
|
|
||||||
for (f = 0; f < files; f++) {
|
for (f = 0; f < files; f++) {
|
||||||
ptr->file[f].precomp = setup_pairs(data, tb_size[f], &size[3 * f], &next, &(ptr->flags[f]), 0);
|
ptr->file[f].precomp = setup_pairs(data, tb_size[f], &size[3 * f], &next, &(ptr->flags[f]), 0);
|
||||||
|
@ -1273,7 +1266,7 @@ static int init_table_dtz(TBEntry *entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data += ((uintptr_t)data) & 0x01;
|
data += (uintptr_t)data & 1;
|
||||||
|
|
||||||
for (f = 0; f < files; f++) {
|
for (f = 0; f < files; f++) {
|
||||||
ptr->file[f].precomp->indextable = (char *)data;
|
ptr->file[f].precomp->indextable = (char *)data;
|
||||||
|
@ -1286,7 +1279,7 @@ static int init_table_dtz(TBEntry *entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (f = 0; f < files; f++) {
|
for (f = 0; f < files; f++) {
|
||||||
data = (uint8_t *)((((uintptr_t)data) + 0x3f) & ~0x3f);
|
data = (uint8_t *)(((uintptr_t)data + 0x3f) & ~0x3f);
|
||||||
ptr->file[f].precomp->data = data;
|
ptr->file[f].precomp->data = data;
|
||||||
data += size[3 * f + 2];
|
data += size[3 * f + 2];
|
||||||
}
|
}
|
||||||
|
@ -1366,7 +1359,7 @@ static uint8_t decompress_pairs(PairsData *d, uint64_t idx)
|
||||||
if (LittleEndian)
|
if (LittleEndian)
|
||||||
tmp = BSWAP32(tmp);
|
tmp = BSWAP32(tmp);
|
||||||
|
|
||||||
code |= ((uint64_t)tmp) << bitcnt;
|
code |= (uint64_t)tmp << bitcnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,17 +52,11 @@ static uint64_t calc_key(Position& pos, bool mirror)
|
||||||
{
|
{
|
||||||
uint64_t key = 0;
|
uint64_t key = 0;
|
||||||
|
|
||||||
Color color = mirror ? BLACK: WHITE;
|
for (int i = 0; i < 2; i++) {
|
||||||
|
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
||||||
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
for (int j = popcount(pos.pieces(Color(i ^ mirror), pt)); j > 0; j--)
|
||||||
for (int i = popcount(pos.pieces(color, pt)); i > 0; i--)
|
key ^= Zobrist::psq[i][pt][j - 1];
|
||||||
key ^= Zobrist::psq[WHITE][pt][i - 1];
|
}
|
||||||
|
|
||||||
color = ~color;
|
|
||||||
|
|
||||||
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
|
||||||
for (int i = popcount(pos.pieces(color, pt)); i > 0; i--)
|
|
||||||
key ^= Zobrist::psq[BLACK][pt][i - 1];
|
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -75,17 +69,11 @@ static uint64_t calc_key_from_pcs(int *pcs, bool mirror)
|
||||||
{
|
{
|
||||||
uint64_t key = 0;
|
uint64_t key = 0;
|
||||||
|
|
||||||
Color color = mirror ? BLACK : WHITE;
|
for (int i = 0; i < 2; i++) {
|
||||||
|
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
||||||
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
for (int j = 0; j < pcs[8 * (i ^ mirror) + pt]; j++)
|
||||||
for (int i = 0; i < pcs[8 * color + pt]; i++)
|
key ^= Zobrist::psq[i][pt][j];
|
||||||
key ^= Zobrist::psq[WHITE][pt][i];
|
}
|
||||||
|
|
||||||
color = ~color;
|
|
||||||
|
|
||||||
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
|
||||||
for (int i = 0; i < pcs[8 * color + pt]; i++)
|
|
||||||
key ^= Zobrist::psq[BLACK][pt][i];
|
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +177,7 @@ static int probe_wdl_table(Position& pos, int *success)
|
||||||
|
|
||||||
for (i = 0; i < entry->num;) {
|
for (i = 0; i < entry->num;) {
|
||||||
Bitboard bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
Bitboard bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
||||||
(PieceType)(pc[i] & 0x07));
|
(PieceType)(pc[i] & 7));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
p[i++] = pop_lsb(&bb);
|
p[i++] = pop_lsb(&bb);
|
||||||
|
@ -201,7 +189,7 @@ static int probe_wdl_table(Position& pos, int *success)
|
||||||
} else {
|
} else {
|
||||||
TBEntry_pawn *entry = (TBEntry_pawn *)ptr;
|
TBEntry_pawn *entry = (TBEntry_pawn *)ptr;
|
||||||
int k = entry->file[0].pieces[0][0] ^ cmirror;
|
int k = entry->file[0].pieces[0][0] ^ cmirror;
|
||||||
Bitboard bb = pos.pieces((Color)(k >> 3), (PieceType)(k & 0x07));
|
Bitboard bb = pos.pieces((Color)(k >> 3), (PieceType)(k & 7));
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -213,7 +201,7 @@ static int probe_wdl_table(Position& pos, int *success)
|
||||||
|
|
||||||
for (; i < entry->num;) {
|
for (; i < entry->num;) {
|
||||||
bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
||||||
(PieceType)(pc[i] & 0x07));
|
(PieceType)(pc[i] & 7));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
p[i++] = pop_lsb(&bb) ^ mirror;
|
p[i++] = pop_lsb(&bb) ^ mirror;
|
||||||
|
@ -224,7 +212,7 @@ static int probe_wdl_table(Position& pos, int *success)
|
||||||
res = decompress_pairs(entry->file[f].precomp[bside], idx);
|
res = decompress_pairs(entry->file[f].precomp[bside], idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((int)res) - 2;
|
return (int)res - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int probe_dtz_table(Position& pos, int wdl, int *success)
|
static int probe_dtz_table(Position& pos, int wdl, int *success)
|
||||||
|
@ -311,7 +299,7 @@ static int probe_dtz_table(Position& pos, int wdl, int *success)
|
||||||
|
|
||||||
for (i = 0; i < entry->num;) {
|
for (i = 0; i < entry->num;) {
|
||||||
Bitboard bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
Bitboard bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
||||||
(PieceType)(pc[i] & 0x07));
|
(PieceType)(pc[i] & 7));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
p[i++] = pop_lsb(&bb);
|
p[i++] = pop_lsb(&bb);
|
||||||
|
@ -329,7 +317,7 @@ static int probe_dtz_table(Position& pos, int wdl, int *success)
|
||||||
} else {
|
} else {
|
||||||
DTZEntry_pawn *entry = (DTZEntry_pawn *)ptr;
|
DTZEntry_pawn *entry = (DTZEntry_pawn *)ptr;
|
||||||
int k = entry->file[0].pieces[0] ^ cmirror;
|
int k = entry->file[0].pieces[0] ^ cmirror;
|
||||||
Bitboard bb = pos.pieces((Color)(k >> 3), (PieceType)(k & 0x07));
|
Bitboard bb = pos.pieces((Color)(k >> 3), (PieceType)(k & 7));
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -347,7 +335,7 @@ static int probe_dtz_table(Position& pos, int wdl, int *success)
|
||||||
|
|
||||||
for (; i < entry->num;) {
|
for (; i < entry->num;) {
|
||||||
bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3),
|
||||||
(PieceType)(pc[i] & 0x07));
|
(PieceType)(pc[i] & 7));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
p[i++] = pop_lsb(&bb) ^ mirror;
|
p[i++] = pop_lsb(&bb) ^ mirror;
|
||||||
|
@ -799,7 +787,7 @@ static Value wdl_to_Value[5] = {
|
||||||
//
|
//
|
||||||
// A return value false indicates that not all probes were successful and that
|
// A return value false indicates that not all probes were successful and that
|
||||||
// no moves were filtered out.
|
// no moves were filtered out.
|
||||||
bool Tablebases::root_probe(Position& pos, Search::RootMoveVector& rootMoves, Value& score)
|
bool Tablebases::root_probe(Position& pos, Search::RootMoves& rootMoves, Value& score)
|
||||||
{
|
{
|
||||||
int success;
|
int success;
|
||||||
|
|
||||||
|
@ -930,7 +918,7 @@ bool Tablebases::root_probe(Position& pos, Search::RootMoveVector& rootMoves, Va
|
||||||
//
|
//
|
||||||
// A return value false indicates that not all probes were successful and that
|
// A return value false indicates that not all probes were successful and that
|
||||||
// no moves were filtered out.
|
// no moves were filtered out.
|
||||||
bool Tablebases::root_probe_wdl(Position& pos, Search::RootMoveVector& rootMoves, Value& score)
|
bool Tablebases::root_probe_wdl(Position& pos, Search::RootMoves& rootMoves, Value& score)
|
||||||
{
|
{
|
||||||
int success;
|
int success;
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ extern int MaxCardinality;
|
||||||
void init(const std::string& path);
|
void init(const std::string& path);
|
||||||
int probe_wdl(Position& pos, int *success);
|
int probe_wdl(Position& pos, int *success);
|
||||||
int probe_dtz(Position& pos, int *success);
|
int probe_dtz(Position& pos, int *success);
|
||||||
bool root_probe(Position& pos, Search::RootMoveVector& rootMoves, Value& score);
|
bool root_probe(Position& pos, Search::RootMoves& rootMoves, Value& score);
|
||||||
bool root_probe_wdl(Position& pos, Search::RootMoveVector& rootMoves, Value& score);
|
bool root_probe_wdl(Position& pos, Search::RootMoves& rootMoves, Value& score);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "uci.h"
|
#include "uci.h"
|
||||||
|
|
||||||
using namespace Search;
|
|
||||||
|
|
||||||
ThreadPool Threads; // Global object
|
ThreadPool Threads; // Global object
|
||||||
|
|
||||||
/// Thread constructor launches the thread and then waits until it goes to sleep
|
/// Thread constructor launches the thread and then waits until it goes to sleep
|
||||||
|
@ -171,26 +169,34 @@ int64_t ThreadPool::nodes_searched() {
|
||||||
/// ThreadPool::start_thinking() wakes up the main thread sleeping in idle_loop()
|
/// ThreadPool::start_thinking() wakes up the main thread sleeping in idle_loop()
|
||||||
/// and starts a new search, then returns immediately.
|
/// and starts a new search, then returns immediately.
|
||||||
|
|
||||||
void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits,
|
void ThreadPool::start_thinking(const Position& pos, StateListPtr& states,
|
||||||
StateStackPtr& states) {
|
const Search::LimitsType& limits) {
|
||||||
|
|
||||||
main()->wait_for_search_finished();
|
main()->wait_for_search_finished();
|
||||||
|
|
||||||
Signals.stopOnPonderhit = Signals.stop = false;
|
Search::Signals.stopOnPonderhit = Search::Signals.stop = false;
|
||||||
|
Search::Limits = limits;
|
||||||
main()->rootMoves.clear();
|
Search::RootMoves rootMoves;
|
||||||
main()->rootPos = pos;
|
|
||||||
Limits = limits;
|
|
||||||
if (states.get()) // If we don't set a new position, preserve current state
|
|
||||||
{
|
|
||||||
SetupStates = std::move(states); // Ownership transfer here
|
|
||||||
assert(!states.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& m : MoveList<LEGAL>(pos))
|
for (const auto& m : MoveList<LEGAL>(pos))
|
||||||
if ( limits.searchmoves.empty()
|
if ( limits.searchmoves.empty()
|
||||||
|| std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m))
|
|| std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m))
|
||||||
main()->rootMoves.push_back(RootMove(m));
|
rootMoves.push_back(Search::RootMove(m));
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
for (Thread* th : Threads)
|
||||||
|
{
|
||||||
|
th->maxPly = 0;
|
||||||
|
th->rootDepth = DEPTH_ZERO;
|
||||||
|
th->rootMoves = rootMoves;
|
||||||
|
th->rootPos.set(pos.fen(), pos.is_chess960(), &setupStates->back(), th);
|
||||||
|
}
|
||||||
|
|
||||||
main()->start_searching();
|
main()->start_searching();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
int maxPly, callsCnt;
|
int maxPly, callsCnt;
|
||||||
|
|
||||||
Position rootPos;
|
Position rootPos;
|
||||||
Search::RootMoveVector rootMoves;
|
Search::RootMoves rootMoves;
|
||||||
Depth rootDepth;
|
Depth rootDepth;
|
||||||
HistoryStats history;
|
HistoryStats history;
|
||||||
MoveStats counterMoves;
|
MoveStats counterMoves;
|
||||||
|
@ -94,9 +94,12 @@ struct ThreadPool : public std::vector<Thread*> {
|
||||||
void exit(); // be initialized and valid during the whole thread lifetime.
|
void exit(); // be initialized and valid during the whole thread lifetime.
|
||||||
|
|
||||||
MainThread* main() { return static_cast<MainThread*>(at(0)); }
|
MainThread* main() { return static_cast<MainThread*>(at(0)); }
|
||||||
void start_thinking(const Position&, const Search::LimitsType&, Search::StateStackPtr&);
|
void start_thinking(const Position&, StateListPtr&, const Search::LimitsType&);
|
||||||
void read_uci_options();
|
void read_uci_options();
|
||||||
int64_t nodes_searched();
|
int64_t nodes_searched();
|
||||||
|
|
||||||
|
private:
|
||||||
|
StateListPtr setupStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ThreadPool Threads;
|
extern ThreadPool Threads;
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace {
|
||||||
enum TimeType { OptimumTime, MaxTime };
|
enum TimeType { OptimumTime, MaxTime };
|
||||||
|
|
||||||
const int MoveHorizon = 50; // Plan time management at most this many moves ahead
|
const int MoveHorizon = 50; // Plan time management at most this many moves ahead
|
||||||
const double MaxRatio = 7.09; // When in trouble, we can step over reserved time with this ratio
|
const double MaxRatio = 7.09; // When in trouble, we can step over reserved time with this ratio
|
||||||
const double StealRatio = 0.35; // However we must not steal time from remaining moves over this ratio
|
const double StealRatio = 0.35; // However we must not steal time from remaining moves over this ratio
|
||||||
|
|
||||||
|
|
||||||
|
|
18
src/uci.cpp
18
src/uci.cpp
|
@ -39,10 +39,10 @@ namespace {
|
||||||
// FEN string of the initial position, normal chess
|
// FEN string of the initial position, normal chess
|
||||||
const char* StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
const char* StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
||||||
|
|
||||||
// Stack to keep track of the position states along the setup moves (from the
|
// 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
|
// start position to the position just before the search starts). Needed by
|
||||||
// 'draw by repetition' detection.
|
// 'draw by repetition' detection.
|
||||||
Search::StateStackPtr SetupStates;
|
StateListPtr States(new std::vector<StateInfo>(1));
|
||||||
|
|
||||||
|
|
||||||
// position() is called when engine receives the "position" UCI command.
|
// position() is called when engine receives the "position" UCI command.
|
||||||
|
@ -68,14 +68,14 @@ namespace {
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pos.set(fen, Options["UCI_Chess960"], Threads.main());
|
States = StateListPtr(new std::vector<StateInfo>(1));
|
||||||
SetupStates = Search::StateStackPtr(new std::stack<StateInfo>);
|
pos.set(fen, Options["UCI_Chess960"], &States->back(), Threads.main());
|
||||||
|
|
||||||
// Parse move list (if any)
|
// Parse move list (if any)
|
||||||
while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE)
|
while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE)
|
||||||
{
|
{
|
||||||
SetupStates->push(StateInfo());
|
States->push_back(StateInfo());
|
||||||
pos.do_move(m, SetupStates->top(), pos.gives_check(m, CheckInfo(pos)));
|
pos.do_move(m, States->back(), pos.gives_check(m, CheckInfo(pos)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ namespace {
|
||||||
else if (token == "infinite") limits.infinite = 1;
|
else if (token == "infinite") limits.infinite = 1;
|
||||||
else if (token == "ponder") limits.ponder = 1;
|
else if (token == "ponder") limits.ponder = 1;
|
||||||
|
|
||||||
Threads.start_thinking(pos, limits, SetupStates);
|
Threads.start_thinking(pos, States, limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -146,9 +146,11 @@ namespace {
|
||||||
|
|
||||||
void UCI::loop(int argc, char* argv[]) {
|
void UCI::loop(int argc, char* argv[]) {
|
||||||
|
|
||||||
Position pos(StartFEN, false, Threads.main()); // The root position
|
Position pos;
|
||||||
string token, cmd;
|
string token, cmd;
|
||||||
|
|
||||||
|
pos.set(StartFEN, false, &States->back(), Threads.main());
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
cmd += std::string(argv[i]) + " ";
|
cmd += std::string(argv[i]) + " ";
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue