From 6b6f70512a84e0035a0c7d287f3c7b89c3305b93 Mon Sep 17 00:00:00 2001 From: amchess Date: Wed, 1 Aug 2018 17:14:00 +0200 Subject: [PATCH] 2.0 Stockfish Patch 08312018 Improve Stats definition --- src/bitboard.h | 2 +- src/endgame.cpp | 2 +- src/evaluate.cpp | 29 +++++++---- src/evaluate.h | 4 +- src/makeAll.bat | 22 ++++---- src/makeAll.sh | 40 +++++++-------- src/misc.cpp | 2 +- src/movepick.h | 25 ++++----- src/position.cpp | 110 +-------------------------------------- src/position.h | 63 ----------------------- src/search.cpp | 92 +++++++++++++++++---------------- src/search.h | 4 ++ src/syzygy/tbprobe.cpp | 6 +-- src/thread.cpp | 113 +++++++++++++++++++++++++++++++++++++++-- src/uci.h | 2 +- src/ucioption.cpp | 2 +- 16 files changed, 234 insertions(+), 284 deletions(-) diff --git a/src/bitboard.h b/src/bitboard.h index 2522282..9f2f4b5 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -382,4 +382,4 @@ inline Square pop_lsb(Bitboard* b) { inline Square frontmost_sq(Color c, Bitboard b) { return c == WHITE ? msb(b) : lsb(b); } inline Square backmost_sq(Color c, Bitboard b) { return c == WHITE ? lsb(b) : msb(b); } -#endif // #ifndef BITBOARD_H_INCLUDED +#endif // #ifndef BITBOARD_H_INCLUDED \ No newline at end of file diff --git a/src/endgame.cpp b/src/endgame.cpp index 3260884..146eed0 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -768,4 +768,4 @@ ScaleFactor Endgame::operator()(const Position& pos) const { // Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw, // it's probably at least a draw even with the pawn. return Bitbases::probe(wksq, psq, bksq, us) ? SCALE_FACTOR_NONE : SCALE_FACTOR_DRAW; -} +} \ No newline at end of file diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 6095c13..e6429c2 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -213,7 +213,7 @@ namespace { public: Evaluation() = delete; - explicit Evaluation(Position& p) : pos(p) {} + explicit Evaluation(const Position& p) : pos(p) {} Evaluation& operator=(const Evaluation&) = delete; Value value(); @@ -227,7 +227,7 @@ namespace { ScaleFactor scale_factor(Value eg) const; Score initiative(Value eg) const; - Position& pos; + const Position& pos; Material::Entry* me; Pawns::Entry* pe; Bitboard mobilityArea[COLOR_NB]; @@ -513,7 +513,7 @@ namespace { - 30; // Transform the kingDanger units into a Score, and subtract it from the evaluation - int kingSafe = pos.getShashinKingSafe();//Shashin very good tactical patch + int kingSafe = Search::shashinKingSafe;//Shashin very good tactical patch if (kingDanger > 0) { int mobilityDanger = mg_value(mobility[Them] - mobility[Us]); @@ -861,7 +861,7 @@ namespace { Value Evaluation::value() { assert(!pos.checkers()); - setWeightsByShashinValue(pos.getShashinValue()); //from shashin + setWeightsByShashinValue(Search::shashinValue); //from shashin // Probe the material hash table me = Material::probe(pos); @@ -897,14 +897,23 @@ namespace { + pieces() - pieces(),weightsMG[PIECES_POS],weightsEG[PIECES_POS]); } //from Sugar - double passed_Junior_scale = 1.0 + (-abs(v / Value(int(1.0 * double(PawnValueMg + PawnValueEg) / 2.0))) + 0.5) * abs(0.2 / (MidgameLimit + EndgameLimit)); - double king_Junior_scale = 1.0 - (-abs(v / Value(int(1.0 * double(PawnValueMg + PawnValueEg) / 2.0))) + 0.5) * abs(0.2 / (MidgameLimit + EndgameLimit)); + double king_Shashin_scale = 1.0; + double passed_Shashin_scale = 1.0; + + if (abs(v) >= double(PawnValueMg + PawnValueEg) / 2.0) + { + king_Shashin_scale = 1.0 - (-abs(v / Value(int(1.0 * double(PawnValueMg + PawnValueEg) / 2.0))) + 0.5) * abs(0.1 / (MidgameLimit + EndgameLimit)); + } + else + { + passed_Shashin_scale = 1.0 + (-abs(v / Value(int(1.0 * double(PawnValueMg + PawnValueEg) / 2.0))) + 0.5) * abs(0.1 / (MidgameLimit + EndgameLimit)); + } //end from Sugar score += apply_weight(mobility[WHITE] - mobility[BLACK],weightsMG[MOBILITY_POS],weightsEG[MOBILITY_POS]); - score += apply_weight(Score(int(double(king< WHITE>() - king< BLACK>()) * king_Junior_scale)),weightsMG[KING_SAFETY_POS],weightsEG[KING_SAFETY_POS]); //from Sugar + score += apply_weight(Score(int(double(king< WHITE>() - king< BLACK>()) * king_Shashin_scale)),weightsMG[KING_SAFETY_POS],weightsEG[KING_SAFETY_POS]); //from Sugar score += apply_weight(threats() - threats(),weightsMG[THREATS_POS],weightsEG[THREATS_POS]); - score += apply_weight(Score(int(double(passed< WHITE>() - passed< BLACK>()) * passed_Junior_scale)),weightsMG[PASSED_PAWNS_POS],weightsEG[PASSED_PAWNS_POS]); //from Sugar + score += apply_weight(Score(int(double(passed< WHITE>() - passed< BLACK>()) * passed_Shashin_scale)),weightsMG[PASSED_PAWNS_POS],weightsEG[PASSED_PAWNS_POS]); //from Sugar if(pawnsPiecesSpace) score += apply_weight(space< WHITE>() - space< BLACK>(),weightsMG[SPACE_POS],weightsEG[SPACE_POS]); if(initiativeToCalculate) @@ -937,7 +946,7 @@ namespace { /// evaluate() is the evaluator for the outer world. It returns a static /// evaluation of the position from the point of view of the side to move. -Value Eval::evaluate(Position& pos) { +Value Eval::evaluate(const Position& pos) { return Evaluation(pos).value(); } @@ -946,7 +955,7 @@ 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(Position& pos) { +std::string Eval::trace(const Position& pos) { std::memset(scores, 0, sizeof(scores)); diff --git a/src/evaluate.h b/src/evaluate.h index 8c8b2ba..b5a3e08 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -31,9 +31,9 @@ namespace Eval { constexpr Value Tempo = Value(20); // Must be visible to search -std::string trace(Position& pos);//from Shashin +std::string trace(const Position& pos); -Value evaluate(Position& pos);//from Shashin +Value evaluate(const Position& pos); } #endif // #ifndef EVALUATE_H_INCLUDED diff --git a/src/makeAll.bat b/src/makeAll.bat index 564bf70..df13e5a 100644 --- a/src/makeAll.bat +++ b/src/makeAll.bat @@ -4,42 +4,42 @@ ren C:\MinGW\mingw32-730-pd mingw32 make clean mingw32-make profile-build ARCH=x86-64 COMP=mingw CXX=x86_64-w64-mingw32-g++ -j14 strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-x86-64.exe" +ren shashchess.exe "ShashChess Pro 2.0-x86-64.exe" make clean mingw32-make profile-build ARCH=x86-64-modern COMP=mingw CXX=x86_64-w64-mingw32-g++ -j14 strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-x86-64-modern.exe" +ren shashchess.exe "ShashChess Pro 2.0-x86-64-modern.exe" make clean mingw32-make profile-build ARCH=x86-64-bmi2 COMP=mingw CXX=x86_64-w64-mingw32-g++ -j14 strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-x86-64-bmi2.exe" +ren shashchess.exe "ShashChess Pro 2.0-x86-64-bmi2.exe" mingw32-make build ARCH=ppc-64 COMP=mingw strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-ppc-64.exe" +ren shashchess.exe "ShashChess Pro 2.0-ppc-64.exe" make clean mingw32-make profile-build ARCH=general-64 COMP=mingw CXX=x86_64-w64-mingw32-g++ -j14 strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-general-64.exe" +ren shashchess.exe "ShashChess Pro 2.0-general-64.exe" make clean mingw32-make build ARCH=ppc-32 COMP=mingw strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-ppc-32.exe" +ren shashchess.exe "ShashChess Pro 2.0-ppc-32.exe" make clean -mingw32-make profile-build ARCH=armv7 COMP=mingw CXX=x86_64-w64-mingw32-g++ -j14 +mingw32-make build ARCH=armv7 COMP=gcc strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-armv7.exe" +ren shashchess.exe "ShashChess Pro 2.0-armv7.exe" make clean mingw32-make -f MakeFile profile-build ARCH=general-32 COMP=mingw strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-general-32.exe" +ren shashchess.exe "ShashChess Pro 2.0-general-32.exe" make clean mingw32-make -f MakeFile profile-build ARCH=x86-32 COMP=mingw strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-x86-32.exe" +ren shashchess.exe "ShashChess Pro 2.0-x86-32.exe" make clean mingw32-make -f MakeFile profile-build ARCH=x86-32-old COMP=mingw strip shashchess.exe -ren shashchess.exe "ShashChess Pro 1.1.1-x86-32-old.exe" +ren shashchess.exe "ShashChess Pro 2.0-x86-32-old.exe" make clean ren C:\MinGW\mingw64 mingw64-730-pse ren C:\MinGW\mingw32 mingw32-730-pd diff --git a/src/makeAll.sh b/src/makeAll.sh index 4bf0b69..b5c250f 100755 --- a/src/makeAll.sh +++ b/src/makeAll.sh @@ -1,49 +1,49 @@ -make profile-build ARCH=x86-64 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=x86-64 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-x86-64' +mv 'shashchess' 'ShashChess Pro 2.0-x86-64' make clean -make profile-build ARCH=x86-64-modern COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=x86-64-modern COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-x86-64-modern' +mv 'shashchess' 'ShashChess Pro 2.0-x86-64-modern' make clean -make profile-build ARCH=x86-64-bmi2 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=x86-64-bmi2 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-x86-64-bmi2' +mv 'shashchess' 'ShashChess Pro 2.0-x86-64-bmi2' make clean -make profile-build ARCH=x86-32 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=x86-32 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-x86-32' +mv 'shashchess' 'ShashChess Pro 2.0-x86-32' make clean -make profile-build ARCH=x86-32-old COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=x86-32-old COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-x86-32-old' +mv 'shashchess' 'ShashChess Pro 2.0-x86-32-old' make clean -make profile-build ARCH=ppc-64 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=ppc-64 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-ppc-64' +mv 'shashchess' 'ShashChess Pro 2.0-ppc-64' make clean -make profile-build ARCH=ppc-32 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=ppc-32 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-ppc-32' +mv 'shashchess' 'ShashChess Pro 2.0-ppc-32' make clean -make profile-build ARCH=armv7 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=armv7 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-armv7' +mv 'shashchess' 'ShashChess Pro 2.0-armv7' make clean -make profile-build ARCH=general-64 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=general-64 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-general-64' +mv 'shashchess' 'ShashChess Pro 2.0-general-64' make clean -make profile-build ARCH=general-32 COMP=gcc COMPCC=gcc-7.3.0 +make build ARCH=general-32 COMPCC=gcc-7.3.0 strip shashchess -mv 'shashchess' 'ShashChess Pro 1.1.1-general-32' +mv 'shashchess' 'ShashChess Pro 2.0-general-32' make clean diff --git a/src/misc.cpp b/src/misc.cpp index 89b8bf7..613568b 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -58,7 +58,7 @@ namespace { /// Version number. If Version is left empty, then compile date in the format /// DD-MM-YY and show in engine_info. -const string Version = "1.1.1"; +const string Version = "2.0"; /// Our fancy logging facility. The trick here is to replace cin.rdbuf() and /// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We diff --git a/src/movepick.h b/src/movepick.h index 96354da..8a4502b 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -36,18 +36,16 @@ template class StatsEntry { - static const bool IsInt = std::is_integral::value; - typedef typename std::conditional::type TT; - T entry; public: - T* get() { return &entry; } void operator=(const T& v) { entry = v; } - operator TT() const { return entry; } + T* operator&() { return &entry; } + T* operator->() { return &entry; } + operator const T&() const { return entry; } void operator<<(int bonus) { - assert(abs(bonus) <= D); // Ensure range is [-D, D] + assert(abs(bonus) <= D); // Ensure range is [-D, D] static_assert(D <= std::numeric_limits::max(), "D overflows T"); entry += bonus - entry * abs(bonus) / D; @@ -64,18 +62,21 @@ class StatsEntry { template struct Stats : public std::array, Size> { - T* get() { return this->at(0).get(); } + typedef Stats stats; void fill(const T& v) { - T* p = get(); - std::fill(p, p + sizeof(*this) / sizeof(*p), v); + + // For standard-layout 'this' points to first struct member + assert(std::is_standard_layout::value); + + typedef StatsEntry entry; + entry* p = reinterpret_cast(this); + std::fill(p, p + sizeof(*this) / sizeof(entry), v); } }; template -struct Stats : public std::array, Size> { - T* get() { return this->at(0).get(); } -}; +struct Stats : public std::array, Size> {}; /// In stats table, D=0 means that the template parameter is not used enum StatsParams { NOT_USED = 0 }; diff --git a/src/position.cpp b/src/position.cpp index 405e474..1690b3d 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1240,116 +1240,8 @@ void Position::flip() { assert(pos_is_ok()); } -//from Shashin -uint8_t getInitialShashinValue() { - if (!Options["Tal"] && !Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_POSITION_DEFAULT; - if (Options["Tal"] && Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_POSITION_TAL_CAPABLANCA; - if (Options["Tal"] && !Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_POSITION_TAL; - - if (!Options["Tal"] && Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_POSITION_CAPABLANCA; - - if (!Options["Tal"] && Options["Capablanca"] - && Options["Petrosian"]) - return SHASHIN_POSITION_CAPABLANCA_PETROSIAN; - - if (!Options["Tal"] && !Options["Capablanca"] - && Options["Petrosian"]) - return SHASHIN_POSITION_PETROSIAN; - - if (Options["Tal"] && Options["Capablanca"] - && Options["Petrosian"]) - return SHASHIN_POSITION_TAL_CAPABLANCA_PETROSIAN; - - return SHASHIN_POSITION_TAL_PETROSIAN; -} - -uint8_t getInitialContemptByShashin() { - if (!Options["Tal"] && !Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_DEFAULT_CONTEMPT; - - if (Options["Tal"] && Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_TAL_CAPABLANCA_CONTEMPT; - - if (Options["Tal"] && !Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_TAL_CONTEMPT; - - if (!Options["Tal"] && Options["Capablanca"] - && !Options["Petrosian"]) - return SHASHIN_CAPABLANCA_CONTEMPT; - - if (!Options["Tal"] && Options["Capablanca"] - && Options["Petrosian"]) - return SHASHIN_CAPABLANCA_PETROSIAN_CONTEMPT; - - if (!Options["Tal"] && !Options["Capablanca"] - && Options["Petrosian"]) - return SHASHIN_PETROSIAN_CONTEMPT; - - if (Options["Tal"] && Options["Capablanca"] - && Options["Petrosian"]) - return SHASHIN_TAL_CAPABLANCA_PETROSIAN_CONTEMPT; - - return SHASHIN_TAL_PETROSIAN_CONTEMPT; -} -int getInitialShashinKingSafe(){ - if ((!Options["Tal"] && !Options["Capablanca"] - && !Options["Petrosian"]) - || - (!Options["Tal"] && Options["Capablanca"] - && !Options["Petrosian"])) - return SHASHIN_KING_SAFE_DEFAULT; - - if ((Options["Tal"] && Options["Capablanca"] - && !Options["Petrosian"]) - || - (!Options["Tal"] && Options["Capablanca"] - && Options["Petrosian"])) - return SHASHIN_KING_SAFE_MIDDLE; - - if ((Options["Tal"] && !Options["Capablanca"] - && !Options["Petrosian"]) - || - (Options["Tal"] && Options["Capablanca"] - && Options["Petrosian"]) - || - (!Options["Tal"] && !Options["Capablanca"] - && Options["Petrosian"])) - return SHASHIN_KING_SAFE_MAX; - return SHASHIN_KING_SAFE_DEFAULT; -} - -int getInitialShashinQuiescent(){ - if ((!Options["Tal"] && !Options["Capablanca"] - && !Options["Petrosian"]) - || - (!Options["Tal"] && Options["Capablanca"] - && !Options["Petrosian"])) - return 1; - return 0; -} -//end from Shashin -//shashin methods -void Position::set_initial_shashin_values() { - shashinValue = getInitialShashinValue(); - shashinContempt = getInitialContemptByShashin(); - shashinKingSafe=getInitialShashinKingSafe(); - shashinQuiescentCapablanca=getInitialShashinQuiescent(); - shashinQuiescentCapablancaMC=getInitialShashinQuiescent(); -} -//end shashin methods /// Position::pos_is_ok() performs some consistency checks for the /// position object and raises an asserts if something wrong is detected. /// This is meant to be helpful when debugging. @@ -1418,4 +1310,4 @@ bool Position::pos_is_ok() const { } return true; -} +} \ No newline at end of file diff --git a/src/position.h b/src/position.h index 0e76dc1..fa61544 100644 --- a/src/position.h +++ b/src/position.h @@ -115,14 +115,6 @@ class Position { template Bitboard attacks_from(Square s, Color c) const; Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const; - //from Shashin - uint8_t shashinValue; - uint8_t shashinContempt; - int shashinKingSafe; - int shashinQuiescentCapablanca; - int shashinQuiescentCapablancaMC; - //end from Shashin - // Properties of moves bool legal(Move m) const; bool pseudo_legal(const Move m) const; @@ -169,21 +161,6 @@ class Position { // Position consistency check, for debugging bool pos_is_ok() const; void flip(); - //from Shashin - uint8_t getShashinContempt (); - void setShashinContempt (uint8_t shashinContempt); - int getShashinKingSafe (); - void setShashinKingSafe (int shashinKingSafe); - int isShashinQuiescentCapablanca (); - void setShashinQuiescentCapablanca (int shashinQuiescentCapablanca); - int isShashinQuiescentCapablancaMC (); - void setShashinQuiescentCapablancaMC (int shashinQuiescentCapablancaMC); - uint8_t getShashinValue (); - void setShashinValue (uint8_t shashinValue); - //shashin methods - void set_initial_shashin_values(); - //end from Shashin - private: // Initialization helpers (used while setting up a position) @@ -221,47 +198,7 @@ namespace PSQT { } extern std::ostream& operator<<(std::ostream& os, const Position& pos); -//from Shashin -inline uint8_t Position::getShashinContempt () { - return shashinContempt; -} - -inline void Position::setShashinContempt (uint8_t shashinContemptIn){ - this->shashinContempt = shashinContemptIn; -} - -inline int Position::getShashinKingSafe () { - return shashinKingSafe; -} - -inline void Position::setShashinKingSafe (int shashinKingSafeIn) { - this->shashinKingSafe = shashinKingSafeIn; -} - -inline int Position::isShashinQuiescentCapablanca () { - return shashinQuiescentCapablanca; -} - -inline void Position::setShashinQuiescentCapablanca (int shashinQuiescentCabablancaIn){ - shashinQuiescentCapablanca = shashinQuiescentCabablancaIn; -} - -inline int Position::isShashinQuiescentCapablancaMC () { - return shashinQuiescentCapablancaMC; -} -inline void Position::setShashinQuiescentCapablancaMC (int shashinQuiescentCabablancaMCIn){ - shashinQuiescentCapablancaMC = shashinQuiescentCabablancaMCIn; -} - -inline uint8_t Position::getShashinValue () { - return shashinValue; -} - -inline void Position::setShashinValue (uint8_t shashinValueIn){ - this->shashinValue = shashinValueIn; -} -//end from Shashin inline Color Position::side_to_move() const { return sideToMove; } diff --git a/src/search.cpp b/src/search.cpp index 02d18de..85e1b0d 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -48,6 +48,10 @@ int uciElo; namespace Search { LimitsType Limits; + //from Shashin + uint8_t shashinValue,shashinContempt; + int shashinKingSafe,shashinQuiescentCapablanca,shashinQuiescentCapablancaMC; + //end from Shashin } namespace Tablebases { @@ -374,7 +378,7 @@ void Thread::search() { std::memset(ss-4, 0, 7 * sizeof(Stack)); for (int i = 4; i > 0; i--) - (ss-i)->continuationHistory = this->continuationHistory[NO_PIECE][0].get(); // Use as sentinel + (ss-i)->continuationHistory = &this->continuationHistory[NO_PIECE][0]; // Use as sentinel if (cleanSearch) Search::clear(); @@ -394,7 +398,7 @@ void Thread::search() { multiPV = std::max(multiPV, (size_t)4); multiPV = std::min(multiPV, rootMoves.size()); - int ct = (rootPos.getShashinContempt()) * PawnValueEg / 100; // From centipawns + int ct = (shashinContempt) * PawnValueEg / 100; // From centipawns Shashin contempt = (us == WHITE ? make_score(ct, ct / 2) : -make_score(ct, ct / 2)); @@ -452,10 +456,10 @@ void Thread::search() { //update Shashin's values from previous score if (abs(previousScore) < VALUE_MATE - MAX_PLY){ Value scoreCP = (Value)(previousScore * 100 / PawnValueEg); - rootPos.setShashinValue(getShashinValue(scoreCP)); - rootPos.setShashinKingSafe(getShashinKingSafe(scoreCP)); - rootPos.setShashinQuiescentCapablanca(abs(scoreCP) > SHASHIN_MAX_SCORE ? 0 : 1); - rootPos.setShashinQuiescentCapablancaMC(abs(scoreCP) > SHASHIN_MAX_SCORE_MC ? 0 : 1); + shashinValue=getShashinValue(scoreCP); + shashinKingSafe=getShashinKingSafe(scoreCP); + shashinQuiescentCapablanca=abs(scoreCP) > SHASHIN_MAX_SCORE ? 0 : 1; + shashinQuiescentCapablancaMC=abs(scoreCP) > SHASHIN_MAX_SCORE_MC ? 0 : 1; } //end update Shashin's values from previous score } @@ -573,10 +577,10 @@ void Thread::search() { Threads.stop = true; } } - //from Stefano80 playoutSimpleAlways - if (mainThread && !Threads.stop && !rootPos.isShashinQuiescentCapablancaMC()) + //from Stefano80 playoutSimple + if (mainThread && !Threads.stop && !shashinQuiescentCapablancaMC) playout(lastBestMove, ss, bestValue); - //end from Stefano80 playoutSimpleAlways + //end from Stefano80 playoutSimple } if (!mainThread) @@ -590,38 +594,37 @@ void Thread::search() { skill.best ? skill.best : skill.pick_best(multiPV))); } -//from Stefano80 playoutSimpleAlways +//from Stefano80 playoutSimple // Playout a game, in the hope of meaningfully filling the TT beyond the horizon Value Thread::playout(Move playMove, Stack* ss, Value playoutValue) { StateInfo st; bool ttHit; - TTEntry* tte ; - - if (!MoveList(rootPos).size()) - return rootPos.checkers()? mated_in(ss->ply): VALUE_DRAW; if ( Threads.stop || !rootPos.pseudo_legal(playMove) || !rootPos.legal(playMove)) - return playoutValue; + return VALUE_NONE; if (rootPos.is_draw(ss->ply)) return VALUE_DRAW; ss->currentMove = playMove; - ss->continuationHistory = continuationHistory[rootPos.moved_piece(playMove)][to_sq(playMove)].get(); - (ss+1)->ply = ss->ply + 1; + ss->continuationHistory = &continuationHistory[rootPos.moved_piece(playMove)][to_sq(playMove)]; rootPos.do_move(playMove, st); - int d = int(rootDepth) * int(rootDepth) / (rootDepth + 4 * ONE_PLY) - ss->ply/2; + (ss+1)->ply = ss->ply + 1; + int d = int(rootDepth) * int(rootDepth) / (rootDepth + 4 * ONE_PLY) - 2; Depth newDepth = d * ONE_PLY; - playoutValue = - ::search(rootPos, ss+1, - playoutValue, - playoutValue + 1, newDepth, false); - - tte = TT.probe(rootPos.key(), ttHit); + TTEntry* tte = TT.probe(rootPos.key(), ttHit); + if (!ttHit && MoveList(rootPos).size()){ + playoutValue = ::search(rootPos, ss+1, - playoutValue, - playoutValue + 1, newDepth, true); + tte = TT.probe(rootPos.key(), ttHit); + } + Move ttMove = ttHit ? tte->move() : MOVE_NONE; - if( ttHit - && ttMove != MOVE_NONE + if( ttHit + && ttMove != MOVE_NONE && ss->ply < MAX_PLY - 2 && abs(playoutValue) < VALUE_KNOWN_WIN) playoutValue = - playout(ttMove, ss+1, - playoutValue); @@ -629,7 +632,7 @@ Value Thread::playout(Move playMove, Stack* ss, Value playoutValue) { rootPos.undo_move(playMove); return playoutValue; } -//end from Stefano80 playoutSimpleAlways +//end from Stefano80 playoutSimple namespace { @@ -637,7 +640,6 @@ namespace { template Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode) { - constexpr bool PvNode = NT == PV; const bool rootNode = PvNode && ss->ply == 0; @@ -693,7 +695,7 @@ namespace { /* //from JEllis MateFinder - if(!pos.getShashinQuiescentCapablanca()){ + if(!shashinQuiescentCapablanca){ excludedMove = ss->excludedMove; posKey = pos.key() ^ Key(excludedMove); tte = TT.probe(posKey, ttHit); @@ -722,7 +724,7 @@ namespace { /* //from JEllis mateFinder - if ((alpha >= mate_in(ss->ply+1)) && !pos.isShashinQuiescentCapablanca()) + if ((alpha >= mate_in(ss->ply+1)) && !shashinQuiescentCapablanca) return alpha; //} //end from JEllis MateFinder @@ -733,7 +735,7 @@ namespace { (ss+1)->ply = ss->ply + 1; ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE; - ss->continuationHistory = thisThread->continuationHistory[NO_PIECE][0].get(); + ss->continuationHistory = &thisThread->continuationHistory[NO_PIECE][0]; (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE; Square prevSq = to_sq((ss-1)->currentMove); @@ -789,7 +791,7 @@ namespace { if (!rootNode && TB::Cardinality) { int piecesCount = pos.count(); - //int piecesCount = !pos.isShashinQuiescentCapablanca() ? popcount(pos.pieces()) : pos.count(); // from JEllis MateFinder + //int piecesCount = !shashinQuiescentCapablanca ? popcount(pos.pieces()) : pos.count(); // from JEllis MateFinder if ( piecesCount <= TB::Cardinality && (piecesCount < TB::Cardinality || depth >= TB::ProbeDepth) @@ -865,7 +867,7 @@ namespace { if ( !PvNode && depth < 3 * ONE_PLY && eval <= alpha - RazorMargin[depth / ONE_PLY]) - //&& (pos.isShashinQuiescentCapablanca()||(abs(eval) < 2 * VALUE_KNOWN_WIN))) //from JEllis MateFinder + //&& (shashinQuiescentCapablanca||(abs(eval) < 2 * VALUE_KNOWN_WIN))) //from JEllis MateFinder { Value ralpha = alpha - (depth >= 2 * ONE_PLY) * RazorMargin[depth / ONE_PLY]; Value v = qsearch(pos, ss, ralpha, ralpha+1); @@ -878,7 +880,7 @@ namespace { // Step 8. Futility pruning: child node (~30 Elo) if ( - ((!rootNode && pos.isShashinQuiescentCapablanca())|| (!PvNode && !pos.isShashinQuiescentCapablanca())) //from JEllis MateFinder + ((!rootNode && shashinQuiescentCapablanca)|| (!PvNode && !shashinQuiescentCapablanca)) //from JEllis MateFinder && depth < 7 * ONE_PLY && eval - futility_margin(depth, improving) >= beta && eval < VALUE_KNOWN_WIN) // Do not return unproven wins @@ -893,7 +895,7 @@ namespace { && !excludedMove && pos.non_pawn_material(us) && (ss->ply > thisThread->nmpMinPly || us != thisThread->nmpColor) - && (pos.isShashinQuiescentCapablanca() || (abs(eval) < 2 * VALUE_KNOWN_WIN )) //from JEllis MateFinder + && (shashinQuiescentCapablanca || (abs(eval) < 2 * VALUE_KNOWN_WIN )) //from JEllis MateFinder ) { assert(eval - beta >= 0); @@ -902,7 +904,7 @@ namespace { Depth R = ((823 + 67 * depth / ONE_PLY) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY; ss->currentMove = MOVE_NULL; - ss->continuationHistory = thisThread->continuationHistory[NO_PIECE][0].get(); + ss->continuationHistory = &thisThread->continuationHistory[NO_PIECE][0]; pos.do_null_move(st); @@ -941,7 +943,7 @@ namespace { if ( !PvNode && depth >= 5 * ONE_PLY && abs(beta) < VALUE_MATE_IN_MAX_PLY) - //&& (pos.isShashinQuiescentCapablanca()|| //from JEllis MateFinder + //&& (shashinQuiescentCapablanca|| //from JEllis MateFinder //(ss->ply % 2 == 0 && abs(eval) < 2 * VALUE_KNOWN_WIN))) { Value rbeta = std::min(beta + 216 - 48 * improving, VALUE_INFINITE); @@ -955,7 +957,7 @@ namespace { probCutCount++; ss->currentMove = move; - ss->continuationHistory = thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)].get(); + ss->continuationHistory = &thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)]; assert(depth >= 5 * ONE_PLY); @@ -1070,9 +1072,9 @@ namespace { // Step 14. Pruning at shallow depth (~170 Elo) if ( (//from JEllis MateFinder - (!rootNode && pos.isShashinQuiescentCapablanca()) + (!rootNode && shashinQuiescentCapablanca) || - (!PvNode && !pos.isShashinQuiescentCapablanca())) //End from JEllis MateFinder + (!PvNode && !shashinQuiescentCapablanca)) //End from JEllis MateFinder && pos.non_pawn_material(us) && bestValue > VALUE_MATED_IN_MAX_PLY) @@ -1127,7 +1129,7 @@ namespace { // Update the current move (this must be done after singular extension search) ss->currentMove = move; - ss->continuationHistory = thisThread->continuationHistory[movedPiece][to_sq(move)].get(); + ss->continuationHistory = &thisThread->continuationHistory[movedPiece][to_sq(move)]; // Step 15. Make the move pos.do_move(move, st, givesCheck); @@ -1137,7 +1139,7 @@ namespace { if ( depth >= 3 * ONE_PLY && moveCount > 1 && (!captureOrPromotion || moveCountPruning) - && (pos.isShashinQuiescentCapablanca() || (thisThread->selDepth > depth //from JEllis MateFinder + && (shashinQuiescentCapablanca || (thisThread->selDepth > depth //from JEllis MateFinder //&& !(depth >= 16 * ONE_PLY && ss->ply < 3 * ONE_PLY) ) ) @@ -1192,7 +1194,7 @@ namespace { // Decrease/increase reduction for moves with a good/bad history (~30 Elo) r -= ss->statScore / 20000 * ONE_PLY; } - /*((newDepth - r + 8 * ONE_PLY < thisThread->rootDepth) && !pos.isShashinQuiescentCapablanca()) //from JEllis MateFinder + /*((newDepth - r + 8 * ONE_PLY < thisThread->rootDepth) && !shashinQuiescentCapablanca) //from JEllis MateFinder r = std::min(r, 3 * ONE_PLY);*/ Depth d = std::max(newDepth - std::max(r, DEPTH_ZERO), ONE_PLY); @@ -1330,7 +1332,7 @@ namespace { && is_ok((ss-1)->currentMove)) update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth)); - if(PvNode && pos.isShashinQuiescentCapablanca()) //from JEllis MateFinder + if(PvNode && shashinQuiescentCapablanca) //from JEllis MateFinder bestValue = std::min(bestValue, maxValue); if (!excludedMove) @@ -1377,7 +1379,7 @@ namespace { Thread* thisThread = pos.this_thread(); (ss+1)->ply = ss->ply + 1; ss->currentMove = bestMove = MOVE_NONE; - ss->continuationHistory = thisThread->continuationHistory[NO_PIECE][0].get(); + ss->continuationHistory = &thisThread->continuationHistory[NO_PIECE][0]; inCheck = pos.checkers(); moveCount = 0; @@ -1386,7 +1388,7 @@ namespace { || ss->ply >= MAX_PLY) return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos) : VALUE_DRAW; - /*if ((alpha >= mate_in(ss->ply+1)) && !pos.isShashinQuiescentCapablanca()) //from JEllis MateFinder + /*if ((alpha >= mate_in(ss->ply+1)) && !shashinQuiescentCapablanca) //from JEllis MateFinder return alpha;*/ assert(0 <= ss->ply && ss->ply < MAX_PLY); @@ -1515,7 +1517,7 @@ namespace { } ss->currentMove = move; - ss->continuationHistory = thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)].get(); + ss->continuationHistory = &thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)]; // Make and search the move pos.do_move(move, st, givesCheck); @@ -1736,7 +1738,7 @@ void MainThread::check_time() { /// 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(Position& pos, Depth depth, Value alpha, Value beta) { +string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) { std::stringstream ss; TimePoint elapsed = Time.elapsed() + 1; diff --git a/src/search.h b/src/search.h index bc8b5ab..e9621a7 100644 --- a/src/search.h +++ b/src/search.h @@ -99,6 +99,10 @@ struct LimitsType { }; extern LimitsType Limits; +//from Shashin +extern uint8_t shashinValue,shashinContempt; +extern int shashinKingSafe,shashinQuiescentCapablanca,shashinQuiescentCapablancaMC; +//end from Shashin void init(bool optionCleanSearch); void clear(); diff --git a/src/syzygy/tbprobe.cpp b/src/syzygy/tbprobe.cpp index 326331f..9b9e8d1 100644 --- a/src/syzygy/tbprobe.cpp +++ b/src/syzygy/tbprobe.cpp @@ -486,7 +486,7 @@ int decompress_pairs(PairsData* d, uint64_t idx) { // I(k) = k * d->span + d->span / 2 (1) // First step is to get the 'k' of the I(k) nearest to our idx, using definition (1) - uint32_t k = idx / d->span; + uint32_t k = uint32_t(idx / d->span); // Then we read the corresponding SparseIndex[] entry uint32_t block = number(&d->sparseIndex[k].block); @@ -532,7 +532,7 @@ int decompress_pairs(PairsData* d, uint64_t idx) { // All the symbols of a given length are consecutive integers (numerical // sequence property), so we can compute the offset of our symbol of // length len, stored at the beginning of buf64. - sym = (buf64 - d->base64[len]) >> (64 - len - d->minSymLen); + sym = uint16_t((buf64 - d->base64[len]) >> (64 - len - d->minSymLen)); // Now add the value of the lowest symbol of length len to get our symbol sym += number(&d->lowestSym[len]); @@ -938,7 +938,7 @@ uint8_t* set_sizes(PairsData* d, uint8_t* data) { // groupLen[] is a zero-terminated list of group lengths, the last groupIdx[] // element stores the biggest index that is the tb size. - uint64_t tbSize = d->groupIdx[std::find(d->groupLen, d->groupLen + 7, 0) - d->groupLen]; + size_t tbSize = size_t(d->groupIdx[std::find(d->groupLen, d->groupLen + 7, 0) - d->groupLen]); d->sizeofBlock = 1ULL << *data++; d->span = 1ULL << *data++; diff --git a/src/thread.cpp b/src/thread.cpp index c12dbec..e18602a 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -63,9 +63,9 @@ void Thread::clear() { for (auto& to : continuationHistory) for (auto& h : to) - h.get()->fill(0); + h->fill(0); - continuationHistory[NO_PIECE][0].get()->fill(Search::CounterMovePruneThreshold - 1); + continuationHistory[NO_PIECE][0]->fill(Search::CounterMovePruneThreshold - 1); } /// Thread::start_searching() wakes up the thread that will start the search @@ -153,7 +153,107 @@ void ThreadPool::clear() { main()->previousScore = VALUE_INFINITE; main()->previousTimeReduction = 1.0; } +//from Shashin +inline uint8_t getInitialShashinValue() { + if (!Options["Tal"] && !Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_POSITION_DEFAULT; + if (Options["Tal"] && Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_POSITION_TAL_CAPABLANCA; + + if (Options["Tal"] && !Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_POSITION_TAL; + + if (!Options["Tal"] && Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_POSITION_CAPABLANCA; + + if (!Options["Tal"] && Options["Capablanca"] + && Options["Petrosian"]) + return SHASHIN_POSITION_CAPABLANCA_PETROSIAN; + + if (!Options["Tal"] && !Options["Capablanca"] + && Options["Petrosian"]) + return SHASHIN_POSITION_PETROSIAN; + + if (Options["Tal"] && Options["Capablanca"] + && Options["Petrosian"]) + return SHASHIN_POSITION_TAL_CAPABLANCA_PETROSIAN; + + return SHASHIN_POSITION_TAL_PETROSIAN; +} + +inline uint8_t getInitialContemptByShashin() { + if (!Options["Tal"] && !Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_DEFAULT_CONTEMPT; + + if (Options["Tal"] && Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_TAL_CAPABLANCA_CONTEMPT; + + if (Options["Tal"] && !Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_TAL_CONTEMPT; + + if (!Options["Tal"] && Options["Capablanca"] + && !Options["Petrosian"]) + return SHASHIN_CAPABLANCA_CONTEMPT; + + if (!Options["Tal"] && Options["Capablanca"] + && Options["Petrosian"]) + return SHASHIN_CAPABLANCA_PETROSIAN_CONTEMPT; + + if (!Options["Tal"] && !Options["Capablanca"] + && Options["Petrosian"]) + return SHASHIN_PETROSIAN_CONTEMPT; + + if (Options["Tal"] && Options["Capablanca"] + && Options["Petrosian"]) + return SHASHIN_TAL_CAPABLANCA_PETROSIAN_CONTEMPT; + + return SHASHIN_TAL_PETROSIAN_CONTEMPT; +} +inline int getInitialShashinKingSafe(){ + if ((!Options["Tal"] && !Options["Capablanca"] + && !Options["Petrosian"]) + || + (!Options["Tal"] && Options["Capablanca"] + && !Options["Petrosian"])) + return SHASHIN_KING_SAFE_DEFAULT; + + if ((Options["Tal"] && Options["Capablanca"] + && !Options["Petrosian"]) + || + (!Options["Tal"] && Options["Capablanca"] + && Options["Petrosian"])) + return SHASHIN_KING_SAFE_MIDDLE; + + if ((Options["Tal"] && !Options["Capablanca"] + && !Options["Petrosian"]) + || + (Options["Tal"] && Options["Capablanca"] + && Options["Petrosian"]) + || + (!Options["Tal"] && !Options["Capablanca"] + && Options["Petrosian"])) + return SHASHIN_KING_SAFE_MAX; + return SHASHIN_KING_SAFE_DEFAULT; +} + +inline int getInitialShashinQuiescent(){ + if ((!Options["Tal"] && !Options["Capablanca"] + && !Options["Petrosian"]) + || + (!Options["Tal"] && Options["Capablanca"] + && !Options["Petrosian"])) + return 1; + return 0; +} +//end from Shashin /// 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. @@ -161,7 +261,13 @@ void ThreadPool::start_thinking(Position& pos, StateListPtr& states, const Search::LimitsType& limits, bool ponderMode) { main()->wait_for_search_finished(); - pos.set_initial_shashin_values(); //from Shashin + //from Shashin + Search::shashinValue = getInitialShashinValue(); + Search::shashinContempt = getInitialContemptByShashin(); + Search::shashinKingSafe=getInitialShashinKingSafe(); + Search::shashinQuiescentCapablanca=getInitialShashinQuiescent(); + Search::shashinQuiescentCapablancaMC=getInitialShashinQuiescent(); + //end from Shashin stopOnPonderhit = stop = false; ponder = ponderMode; Search::Limits = limits; @@ -195,7 +301,6 @@ void ThreadPool::start_thinking(Position& pos, StateListPtr& states, th->rootDepth = th->completedDepth = DEPTH_ZERO; th->rootMoves = rootMoves; th->rootPos.set(pos.fen(), pos.is_chess960(), &setupStates->back(), th); - th->rootPos.set_initial_shashin_values(); //from Shashin } setupStates->back() = tmp; diff --git a/src/uci.h b/src/uci.h index 9280d6b..f0e4494 100644 --- a/src/uci.h +++ b/src/uci.h @@ -82,7 +82,7 @@ void loop(int argc, char* argv[]); std::string value(Value v); std::string square(Square s); std::string move(Move m, bool chess960); -std::string pv(Position& pos, Depth depth, Value alpha, Value beta); //Shashin +std::string pv(const Position& pos, Depth depth, Value alpha, Value beta); Move to_move(const Position& pos, std::string& str); } // namespace UCI diff --git a/src/ucioption.cpp b/src/ucioption.cpp index aad0fdd..f567a16 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -78,7 +78,7 @@ void init(OptionsMap& o) { o["Debug Log File"] << Option("", on_logger); o["Threads"] << Option(n, unsigned(1), unsigned(512), on_threads); - o["Large Pages"] << Option(false, on_large_pages); + o["Large Pages"] << Option(true, on_large_pages); o["Hash"] << Option(16, 1, MaxHashMB, on_hash_size); o["Clear_Hash"] << Option(on_clear_hash); o["NeverClearHash"] << Option(false);