2008-08-31 23:59:13 -06:00
|
|
|
/*
|
2008-10-19 10:56:28 -06:00
|
|
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
|
|
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
2016-01-02 02:43:25 -07:00
|
|
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
2020-01-07 13:35:47 -07:00
|
|
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2008-10-19 10:56:28 -06:00
|
|
|
Stockfish is free software: you can redistribute it and/or modify
|
2008-08-31 23:59:13 -06:00
|
|
|
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.
|
2008-09-23 16:32:53 -06:00
|
|
|
|
2008-10-19 10:56:28 -06:00
|
|
|
Stockfish is distributed in the hope that it will be useful,
|
2008-08-31 23:59:13 -06:00
|
|
|
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.
|
2008-09-23 16:32:53 -06:00
|
|
|
|
2008-08-31 23:59:13 -06:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2019-03-31 04:02:19 -06:00
|
|
|
#include <algorithm>
|
2008-08-31 23:59:13 -06:00
|
|
|
#include <cassert>
|
2014-12-30 02:31:50 -07:00
|
|
|
#include <cstring> // For std::memset
|
2011-02-26 06:09:58 -07:00
|
|
|
#include <iomanip>
|
|
|
|
#include <sstream>
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2016-04-08 11:52:15 -06:00
|
|
|
#include "bitboard.h"
|
2008-08-31 23:59:13 -06:00
|
|
|
#include "evaluate.h"
|
2013-04-28 16:54:08 -06:00
|
|
|
#include "material.h"
|
|
|
|
#include "pawns.h"
|
Use per-thread dynamic contempt
We now use per-thread dynamic contempt. This patch has the following
effects:
* for Threads=1: **non-functional**
* for Threads>1:
* with MultiPV=1: **no regression, little to no ELO gain**
* with MultiPV>1: **clear improvement over master**
First, I tried testing at standard MultiPV=1 play with [0,5] bounds.
This yielded 2 yellow and 1 red test:
5+0.05, Threads=5:
LLR: -2.96 (-2.94,2.94) [0.00,5.00]
Total: 82689 W: 16439 L: 16190 D: 50060
http://tests.stockfishchess.org/tests/view/5aa93a5a0ebc5902952892e6
5+0.05, Threads=8:
LLR: -2.96 (-2.94,2.94) [0.00,5.00]
Total: 27164 W: 4974 L: 4983 D: 17207
http://tests.stockfishchess.org/tests/view/5ab2639b0ebc5902a6fbefd5
5+0.5, Threads=16:
LLR: -2.97 (-2.94,2.94) [0.00,5.00]
Total: 41396 W: 7127 L: 7082 D: 27187
http://tests.stockfishchess.org/tests/view/5ab124220ebc59029516cb62
Then, I tested with Skill Level=17 (implicitly MutliPV=4), showing
a clear improvement:
5+0.05, Threads=5:
LLR: 2.96 (-2.94,2.94) [0.00,5.00]
Total: 3498 W: 1316 L: 1135 D: 1047
http://tests.stockfishchess.org/tests/view/5ab4b6580ebc5902932aeca2
Next, I tested the patch with MultiPV=1 again, this time checking for
non-regression ([-3, 1]):
5+0.5, Threads=5:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 65575 W: 12786 L: 12745 D: 40044
http://tests.stockfishchess.org/tests/view/5ab4e8500ebc5902932aecb3
Finally, I ran some tests with fixed number of games, checking if
reverting dynamic contempt gains more elo with Skill Level=17 (i.e.
MultiPV) than applying the "prevScore" fix and this patch. These tests
showed, that this patch gains 15 ELO when playing with Skill Level=17:
5+0.05, Threads=3, "revert dynamic contempt" vs. "WITHOUT this patch":
ELO: -11.43 +-4.1 (95%) LOS: 0.0%
Total: 20000 W: 7085 L: 7743 D: 5172
http://tests.stockfishchess.org/tests/view/5ab636450ebc590295d88536
5+0.05, Threads=3, "revert dynamic contempt" vs. "WITH this patch":
ELO: -26.42 +-4.1 (95%) LOS: 0.0%
Total: 20000 W: 6661 L: 8179 D: 5160
http://tests.stockfishchess.org/tests/view/5ab62e680ebc590295d88524
---
***FAQ***
**Why should this be commited?**
I believe that the gain for multi-thread MultiPV search is a sufficient
justification for this otherwise neutral change. I also believe this
implementation of dynamic contempt is more logical, although this may
be just my opinion.
**Why is per-thread contempt better at MultiPV?**
A likely explanation for the gain in MultiPV mode is that during
search each thread independently switches between rootMoves and via
the shared contempt score skews each other's evaluation.
**Why were the tests done with Skill Level=17?**
This was originally suggested by @Hanamuke and the idea is that with
Skill Level Stockfish sometimes plays also moves it thinks are slightly
sub-optimal and thus the quality of all moves offered by the MultiPV
search is checked by the test.
**Why are the ELO differences so huge?**
This is most likely because of the nature of Skill Level mode --
since it slower and weaker than normal mode, bugs in evaluation have
much greater effect.
---
Closes https://github.com/official-stockfish/Stockfish/pull/1515.
No functional change -- in single thread mode.
2018-03-30 02:47:05 -06:00
|
|
|
#include "thread.h"
|
2015-02-27 01:52:56 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
namespace Trace {
|
2015-02-27 01:52:56 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
enum Tracing { NO_TRACE, TRACE };
|
2015-08-25 09:12:51 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
enum Term { // The first 8 entries are reserved for PieceType
|
|
|
|
MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, INITIATIVE, TOTAL, TERM_NB
|
|
|
|
};
|
2015-08-25 09:12:51 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
Score scores[TERM_NB][COLOR_NB];
|
2015-08-25 09:12:51 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
double to_cp(Value v) { return double(v) / PawnValueEg; }
|
2015-08-25 09:12:51 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
void add(int idx, Color c, Score s) {
|
|
|
|
scores[idx][c] = s;
|
|
|
|
}
|
2015-08-25 09:12:51 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
void add(int idx, Score w, Score b = SCORE_ZERO) {
|
|
|
|
scores[idx][WHITE] = w;
|
|
|
|
scores[idx][BLACK] = b;
|
2015-02-27 01:52:56 -07:00
|
|
|
}
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
std::ostream& operator<<(std::ostream& os, Score s) {
|
|
|
|
os << std::setw(5) << to_cp(mg_value(s)) << " "
|
|
|
|
<< std::setw(5) << to_cp(eg_value(s));
|
|
|
|
return os;
|
|
|
|
}
|
2015-02-27 01:52:56 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
std::ostream& operator<<(std::ostream& os, Term t) {
|
2017-06-21 15:01:59 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
if (t == MATERIAL || t == IMBALANCE || t == INITIATIVE || t == TOTAL)
|
|
|
|
os << " ---- ----" << " | " << " ---- ----";
|
|
|
|
else
|
|
|
|
os << scores[t][WHITE] << " | " << scores[t][BLACK];
|
2017-06-21 15:01:59 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
}
|
2017-06-21 15:01:59 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
using namespace Trace;
|
2017-01-17 19:40:31 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
namespace {
|
2013-04-28 16:54:08 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Threshold for lazy and space evaluation
|
2019-05-31 06:35:39 -06:00
|
|
|
constexpr Value LazyThreshold = Value(1400);
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Value SpaceThreshold = Value(12222);
|
2013-04-28 16:54:08 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// KingAttackWeights[PieceType] contains king attack weights by piece type
|
Simplify RookOnPawn
Remove the RookOnPawn logic (for rook on rank 5 and above aligning with pawns
on same row or file) which was overlapping with a few other parameters.
Inspired by @31m059 interesting result hinting that a direct attack on pawns
instead of PseudoAttacks might work.
http://tests.stockfishchess.org/tests/view/5d89a7c70ebc595091801b8d
After a few attempts by me and @31m059, and some long STC greens but red LTC,
as a proof of concept I first tried a local SPSA at VSTC trying to tune related
rook psqt rows, and mainly some rook related stuff in evaluate.cpp.
Result was STC green, but still red LTC,
Finally a 100M fishtest SPSA at LTC proved successful both at STC and LTC.
All this was possible with the awesome fishtest contributors.
At some point, I had 850 workers on the last test !
Run as a simplification
STC
http://tests.stockfishchess.org/tests/view/5d8d68f40ebc590f3beaf171
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 7399 W: 1693 L: 1543 D: 4163
LTC
http://tests.stockfishchess.org/tests/view/5d8d70270ebc590f3beaf63c
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 41617 W: 6981 L: 6894 D: 27742
Closes https://github.com/official-stockfish/Stockfish/pull/2329
bench: 4037914
2019-09-25 21:23:07 -06:00
|
|
|
constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
|
2013-04-28 16:54:08 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Penalties for enemy's safe checks
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr int QueenSafeCheck = 780;
|
2019-01-31 23:21:23 -07:00
|
|
|
constexpr int RookSafeCheck = 1080;
|
|
|
|
constexpr int BishopSafeCheck = 635;
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr int KnightSafeCheck = 790;
|
2013-04-28 16:54:08 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
#define S(mg, eg) make_score(mg, eg)
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2017-03-05 19:20:27 -07:00
|
|
|
// MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
|
2017-01-17 19:40:31 -07:00
|
|
|
// indexed by piece type and number of attacked squares in the mobility area.
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Score MobilityBonus[][32] = {
|
2018-10-26 06:17:42 -06:00
|
|
|
{ S(-62,-81), S(-53,-56), S(-12,-30), S( -4,-14), S( 3, 8), S( 13, 15), // Knights
|
|
|
|
S( 22, 23), S( 28, 27), S( 33, 33) },
|
2017-02-19 14:56:17 -07:00
|
|
|
{ S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishops
|
|
|
|
S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
|
|
|
|
S( 91, 88), S( 98, 97) },
|
2017-05-07 21:56:04 -06:00
|
|
|
{ S(-58,-76), S(-27,-18), S(-15, 28), S(-10, 55), S( -5, 69), S( -2, 82), // Rooks
|
|
|
|
S( 9,112), S( 16,118), S( 30,132), S( 29,142), S( 32,155), S( 38,165),
|
|
|
|
S( 46,166), S( 48,169), S( 58,171) },
|
2017-02-19 14:56:17 -07:00
|
|
|
{ S(-39,-36), S(-21,-15), S( 3, 8), S( 3, 18), S( 14, 34), S( 22, 54), // Queens
|
|
|
|
S( 28, 61), S( 41, 73), S( 43, 79), S( 48, 92), S( 56, 94), S( 60,104),
|
|
|
|
S( 60,113), S( 66,120), S( 67,123), S( 70,126), S( 71,133), S( 73,136),
|
|
|
|
S( 79,140), S( 88,143), S( 88,148), S( 99,166), S(102,170), S(102,175),
|
|
|
|
S(106,184), S(109,191), S(113,206), S(116,212) }
|
2008-08-31 23:59:13 -06:00
|
|
|
};
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// RookOnFile[semiopen/open] contains bonuses for each rook when there is
|
|
|
|
// no (friendly) pawn on the rook file.
|
Simplify RookOnPawn
Remove the RookOnPawn logic (for rook on rank 5 and above aligning with pawns
on same row or file) which was overlapping with a few other parameters.
Inspired by @31m059 interesting result hinting that a direct attack on pawns
instead of PseudoAttacks might work.
http://tests.stockfishchess.org/tests/view/5d89a7c70ebc595091801b8d
After a few attempts by me and @31m059, and some long STC greens but red LTC,
as a proof of concept I first tried a local SPSA at VSTC trying to tune related
rook psqt rows, and mainly some rook related stuff in evaluate.cpp.
Result was STC green, but still red LTC,
Finally a 100M fishtest SPSA at LTC proved successful both at STC and LTC.
All this was possible with the awesome fishtest contributors.
At some point, I had 850 workers on the last test !
Run as a simplification
STC
http://tests.stockfishchess.org/tests/view/5d8d68f40ebc590f3beaf171
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 7399 W: 1693 L: 1543 D: 4163
LTC
http://tests.stockfishchess.org/tests/view/5d8d70270ebc590f3beaf63c
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 41617 W: 6981 L: 6894 D: 27742
Closes https://github.com/official-stockfish/Stockfish/pull/2329
bench: 4037914
2019-09-25 21:23:07 -06:00
|
|
|
constexpr Score RookOnFile[] = { S(21, 4), S(47, 25) };
|
2015-12-30 04:29:25 -07:00
|
|
|
|
2016-12-28 15:14:09 -07:00
|
|
|
// ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
|
|
|
|
// which piece type attacks which one. Attacks on lesser pieces which are
|
|
|
|
// pawn-defended are not considered.
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
|
Weak queen protection
Extra penalty if weak piece is only protected by a queen.
STC:
http://tests.stockfishchess.org/tests/view/5e53c6ab84a82b4acd4148fa
LLR: 2.96 (-2.94,2.94) {-0.50,1.50}
Total: 44630 W: 8615 L: 8359 D: 27656
Ptnml(0-2): 746, 5156, 10323, 5276, 814
LTC:
http://tests.stockfishchess.org/tests/view/5e54e05d84a82b4acd414947
LLR: 2.94 (-2.94,2.94) {0.25,1.75}
Total: 175480 W: 23085 L: 22409 D: 129986
Ptnml(0-2): 1264, 16494, 51678, 16910, 1394
closes https://github.com/official-stockfish/Stockfish/pull/2564
Bench: 4923286
2020-02-22 06:57:01 -07:00
|
|
|
S(0, 0), S(5, 32), S(57, 41), S(77, 56), S(88, 119), S(79, 161)
|
2009-11-12 09:42:43 -07:00
|
|
|
};
|
|
|
|
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
|
Weak queen protection
Extra penalty if weak piece is only protected by a queen.
STC:
http://tests.stockfishchess.org/tests/view/5e53c6ab84a82b4acd4148fa
LLR: 2.96 (-2.94,2.94) {-0.50,1.50}
Total: 44630 W: 8615 L: 8359 D: 27656
Ptnml(0-2): 746, 5156, 10323, 5276, 814
LTC:
http://tests.stockfishchess.org/tests/view/5e54e05d84a82b4acd414947
LLR: 2.94 (-2.94,2.94) {0.25,1.75}
Total: 175480 W: 23085 L: 22409 D: 129986
Ptnml(0-2): 1264, 16494, 51678, 16910, 1394
closes https://github.com/official-stockfish/Stockfish/pull/2564
Bench: 4923286
2020-02-22 06:57:01 -07:00
|
|
|
S(0, 0), S(2, 44), S(36, 71), S(36, 61), S(0, 38), S(51, 38)
|
2016-12-28 15:14:09 -07:00
|
|
|
};
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// PassedRank[Rank] contains a bonus according to the rank of a passed pawn
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Score PassedRank[RANK_NB] = {
|
2019-07-20 09:38:45 -06:00
|
|
|
S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
|
2015-10-03 04:46:53 -06:00
|
|
|
};
|
2019-11-12 10:36:12 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Assorted bonuses and penalties
|
2020-03-01 01:31:17 -07:00
|
|
|
constexpr Score BishopPawns = S( 3, 7);
|
|
|
|
constexpr Score CorneredBishop = S( 50, 50);
|
|
|
|
constexpr Score FlankAttacks = S( 8, 0);
|
|
|
|
constexpr Score Hanging = S( 69, 36);
|
|
|
|
constexpr Score KingProtector = S( 7, 8);
|
|
|
|
constexpr Score KnightOnQueen = S( 16, 12);
|
|
|
|
constexpr Score LongDiagonalBishop = S( 45, 0);
|
|
|
|
constexpr Score MinorBehindPawn = S( 18, 3);
|
|
|
|
constexpr Score Outpost = S( 30, 21);
|
|
|
|
constexpr Score PassedFile = S( 11, 8);
|
|
|
|
constexpr Score PawnlessFlank = S( 17, 95);
|
|
|
|
constexpr Score RestrictedPiece = S( 7, 7);
|
|
|
|
constexpr Score RookOnQueenFile = S( 7, 6);
|
|
|
|
constexpr Score SliderOnQueen = S( 59, 18);
|
|
|
|
constexpr Score ThreatByKing = S( 24, 89);
|
|
|
|
constexpr Score ThreatByPawnPush = S( 48, 39);
|
|
|
|
constexpr Score ThreatBySafePawn = S(173, 94);
|
|
|
|
constexpr Score TrappedRook = S( 52, 10);
|
|
|
|
constexpr Score WeakQueen = S( 49, 15);
|
|
|
|
constexpr Score WeakQueenProtection = S( 14, 0);
|
2018-02-20 09:10:37 -07:00
|
|
|
|
|
|
|
#undef S
|
|
|
|
|
|
|
|
// Evaluation class computes and stores attacks tables and other working data
|
|
|
|
template<Tracing T>
|
|
|
|
class Evaluation {
|
2012-03-21 06:19:21 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
public:
|
|
|
|
Evaluation() = delete;
|
|
|
|
explicit Evaluation(const Position& p) : pos(p) {}
|
|
|
|
Evaluation& operator=(const Evaluation&) = delete;
|
|
|
|
Value value();
|
2009-11-07 07:02:10 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
private:
|
|
|
|
template<Color Us> void initialize();
|
|
|
|
template<Color Us, PieceType Pt> Score pieces();
|
|
|
|
template<Color Us> Score king() const;
|
|
|
|
template<Color Us> Score threats() const;
|
|
|
|
template<Color Us> Score passed() const;
|
|
|
|
template<Color Us> Score space() const;
|
|
|
|
ScaleFactor scale_factor(Value eg) const;
|
Dynamic Complexity based on psqt
Adjust initiative score by psqt/2 instead of materialScore/2 which simplifies #2516
Passed STC
http://tests.stockfishchess.org/tests/view/5e2e667dab2d69d58394fc73
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 23198 W: 4506 L: 4353 D: 14339
Ptnml(0-2): 396, 2615, 5380, 2728, 418
Passed LTC
http://tests.stockfishchess.org/tests/view/5e2ed75cab2d69d58394fcbf
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 8519 W: 1179 L: 1062 D: 6278
Ptnml(0-2): 50, 775, 2472, 843, 74
closes https://github.com/official-stockfish/Stockfish/pull/2522
Bench: 4684459
2020-01-27 07:25:41 -07:00
|
|
|
Score initiative(Score score) const;
|
2013-06-01 03:48:38 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
const Position& pos;
|
|
|
|
Material::Entry* me;
|
|
|
|
Pawns::Entry* pe;
|
|
|
|
Bitboard mobilityArea[COLOR_NB];
|
|
|
|
Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
|
|
|
|
|
|
|
|
// attackedBy[color][piece type] is a bitboard representing all squares
|
|
|
|
// attacked by a given color and piece type. Special "piece types" which
|
2018-03-08 18:04:33 -07:00
|
|
|
// is also calculated is ALL_PIECES.
|
2018-02-20 09:10:37 -07:00
|
|
|
Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
|
|
|
|
|
2019-03-31 04:02:19 -06:00
|
|
|
// attackedBy2[color] are the squares attacked by at least 2 units of a given
|
|
|
|
// color, including x-rays. But diagonal x-rays through pawns are not computed.
|
2018-02-20 09:10:37 -07:00
|
|
|
Bitboard attackedBy2[COLOR_NB];
|
|
|
|
|
2019-05-02 11:36:25 -06:00
|
|
|
// kingRing[color] are the squares adjacent to the king plus some other
|
|
|
|
// very near squares, depending on king position.
|
2018-02-20 09:10:37 -07:00
|
|
|
Bitboard kingRing[COLOR_NB];
|
2013-06-01 03:48:38 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// kingAttackersCount[color] is the number of pieces of the given color
|
|
|
|
// which attack a square in the kingRing of the enemy king.
|
|
|
|
int kingAttackersCount[COLOR_NB];
|
|
|
|
|
Renaming some variables in code
Implements renaming suggestions by Marco Costalba, Günther Demetz,
Gontran Lemaire, Ronald de Man, Stéphane Nicolet, Alain Savard,
Joost VandeVondele, Jerry Donald Watson, Mike Whiteley, xoto10,
and I hope that I haven't forgotten anybody.
Perpetual renaming thread for suggestions:
https://github.com/official-stockfish/Stockfish/issues/1426
No functional change.
2018-03-15 03:44:26 -06:00
|
|
|
// kingAttackersWeight[color] is the sum of the "weights" of the pieces of
|
|
|
|
// the given color which attack a square in the kingRing of the enemy king.
|
|
|
|
// The weights of the individual piece types are given by the elements in
|
|
|
|
// the KingAttackWeights array.
|
2018-02-20 09:10:37 -07:00
|
|
|
int kingAttackersWeight[COLOR_NB];
|
|
|
|
|
Renaming some variables in code
Implements renaming suggestions by Marco Costalba, Günther Demetz,
Gontran Lemaire, Ronald de Man, Stéphane Nicolet, Alain Savard,
Joost VandeVondele, Jerry Donald Watson, Mike Whiteley, xoto10,
and I hope that I haven't forgotten anybody.
Perpetual renaming thread for suggestions:
https://github.com/official-stockfish/Stockfish/issues/1426
No functional change.
2018-03-15 03:44:26 -06:00
|
|
|
// kingAttacksCount[color] is the number of attacks by the given color to
|
|
|
|
// squares directly adjacent to the enemy king. Pieces which attack more
|
|
|
|
// than one square are counted multiple times. For instance, if there is
|
2018-02-20 09:10:37 -07:00
|
|
|
// a white knight on g5 and black's king is on g8, this white knight adds 2
|
Renaming some variables in code
Implements renaming suggestions by Marco Costalba, Günther Demetz,
Gontran Lemaire, Ronald de Man, Stéphane Nicolet, Alain Savard,
Joost VandeVondele, Jerry Donald Watson, Mike Whiteley, xoto10,
and I hope that I haven't forgotten anybody.
Perpetual renaming thread for suggestions:
https://github.com/official-stockfish/Stockfish/issues/1426
No functional change.
2018-03-15 03:44:26 -06:00
|
|
|
// to kingAttacksCount[WHITE].
|
|
|
|
int kingAttacksCount[COLOR_NB];
|
2018-02-20 09:10:37 -07:00
|
|
|
};
|
2010-05-15 06:29:21 -06:00
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::initialize() computes king and pawn attacks, and the king ring
|
|
|
|
// bitboard for a given color. This is done at the beginning of the evaluation.
|
2017-06-21 15:01:59 -06:00
|
|
|
template<Tracing T> template<Color Us>
|
|
|
|
void Evaluation<T>::initialize() {
|
2010-05-15 06:29:21 -06:00
|
|
|
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
2019-10-31 10:17:46 -06:00
|
|
|
constexpr Direction Up = pawn_push(Us);
|
|
|
|
constexpr Direction Down = -Up;
|
2019-06-09 07:07:36 -06:00
|
|
|
constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
|
2010-05-15 06:29:21 -06:00
|
|
|
|
2019-01-01 06:13:08 -07:00
|
|
|
const Square ksq = pos.square<KING>(Us);
|
|
|
|
|
2019-04-04 00:49:35 -06:00
|
|
|
Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Find our pawns that are blocked or on the first two ranks
|
2017-01-17 19:40:31 -07:00
|
|
|
Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
|
|
|
|
|
2019-12-08 07:10:14 -07:00
|
|
|
// Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
|
|
|
|
// or controlled by enemy pawns are excluded from the mobility area.
|
|
|
|
mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
|
2017-01-17 19:40:31 -07:00
|
|
|
|
2019-01-01 06:13:08 -07:00
|
|
|
// Initialize attackedBy[] for king and pawns
|
|
|
|
attackedBy[Us][KING] = pos.attacks_from<KING>(ksq);
|
2017-06-21 15:01:59 -06:00
|
|
|
attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
|
2018-02-20 09:10:37 -07:00
|
|
|
attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
|
2019-03-31 04:02:19 -06:00
|
|
|
attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
|
2018-11-19 02:27:52 -07:00
|
|
|
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
// Init our king safety tables
|
2020-03-05 10:37:08 -07:00
|
|
|
Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
|
|
|
|
Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
|
2019-11-16 12:42:47 -07:00
|
|
|
kingRing[Us] = PseudoAttacks[KING][s] | s;
|
2018-03-26 01:26:50 -06:00
|
|
|
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
|
|
|
|
kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
|
2019-01-01 06:13:08 -07:00
|
|
|
|
|
|
|
// Remove from kingRing[] the squares defended by two pawns
|
2019-04-04 00:49:35 -06:00
|
|
|
kingRing[Us] &= ~dblAttackByPawn;
|
2010-05-15 06:29:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::pieces() scores pieces of a given color and type
|
|
|
|
template<Tracing T> template<Color Us, PieceType Pt>
|
|
|
|
Score Evaluation<T>::pieces() {
|
2017-01-17 19:40:31 -07:00
|
|
|
|
2018-04-30 23:12:17 -06:00
|
|
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
2019-10-31 10:17:46 -06:00
|
|
|
constexpr Direction Down = -pawn_push(Us);
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
|
2018-03-20 18:26:12 -06:00
|
|
|
: Rank5BB | Rank4BB | Rank3BB);
|
2015-08-04 01:00:52 -06:00
|
|
|
const Square* pl = pos.squares<Pt>(Us);
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2016-12-28 15:14:09 -07:00
|
|
|
Bitboard b, bb;
|
|
|
|
Score score = SCORE_ZERO;
|
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
attackedBy[Us][Pt] = 0;
|
2010-08-24 07:59:24 -06:00
|
|
|
|
2019-01-01 06:13:08 -07:00
|
|
|
for (Square s = *pl; s != SQ_NONE; s = *++pl)
|
2009-03-06 08:29:46 -07:00
|
|
|
{
|
2009-11-12 09:42:43 -07:00
|
|
|
// Find attacked squares, including x-ray attacks for bishops and rooks
|
2017-12-22 03:50:09 -07:00
|
|
|
b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
|
|
|
|
: Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
|
2014-02-15 05:27:16 -07:00
|
|
|
: pos.attacks_from<Pt>(s);
|
2009-05-09 15:21:26 -06:00
|
|
|
|
2018-02-26 17:18:33 -07:00
|
|
|
if (pos.blockers_for_king(Us) & s)
|
2015-08-04 01:00:52 -06:00
|
|
|
b &= LineBB[pos.square<KING>(Us)][s];
|
2013-11-07 11:59:11 -07:00
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
|
2018-02-20 09:10:37 -07:00
|
|
|
attackedBy[Us][Pt] |= b;
|
|
|
|
attackedBy[Us][ALL_PIECES] |= b;
|
2009-11-11 13:17:38 -07:00
|
|
|
|
2018-12-15 10:09:35 -07:00
|
|
|
if (b & kingRing[Them])
|
2009-11-11 13:17:38 -07:00
|
|
|
{
|
2017-06-21 15:01:59 -06:00
|
|
|
kingAttackersCount[Us]++;
|
|
|
|
kingAttackersWeight[Us] += KingAttackWeights[Pt];
|
Renaming some variables in code
Implements renaming suggestions by Marco Costalba, Günther Demetz,
Gontran Lemaire, Ronald de Man, Stéphane Nicolet, Alain Savard,
Joost VandeVondele, Jerry Donald Watson, Mike Whiteley, xoto10,
and I hope that I haven't forgotten anybody.
Perpetual renaming thread for suggestions:
https://github.com/official-stockfish/Stockfish/issues/1426
No functional change.
2018-03-15 03:44:26 -06:00
|
|
|
kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
|
2009-11-11 13:17:38 -07:00
|
|
|
}
|
|
|
|
|
2018-04-23 13:49:34 -06:00
|
|
|
int mob = popcount(b & mobilityArea[Us]);
|
2013-07-13 15:07:24 -06:00
|
|
|
|
2017-05-09 05:50:05 -06:00
|
|
|
mobility[Us] += MobilityBonus[Pt - 2][mob];
|
2017-03-08 19:45:09 -07:00
|
|
|
|
2014-02-15 05:27:16 -07:00
|
|
|
if (Pt == BISHOP || Pt == KNIGHT)
|
2013-08-13 06:19:42 -06:00
|
|
|
{
|
2018-02-20 09:10:37 -07:00
|
|
|
// Bonus if piece is on an outpost square or can reach one
|
2019-06-03 07:16:33 -06:00
|
|
|
bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
|
2019-11-16 12:42:47 -07:00
|
|
|
if (bb & s)
|
|
|
|
score += Outpost * (Pt == KNIGHT ? 2 : 1);
|
2013-08-13 06:19:42 -06:00
|
|
|
|
No reachable outpost bonus for bishops
Previously, we used various control statements and ternary operators to divide
Outpost into four bonuses, based on whether the outpost was for a knight or
bishop, and whether it was currently an Outpost or merely a potential ("reachable")
one in the future. Bishop outposts, however, have traditionally been worth far
less Elo in testing. An attempt to remove them altogether passed STC, but failed LTC.
Here we include a narrower simplification, removing the reachable Outpost bonus
for bishops. This bonus was always suspect, given that its current implementation
conflicts directly with BishopPawns. BishopPawns penalizes our bishops based on the
number of friendly pawns on the same color of square, but by definition, Outposts
must be pawn-protected! This PR helps to alleviate this conceptual contradiction
without loss of Elo and with slightly simpler code.
On a code level, this allows us to simplify a ternary operator into the previous
"if" block and distribute a multiplication into an existing constant Score. On a
conceptual level, we retire one of the four traditional Outpost bonuses.
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 22277 W: 4882 L: 4762 D: 12633
http://tests.stockfishchess.org/tests/view/5d9aeed60ebc5902b6cf9751
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 51206 W: 8353 L: 8280 D: 34573
http://tests.stockfishchess.org/tests/view/5d9af1940ebc5902b6cf9cd5
Closes https://github.com/official-stockfish/Stockfish/pull/2352
Bench: 3941591
2019-10-07 12:47:43 -06:00
|
|
|
else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
|
Use single param for Outpost and ReachableOutpost.
In November 2019, as a result of the simplification of rank-based outposts by 37698b0,
separate bonuses were introduced for outposts that are currently occupied and outposts
that are reachable on the next move. However, the values of these two bonuses are
quite similar, and they have remained that way for three months of development.
It appears that we can safely retire the separate ReachableOutpost parameter and
use the same Outpost bonus in both cases, restoring the basic principles of Stockfish
outpost evaluation to their pre-November state, while also reducing
the size of the parameter space.
STC:
LLR: 2.96 (-2.94,2.94) {-1.50,0.50}
Total: 47680 W: 9213 L: 9092 D: 29375
Ptnml(0-2): 776, 5573, 11071, 5594, 826
https://tests.stockfishchess.org/tests/view/5e51e33190a0a02810d09802
LTC:
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 14690 W: 1960 L: 1854 D: 10876
Ptnml(0-2): 93, 1381, 4317, 1435, 119
https://tests.stockfishchess.org/tests/view/5e52197990a0a02810d0980f
closes https://github.com/official-stockfish/Stockfish/pull/2559
Bench: 4697493
2020-02-22 19:27:32 -07:00
|
|
|
score += Outpost;
|
No reachable outpost bonus for bishops
Previously, we used various control statements and ternary operators to divide
Outpost into four bonuses, based on whether the outpost was for a knight or
bishop, and whether it was currently an Outpost or merely a potential ("reachable")
one in the future. Bishop outposts, however, have traditionally been worth far
less Elo in testing. An attempt to remove them altogether passed STC, but failed LTC.
Here we include a narrower simplification, removing the reachable Outpost bonus
for bishops. This bonus was always suspect, given that its current implementation
conflicts directly with BishopPawns. BishopPawns penalizes our bishops based on the
number of friendly pawns on the same color of square, but by definition, Outposts
must be pawn-protected! This PR helps to alleviate this conceptual contradiction
without loss of Elo and with slightly simpler code.
On a code level, this allows us to simplify a ternary operator into the previous
"if" block and distribute a multiplication into an existing constant Score. On a
conceptual level, we retire one of the four traditional Outpost bonuses.
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 22277 W: 4882 L: 4762 D: 12633
http://tests.stockfishchess.org/tests/view/5d9aeed60ebc5902b6cf9751
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 51206 W: 8353 L: 8280 D: 34573
http://tests.stockfishchess.org/tests/view/5d9af1940ebc5902b6cf9cd5
Closes https://github.com/official-stockfish/Stockfish/pull/2352
Bench: 3941591
2019-10-07 12:47:43 -06:00
|
|
|
|
2018-07-14 00:26:57 -06:00
|
|
|
// Knight and Bishop bonus for being right behind a pawn
|
|
|
|
if (shift<Down>(pos.pieces(PAWN)) & s)
|
2013-08-17 03:05:55 -06:00
|
|
|
score += MinorBehindPawn;
|
2014-12-27 02:47:21 -07:00
|
|
|
|
2018-06-24 09:07:38 -06:00
|
|
|
// Penalty if the piece is far from the king
|
Use single value for KingProtector.
After some recent big tuning session, the values for King Protector were
simplified to only be used on minor pieces. This patch tries to further
simplify by just using a single value, since current S(6,5) and S(5,6)
are close to each other. The value S(6,6) ended up passing, although
S(5,5) was also tried and failed STC.
STC
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 14261 W: 3288 L: 3151 D: 7822
http://tests.stockfishchess.org/tests/view/5b4ccdf50ebc5902bdb77f65
LTC
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 19606 W: 3396 L: 3273 D: 12937
http://tests.stockfishchess.org/tests/view/5b4ce4280ebc5902bdb7803b
Bench: 5448998
2018-07-16 10:51:43 -06:00
|
|
|
score -= KingProtector * distance(s, pos.square<KING>(Us));
|
2018-06-24 09:07:38 -06:00
|
|
|
|
2014-12-27 02:47:21 -07:00
|
|
|
if (Pt == BISHOP)
|
2017-10-01 16:41:06 -06:00
|
|
|
{
|
2018-04-30 23:12:17 -06:00
|
|
|
// Penalty according to number of pawns on the same color square as the
|
Anchored bishops
Reduce the "bad bishop" penalty when the bishop is protected by
one of our pawns, as it may indicate that the bishop has found
a safe spot outside the pawn chain.
STC:
LLR: 2.94 (-2.94,2.94) {-0.50,1.50}
Total: 176942 W: 34142 L: 33696 D: 109104
Ptnml(0-2): 3129, 20422, 40919, 20876, 3125
http://tests.stockfishchess.org/tests/view/5e6f61aae42a5c3b3ca2e62d
LTC:
LLR: 2.95 (-2.94,2.94) {0.25,1.75}
Total: 42252 W: 5615 L: 5322 D: 31315
Ptnml(0-2): 308, 3881, 12500, 4084, 353
http://tests.stockfishchess.org/tests/view/5e701382e42a5c3b3ca2e661
closes https://github.com/official-stockfish/Stockfish/pull/2587
Bench: 4963440
2020-03-17 01:26:27 -06:00
|
|
|
// bishop, bigger when the center files are blocked with pawns and smaller
|
|
|
|
// when the bishop is outside the pawn chain.
|
2018-04-30 23:12:17 -06:00
|
|
|
Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
|
|
|
|
|
2019-04-16 15:10:53 -06:00
|
|
|
score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
|
Anchored bishops
Reduce the "bad bishop" penalty when the bishop is protected by
one of our pawns, as it may indicate that the bishop has found
a safe spot outside the pawn chain.
STC:
LLR: 2.94 (-2.94,2.94) {-0.50,1.50}
Total: 176942 W: 34142 L: 33696 D: 109104
Ptnml(0-2): 3129, 20422, 40919, 20876, 3125
http://tests.stockfishchess.org/tests/view/5e6f61aae42a5c3b3ca2e62d
LTC:
LLR: 2.95 (-2.94,2.94) {0.25,1.75}
Total: 42252 W: 5615 L: 5322 D: 31315
Ptnml(0-2): 308, 3881, 12500, 4084, 353
http://tests.stockfishchess.org/tests/view/5e701382e42a5c3b3ca2e661
closes https://github.com/official-stockfish/Stockfish/pull/2587
Bench: 4963440
2020-03-17 01:26:27 -06:00
|
|
|
* (!bool(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
|
2014-12-27 02:47:21 -07:00
|
|
|
|
2017-10-07 14:35:19 -06:00
|
|
|
// Bonus for bishop on a long diagonal which can "see" both center squares
|
2018-08-31 07:30:16 -06:00
|
|
|
if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
|
Renaming some variables in code
Implements renaming suggestions by Marco Costalba, Günther Demetz,
Gontran Lemaire, Ronald de Man, Stéphane Nicolet, Alain Savard,
Joost VandeVondele, Jerry Donald Watson, Mike Whiteley, xoto10,
and I hope that I haven't forgotten anybody.
Perpetual renaming thread for suggestions:
https://github.com/official-stockfish/Stockfish/issues/1426
No functional change.
2018-03-15 03:44:26 -06:00
|
|
|
score += LongDiagonalBishop;
|
2017-10-01 16:41:06 -06:00
|
|
|
|
2020-01-09 12:49:13 -07:00
|
|
|
// An important Chess960 pattern: a cornered bishop blocked by a friendly
|
|
|
|
// pawn diagonally in front of it is a very serious problem, especially
|
|
|
|
// when that pawn is also blocked.
|
|
|
|
if ( pos.is_chess960()
|
|
|
|
&& (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
|
|
|
|
{
|
|
|
|
Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
|
|
|
|
if (pos.piece_on(s + d) == make_piece(Us, PAWN))
|
|
|
|
score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
|
|
|
|
: pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
|
|
|
|
: CorneredBishop;
|
|
|
|
}
|
2014-12-27 02:47:21 -07:00
|
|
|
}
|
2013-08-13 06:19:42 -06:00
|
|
|
}
|
2008-08-31 23:59:13 -06:00
|
|
|
|
Remove QueenOn7th and QueenOnPawn
Small simplification.
Passed SPRT(-3,1) both at STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 17051 W: 3132 L: 3005 D: 10914
and LTC:
LLR: 4.55 (-2.94,2.94) [-3.00,1.00]
Total: 24890 W: 3842 L: 3646 D: 17402
The rationale behind this is that I've never managed to add a
Queen on 7th rank bonus in DiscoCheck, because it never showed
to be positive (evne slightly) in testing. The only thing that
worked is Rook on 7th rank.
In terms of SF code, it seemed natural to group it with QueenOnPawn
as well as those are done together. I know you're against groupping
in general, but when it comes to non regression test, you are being
more conservative by groupping. If the group passes SPRT(-3,1) it's
safer to commit, than test every component in SPRT(-3,1) and end up
with the risk of commiting several -1 elo regression instead of just
one -1 elo regression.
In chess terms, perhaps it's just easier to manouver a Queen (which
can more also diagonaly) than a Rook. Therefore you can let the search
do its job without needing eval ad-hoc terms to guide it. For the Rook
which takes more moves to manouver such eval terms can be (marginally)
useful.
bench: 7473314
2014-04-03 07:31:42 -06:00
|
|
|
if (Pt == ROOK)
|
2009-03-06 08:29:46 -07:00
|
|
|
{
|
2019-09-13 13:46:05 -06:00
|
|
|
// Bonus for rook on the same file as a queen
|
|
|
|
if (file_bb(s) & pos.pieces(QUEEN))
|
2019-09-11 21:29:23 -06:00
|
|
|
score += RookOnQueenFile;
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Bonus for rook on an open or semi-open file
|
2019-05-29 02:00:32 -06:00
|
|
|
if (pos.is_on_semiopen_file(Us, s))
|
2019-09-22 19:48:52 -06:00
|
|
|
score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
|
2008-09-24 08:45:19 -06:00
|
|
|
|
2017-01-17 19:40:31 -07:00
|
|
|
// Penalty when trapped by the king, even more if the king cannot castle
|
2015-12-30 04:29:25 -07:00
|
|
|
else if (mob <= 3)
|
2014-12-27 02:47:21 -07:00
|
|
|
{
|
2018-02-15 11:34:23 -07:00
|
|
|
File kf = file_of(pos.square<KING>(Us));
|
|
|
|
if ((kf < FILE_E) == (file_of(s) < kf))
|
2019-01-21 11:55:51 -07:00
|
|
|
score -= TrappedRook * (1 + !pos.castling_rights(Us));
|
2014-12-27 02:47:21 -07:00
|
|
|
}
|
2008-08-31 23:59:13 -06:00
|
|
|
}
|
2016-06-04 07:57:17 -06:00
|
|
|
|
|
|
|
if (Pt == QUEEN)
|
|
|
|
{
|
|
|
|
// Penalty if any relative pin or discovered attack against the queen
|
2018-02-26 17:18:33 -07:00
|
|
|
Bitboard queenPinners;
|
|
|
|
if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
|
2016-06-04 07:57:17 -06:00
|
|
|
score -= WeakQueen;
|
|
|
|
}
|
2008-09-24 08:45:19 -06:00
|
|
|
}
|
2017-06-21 15:01:59 -06:00
|
|
|
if (T)
|
2015-08-25 09:12:51 -06:00
|
|
|
Trace::add(Pt, Us, score);
|
2011-02-26 06:09:58 -07:00
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
return score;
|
2009-09-28 03:46:55 -06:00
|
|
|
}
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2009-09-28 05:27:05 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::king() assigns bonuses and penalties to a king of a given color
|
|
|
|
template<Tracing T> template<Color Us>
|
|
|
|
Score Evaluation<T>::king() const {
|
2008-09-23 16:32:53 -06:00
|
|
|
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
|
|
|
constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
|
2018-03-27 08:44:47 -06:00
|
|
|
: AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
|
2009-11-12 11:01:44 -07:00
|
|
|
|
2019-11-16 04:53:11 -07:00
|
|
|
Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
|
2019-02-08 02:36:03 -07:00
|
|
|
Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
|
2019-01-01 06:13:08 -07:00
|
|
|
int kingDanger = 0;
|
2016-12-28 15:14:09 -07:00
|
|
|
const Square ksq = pos.square<KING>(Us);
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2019-01-01 06:13:08 -07:00
|
|
|
// Init the score with king shelter and enemy pawns storm
|
2018-11-10 20:49:13 -07:00
|
|
|
Score score = pe->king_safety<Us>(pos);
|
2008-08-31 23:59:13 -06:00
|
|
|
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
// Attacked squares defended at most once by our queen or king
|
|
|
|
weak = attackedBy[Them][ALL_PIECES]
|
|
|
|
& ~attackedBy2[Us]
|
|
|
|
& (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
|
|
|
|
|
|
|
|
// Analyse the safe enemy's checks which are possible on next move
|
|
|
|
safe = ~pos.pieces(Them);
|
|
|
|
safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
|
|
|
|
|
|
|
|
b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
|
|
|
|
b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
|
|
|
|
|
|
|
|
// Enemy rooks checks
|
2019-02-08 02:36:03 -07:00
|
|
|
rookChecks = b1 & safe & attackedBy[Them][ROOK];
|
2019-01-31 23:21:23 -07:00
|
|
|
|
2019-02-08 02:36:03 -07:00
|
|
|
if (rookChecks)
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
kingDanger += RookSafeCheck;
|
|
|
|
else
|
2019-01-31 23:21:23 -07:00
|
|
|
unsafeChecks |= b1 & attackedBy[Them][ROOK];
|
|
|
|
|
|
|
|
// Enemy queen safe checks: we count them only if they are from squares from
|
|
|
|
// which we can't give a rook check, because rook checks are more valuable.
|
2019-02-08 02:36:03 -07:00
|
|
|
queenChecks = (b1 | b2)
|
|
|
|
& attackedBy[Them][QUEEN]
|
|
|
|
& safe
|
|
|
|
& ~attackedBy[Us][QUEEN]
|
|
|
|
& ~rookChecks;
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
|
2019-02-08 02:36:03 -07:00
|
|
|
if (queenChecks)
|
2019-01-31 23:21:23 -07:00
|
|
|
kingDanger += QueenSafeCheck;
|
|
|
|
|
|
|
|
// Enemy bishops checks: we count them only if they are from squares from
|
|
|
|
// which we can't give a queen check, because queen checks are more valuable.
|
2019-02-08 02:36:03 -07:00
|
|
|
bishopChecks = b2
|
|
|
|
& attackedBy[Them][BISHOP]
|
|
|
|
& safe
|
|
|
|
& ~queenChecks;
|
2019-01-31 23:21:23 -07:00
|
|
|
|
2019-02-08 02:36:03 -07:00
|
|
|
if (bishopChecks)
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
kingDanger += BishopSafeCheck;
|
|
|
|
else
|
2019-01-31 23:21:23 -07:00
|
|
|
unsafeChecks |= b2 & attackedBy[Them][BISHOP];
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
|
|
|
|
// Enemy knights checks
|
2019-02-08 02:36:03 -07:00
|
|
|
knightChecks = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
|
2019-01-31 23:21:23 -07:00
|
|
|
|
2019-02-08 02:36:03 -07:00
|
|
|
if (knightChecks & safe)
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
kingDanger += KnightSafeCheck;
|
|
|
|
else
|
2019-02-08 02:36:03 -07:00
|
|
|
unsafeChecks |= knightChecks;
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
|
2019-11-16 04:53:11 -07:00
|
|
|
// Find the squares that opponent attacks in our king flank, the squares
|
|
|
|
// which they attack twice in that flank, and the squares that we defend.
|
2019-01-01 06:13:08 -07:00
|
|
|
b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
|
|
|
|
b2 = b1 & attackedBy2[Them];
|
2019-11-16 04:53:11 -07:00
|
|
|
b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
|
2019-01-01 06:13:08 -07:00
|
|
|
|
2019-11-16 04:53:11 -07:00
|
|
|
int kingFlankAttack = popcount(b1) + popcount(b2);
|
|
|
|
int kingFlankDefense = popcount(b3);
|
2019-01-01 06:13:08 -07:00
|
|
|
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
|
|
|
|
+ 185 * popcount(kingRing[Us] & weak)
|
2019-08-14 02:02:21 -06:00
|
|
|
+ 148 * popcount(unsafeChecks)
|
|
|
|
+ 98 * popcount(pos.blockers_for_king(Us))
|
2019-10-18 18:20:38 -06:00
|
|
|
+ 69 * kingAttacksCount[Them]
|
2019-11-16 04:53:11 -07:00
|
|
|
+ 3 * kingFlankAttack * kingFlankAttack / 8
|
2019-10-18 18:20:38 -06:00
|
|
|
+ mg_value(mobility[Them] - mobility[Us])
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
- 873 * !pos.count<QUEEN>(Them)
|
2019-10-18 18:20:38 -06:00
|
|
|
- 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
- 6 * mg_value(score) / 8
|
2019-11-25 16:56:53 -07:00
|
|
|
- 4 * kingFlankDefense
|
|
|
|
+ 37;
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
|
|
|
|
// Transform the kingDanger units into a Score, and subtract it from the evaluation
|
Raise kingDanger threshold and adjust constant term #2087
The kingDanger term is intended to give a penalty which increases rapidly in the middlegame but less so in the endgame. To this end, the middlegame component is quadratic, and the endgame component is linear. However, this produces unintended consequences for relatively small values of kingDanger: the endgame penalty will exceed the middlegame penalty. This remains true up to kingDanger = 256 (a S(16, 16) penalty), so some of these inaccurate penalties are actually rather large.
In this patch, we increase the threshold for applying the kingDanger penalty to eliminate some of this unintended behavior. This was very nearly, but not quite, sufficient to pass on its own. The patch was finally successful by integrating a second kingDanger tweak by @Vizvezdenec, increasing the kingDanger constant term slightly and improving both STC and LTC performance.
Where do we go from here? I propose that in the future, any attempts to tune kingDanger coefficients should also consider tuning the kingDanger threshold. The evidence shows clearly that it should not be automatically taken to be zero.
Special thanks to @Vizvezdenec for the kingDanger constant tweak. Thanks also to all the approvers and CPU donors who made this possible!
STC:
LLR: -2.96 (-2.94,2.94) [0.00,4.00]
Total: 141225 W: 31239 L: 30846 D: 79140
http://tests.stockfishchess.org/tests/view/5cabbdb20ebc5925cf00b86c
LTC:
LLR: 2.95 (-2.94,2.94) [0.00,4.00]
Total: 30708 W: 5296 L: 5043 D: 20369
http://tests.stockfishchess.org/tests/view/5cabff760ebc5925cf00c22d
Bench: 3445945
2019-04-09 11:35:17 -06:00
|
|
|
if (kingDanger > 100)
|
Always initialize and evaluate king safety
Recent tests by @xoto10, @Vizvezdenec, and myself seemed to hint that Elo could
be gained by expanding the number of cases where king safety is applied. Several
users (@Spliffjiffer, @Vizvezdenec) have anticipated benefits specifically in
evaluation of tactics. It appears that we actually do not need to restrict the
cases in which we initialize and evaluate king safety at all: initializing and
evaluating it in every position appears roughly Elo-neutral at STC and possibly
a substantial Elo gain at LTC.
Any explanation for this scaling is, at this point, conjecture. Assuming it is
not due to chance, my hypothesis is that initialization of king safety in all
positions is a mild slowdown, offset by an Elo gain of evaluating king safety
in all positions. At STC this produces Elo gains and losses that offset each
other, while at longer time control the slowdown is much less important, leaving
only the Elo gain. It probably helps SF to explore king attacks much earlier in
search with high numbers of enemy pieces concentrating but not essentially attacking
king ring.
Thanks to @xoto10 and @Vizvezdenec for helping run my LTC!
Closes https://github.com/official-stockfish/Stockfish/pull/1906
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 35432 W: 7815 L: 7721 D: 19896
http://tests.stockfishchess.org/tests/view/5c24779d0ebc5902ba131b26
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12887 W: 2217 L: 2084 D: 8586
http://tests.stockfishchess.org/tests/view/5c25049a0ebc5902ba132586
Bench: 3163951
------------------
How to continue from there?
* Next step will be to tune all the king danger terms once more after that :-)
2018-12-26 23:51:43 -07:00
|
|
|
score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
|
2011-02-26 06:09:58 -07:00
|
|
|
|
2018-02-27 11:10:40 -07:00
|
|
|
// Penalty when our king is on a pawnless flank
|
2019-01-01 06:13:08 -07:00
|
|
|
if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
|
2018-02-27 11:10:40 -07:00
|
|
|
score -= PawnlessFlank;
|
2016-08-27 16:16:28 -06:00
|
|
|
|
2019-01-01 06:13:08 -07:00
|
|
|
// Penalty if king flank is under attack, potentially moving toward the king
|
2019-11-16 04:53:11 -07:00
|
|
|
score -= FlankAttacks * kingFlankAttack;
|
2016-08-27 16:16:28 -06:00
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
if (T)
|
2015-08-25 09:12:51 -06:00
|
|
|
Trace::add(KING, Us, score);
|
2011-02-26 06:09:58 -07:00
|
|
|
|
2011-05-02 01:43:16 -06:00
|
|
|
return score;
|
2008-08-31 23:59:13 -06:00
|
|
|
}
|
|
|
|
|
2014-10-23 11:10:11 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::threats() assigns bonuses according to the types of the
|
|
|
|
// attacking and the attacked pieces.
|
|
|
|
template<Tracing T> template<Color Us>
|
|
|
|
Score Evaluation<T>::threats() const {
|
2013-10-18 09:42:52 -06:00
|
|
|
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
2019-10-31 10:17:46 -06:00
|
|
|
constexpr Direction Up = pawn_push(Us);
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
|
2013-10-18 09:42:52 -06:00
|
|
|
|
2019-02-08 02:36:03 -07:00
|
|
|
Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
|
2013-10-18 09:42:52 -06:00
|
|
|
Score score = SCORE_ZERO;
|
|
|
|
|
Introduce Overload
This patch applies a S(10, 5) bonus for every square that is:
- Occupied by an enemy piece which is not a pawn
- Attacked exactly once by our pieces
- Defended exactly once by enemy pieces
The idea is that these pieces must be defended. Their defenders have
dramatically limited mobility, and they are vulnerable to our future
attack.
As with connectivity, there are probably many more tests to be run in
this area. In particular:
- I believe @snicolet's queen overload tests have demonstrated a potential
need for a queen overload bonus above and beyond this one; however, the
conditions for "overload" in this patch are different (excluding pieces
we attack twice). My next test after this is (hopefully) merged will be
to intersect the Bitboard I define here with the enemy's queen attacks and
attempt to give additional bonus.
- Perhaps we should exclude pieces attacked by pawns--can pawns really be
overloaded? Should they have the same weight, or less? This didn't work
with a previous version, but it could work with this one.
- More generally, different pieces may need more or less bonus. We could
change bonuses based on what type of enemy piece is being overloaded, what
type of friendly piece is attacking, and/or what type of piece is being
defended by the overloaded piece and attacked by us, or any intersection
of these three. For example, here attacked/defended pawns are excluded,
but they're not totally worthless targets, and could be added again with
a smaller bonus.
- This list is by no means exhaustive.
STC:
LLR: 2.96 (-2.94,2.94) [0.00,5.00]
Total: 17439 W: 3599 L: 3390 D: 10450
http://tests.stockfishchess.org/tests/view/5ac78a2e0ebc59435923735e
LTC:
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 43304 W: 6533 L: 6256 D: 30515
http://tests.stockfishchess.org/tests/view/5ac7a1d80ebc59435923736f
Closes https://github.com/official-stockfish/Stockfish/pull/1533
Bench: 5248871
----------------
This is my first time opening a PR, so I apologize if there are errors.
There are too many people to thank since I submitted my first test just
over a month ago. Thank you all for the warm welcome and here is to more
green patches!
In particular, I would like to thank:
- @crossbr, whose comment in a FishCooking thread first inspired me to
consider the overloading of pieces other than queens,
- @snicolet, whose queen overload tests inspired this one and served as
the base of my first overload attempts,
- @protonspring, whose connectivity tests inspired this one and who provided
much of the feedback needed to take this from red to green,
- @vondele, who kindly corrected me when I submitted a bad LTC test,
- @Rocky640, who has helped me over and over again in the past month.
Thank you all!
2018-04-06 17:20:48 -06:00
|
|
|
// Non-pawn enemies
|
2019-01-01 06:10:26 -07:00
|
|
|
nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
|
2015-03-29 01:54:25 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Squares strongly protected by the enemy, either because they defend the
|
|
|
|
// square with a pawn, or because they defend the square twice and we don't.
|
2017-06-21 15:01:59 -06:00
|
|
|
stronglyProtected = attackedBy[Them][PAWN]
|
|
|
|
| (attackedBy2[Them] & ~attackedBy2[Us]);
|
2017-02-25 18:43:54 -07:00
|
|
|
|
|
|
|
// Non-pawn enemies, strongly protected
|
2018-02-20 09:10:37 -07:00
|
|
|
defended = nonPawnEnemies & stronglyProtected;
|
2014-06-30 08:55:10 -06:00
|
|
|
|
2017-02-25 18:43:54 -07:00
|
|
|
// Enemies not strongly protected and under our attack
|
2018-02-20 09:10:37 -07:00
|
|
|
weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
|
2013-10-18 09:42:52 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Bonus according to the kind of attacking pieces
|
2015-10-18 20:17:37 -06:00
|
|
|
if (defended | weak)
|
2013-12-18 12:00:01 -07:00
|
|
|
{
|
2017-06-21 15:01:59 -06:00
|
|
|
b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
|
2014-11-04 08:40:37 -07:00
|
|
|
while (b)
|
2019-09-30 15:10:44 -06:00
|
|
|
score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
|
2013-12-18 12:00:01 -07:00
|
|
|
|
2018-07-22 16:02:37 -06:00
|
|
|
b = weak & attackedBy[Us][ROOK];
|
2014-11-04 08:40:37 -07:00
|
|
|
while (b)
|
2019-09-30 15:10:44 -06:00
|
|
|
score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
|
2014-04-26 17:35:46 -06:00
|
|
|
|
Simplify ThreatByKing to be a single Score.
In the current master, ThreatByKing is an array of two Scores, one for
when we have a single attack and one for when we have many. The latter
case is very rarely called during bench and was recently given a strange
negative value during a tuning run, as pointed out by @candirufish on
commit efd4ca2. Here, we simplify away this second case entirely, and
increase the remaining ThreatByKing to compensate.
Although I derived the parameter tweak independently, with the goal of
preserving the same average bonus, I later noticed that a very similar
Score had already been derived by an ongoing SPSA tuning session.
I therefore recognize @candirufish for first discovering these values.
I would also like to thank @Rocky640 for valuable feedback that pointed
me in the direction of ThreatByKing.
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 7677 W: 1772 L: 1623 D: 4282
http://tests.stockfishchess.org/tests/view/5b3db0320ebc5902b9ffe97a
LTC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 108031 W: 18329 L: 18350 D: 71352
http://tests.stockfishchess.org/tests/view/5b3dbf4b0ebc5902b9ffe9db
Closes https://github.com/official-stockfish/Stockfish/pull/1666
Bench: 4678861
2018-07-04 20:18:52 -06:00
|
|
|
if (weak & attackedBy[Us][KING])
|
|
|
|
score += ThreatByKing;
|
2018-04-18 11:44:22 -06:00
|
|
|
|
2018-12-01 02:28:10 -07:00
|
|
|
b = ~attackedBy[Them][ALL_PIECES]
|
|
|
|
| (nonPawnEnemies & attackedBy2[Us]);
|
|
|
|
score += Hanging * popcount(weak & b);
|
Weak queen protection
Extra penalty if weak piece is only protected by a queen.
STC:
http://tests.stockfishchess.org/tests/view/5e53c6ab84a82b4acd4148fa
LLR: 2.96 (-2.94,2.94) {-0.50,1.50}
Total: 44630 W: 8615 L: 8359 D: 27656
Ptnml(0-2): 746, 5156, 10323, 5276, 814
LTC:
http://tests.stockfishchess.org/tests/view/5e54e05d84a82b4acd414947
LLR: 2.94 (-2.94,2.94) {0.25,1.75}
Total: 175480 W: 23085 L: 22409 D: 129986
Ptnml(0-2): 1264, 16494, 51678, 16910, 1394
closes https://github.com/official-stockfish/Stockfish/pull/2564
Bench: 4923286
2020-02-22 06:57:01 -07:00
|
|
|
|
|
|
|
// Additional bonus if weak piece is only protected by a queen
|
2020-03-01 01:31:17 -07:00
|
|
|
score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
|
2014-09-21 11:27:34 -06:00
|
|
|
}
|
2013-10-18 09:42:52 -06:00
|
|
|
|
2018-11-19 23:45:00 -07:00
|
|
|
// Bonus for restricting their piece moves
|
2019-02-08 02:36:03 -07:00
|
|
|
b = attackedBy[Them][ALL_PIECES]
|
|
|
|
& ~stronglyProtected
|
|
|
|
& attackedBy[Us][ALL_PIECES];
|
Revert 5 recent patches
Revert 5 patches which were merged, but lead to a regression test that showed negative Elo gain:
http://tests.stockfishchess.org/tests/view/5e307251ab2d69d58394fdb9
This was discussed in depth in:
https://github.com/official-stockfish/Stockfish/issues/2531
Each patch was removed and tested as a simplification, full list below, and the whole combo as well.
After the revert the regression test showed a neutral result:
http://tests.stockfishchess.org/tests/view/5e334851708b13464ceea33c
As a result of this experience, the SPRT testing bounds will be made more strict.
Reverted patches:
1 Dynamic Complexity 6d0eabd5fe2961551477820ab7619e2c31e01ffd :
STC 10+0.1 https://tests.stockfishchess.org/tests/view/5e31fcacec661e2e6a340d08 :
LLR: 2.97 (-2.94,2.94) {-1.50,0.50}
Total: 38130 W: 7326 L: 7189 D: 23615
Ptnml(0-2): 677, 4346, 8843, 4545, 646
LTC 60+0.6 https://tests.stockfishchess.org/tests/view/5e32c18fec661e2e6a340d73 :
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 38675 W: 4941 L: 4866 D: 28868
Ptnml(0-2): 270, 3556, 11429, 3584, 291
3 More bonus for bestMoves on past PV nodes 71e0b5385e2717679a57c6b77d8c7ac5fff3b89f :
STC 10+0.1 https://tests.stockfishchess.org/tests/view/5e31fe93ec661e2e6a340d10 :
LLR: 2.95 (-2.94,2.94) {-1.50,0.50}
Total: 46100 W: 8853 L: 8727 D: 28520
Ptnml(0-2): 796, 5297, 10749, 5387, 813
LTC 60+0.6 https://tests.stockfishchess.org/tests/view/5e32c187ec661e2e6a340d71 :
LLR: 2.96 (-2.94,2.94) {-1.50,0.50}
Total: 16920 W: 2161 L: 2055 D: 12704
Ptnml(0-2): 115, 1498, 5006, 1569, 130
4 Tweak Restricted Piece Bonus 0ae00454ba6928d181b46103e5c83e6d58fcebe5 :
STC 10+0.1 https://tests.stockfishchess.org/tests/view/5e31fefaec661e2e6a340d15 :
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 88328 W: 17060 L: 16997 D: 54271
Ptnml(0-2): 1536, 10446, 20169, 10422, 1581
LTC 60+0.6 https://tests.stockfishchess.org/tests/view/5e32c17aec661e2e6a340d6f :
LLR: 2.95 (-2.94,2.94) {-1.50,0.50}
Total: 34784 W: 4551 L: 4466 D: 25767
Ptnml(0-2): 255, 3279, 10061, 3345, 262
5 History update for pruned captures 01b6088af39902001d2d6844561b6a2faa549282 :
STC 10+0.1 https://tests.stockfishchess.org/tests/view/5e31ff5eec661e2e6a340d1a :
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 29541 W: 5735 L: 5588 D: 18218
Ptnml(0-2): 483, 3445, 6820, 3469, 545
LTC 60+0.6 https://tests.stockfishchess.org/tests/view/5e32c196ec661e2e6a340d75 :
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 22177 W: 2854 L: 2757 D: 16566
Ptnml(0-2): 143, 2005, 6555, 2055, 164
6 Tweak trapped rook penalty 18fc21eba0368fd5e3c4c4b8ee1000c9ac445425 :
STC 10+0.1 https://tests.stockfishchess.org/tests/view/5e31ffb1ec661e2e6a340d1c :
LLR: 2.95 (-2.94,2.94) {-1.50,0.50}
Total: 24476 W: 4727 L: 4569 D: 15180
Ptnml(0-2): 390, 2834, 5659, 2933, 417
LTC 60+0.6 https://tests.stockfishchess.org/tests/view/5e32c19eec661e2e6a340d77 :
LLR: 2.95 (-2.94,2.94) {-1.50,0.50}
Total: 97332 W: 12492 L: 12466 D: 72374
Ptnml(0-2): 690, 9107, 28738, 9034, 720
All 5 as one simplification :
LTC 60+0.6 https://tests.stockfishchess.org/tests/view/5e334098708b13464ceea330 :
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 7829 W: 1079 L: 964 D: 5786
Ptnml(0-2): 52, 690, 2281, 781, 65
Bench: 5153165
2020-01-30 13:44:04 -07:00
|
|
|
score += RestrictedPiece * popcount(b);
|
2018-11-19 23:45:00 -07:00
|
|
|
|
2019-08-14 14:15:41 -06:00
|
|
|
// Protected or unattacked squares
|
|
|
|
safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
|
|
|
|
|
|
|
|
// Bonus for attacking enemy pieces with our relatively safe pawns
|
|
|
|
b = pos.pieces(Us, PAWN) & safe;
|
|
|
|
b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
|
|
|
|
score += ThreatBySafePawn * popcount(b);
|
|
|
|
|
2017-06-22 22:03:58 -06:00
|
|
|
// Find squares where our pawns can push on the next move
|
|
|
|
b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
|
|
|
|
b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
|
2015-02-02 20:16:50 -07:00
|
|
|
|
2018-07-25 10:31:02 -06:00
|
|
|
// Keep only the squares which are relatively safe
|
Small reformat in evaluate threats (non functional)
When evaluating threat by safe pawn and pawn push the same expression is used.
STC
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 19444 W: 4540 L: 4309 D: 10595
http://tests.stockfishchess.org/tests/view/5b5a6e150ebc5902bdb8c5c0
Closes https://github.com/official-stockfish/Stockfish/pull/1709
No functional change.
--------------------
Comments by Stéphane Nicolet:
I don't measure any speed-up on my system, with two parallel benches at depth 22:
Total time (ms) : 74989
Nodes searched : 144830258
Nodes/second : 1931353
master
Total time (ms) : 75341
Nodes searched : 144830258
Nodes/second : 1922329
testedpatch
And anyway, like Stefan Geschwentner, I don't think that a 0.3% speed-up would
be enough to pass a [0..5] LTC test -- as a first approximation, we have this
rule of thumb that 1% speed-up gives about 1 Elo point.
However, considering the facts that the reformatting by itself is interesting,
that this is your first green test and that you played by the rules by running
the SPRT[0..5] test before opening the pull request, I will commit the change.
I will only take the liberty to change the occurrences of safe in lines 590 and
591 to b, to make the code more similar to lines 584 and 585.
So approved, and congrats :-)
2018-07-27 02:24:49 -06:00
|
|
|
b &= ~attackedBy[Them][PAWN] & safe;
|
2015-02-14 07:55:11 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Bonus for safe pawn threats on the next move
|
2019-06-09 07:07:36 -06:00
|
|
|
b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
|
2016-04-20 22:23:40 -06:00
|
|
|
score += ThreatByPawnPush * popcount(b);
|
2015-02-02 20:16:50 -07:00
|
|
|
|
2018-03-08 18:04:33 -07:00
|
|
|
// Bonus for threats on the next moves against enemy queen
|
2018-03-07 14:12:29 -07:00
|
|
|
if (pos.count<QUEEN>(Them) == 1)
|
|
|
|
{
|
2018-03-08 18:04:33 -07:00
|
|
|
Square s = pos.square<QUEEN>(Them);
|
Small reformat in evaluate threats (non functional)
When evaluating threat by safe pawn and pawn push the same expression is used.
STC
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 19444 W: 4540 L: 4309 D: 10595
http://tests.stockfishchess.org/tests/view/5b5a6e150ebc5902bdb8c5c0
Closes https://github.com/official-stockfish/Stockfish/pull/1709
No functional change.
--------------------
Comments by Stéphane Nicolet:
I don't measure any speed-up on my system, with two parallel benches at depth 22:
Total time (ms) : 74989
Nodes searched : 144830258
Nodes/second : 1931353
master
Total time (ms) : 75341
Nodes searched : 144830258
Nodes/second : 1922329
testedpatch
And anyway, like Stefan Geschwentner, I don't think that a 0.3% speed-up would
be enough to pass a [0..5] LTC test -- as a first approximation, we have this
rule of thumb that 1% speed-up gives about 1 Elo point.
However, considering the facts that the reformatting by itself is interesting,
that this is your first green test and that you played by the rules by running
the SPRT[0..5] test before opening the pull request, I will commit the change.
I will only take the liberty to change the occurrences of safe in lines 590 and
591 to b, to make the code more similar to lines 584 and 585.
So approved, and congrats :-)
2018-07-27 02:24:49 -06:00
|
|
|
safe = mobilityArea[Us] & ~stronglyProtected;
|
2018-03-08 18:04:33 -07:00
|
|
|
|
|
|
|
b = attackedBy[Us][KNIGHT] & pos.attacks_from<KNIGHT>(s);
|
|
|
|
|
Small reformat in evaluate threats (non functional)
When evaluating threat by safe pawn and pawn push the same expression is used.
STC
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 19444 W: 4540 L: 4309 D: 10595
http://tests.stockfishchess.org/tests/view/5b5a6e150ebc5902bdb8c5c0
Closes https://github.com/official-stockfish/Stockfish/pull/1709
No functional change.
--------------------
Comments by Stéphane Nicolet:
I don't measure any speed-up on my system, with two parallel benches at depth 22:
Total time (ms) : 74989
Nodes searched : 144830258
Nodes/second : 1931353
master
Total time (ms) : 75341
Nodes searched : 144830258
Nodes/second : 1922329
testedpatch
And anyway, like Stefan Geschwentner, I don't think that a 0.3% speed-up would
be enough to pass a [0..5] LTC test -- as a first approximation, we have this
rule of thumb that 1% speed-up gives about 1 Elo point.
However, considering the facts that the reformatting by itself is interesting,
that this is your first green test and that you played by the rules by running
the SPRT[0..5] test before opening the pull request, I will commit the change.
I will only take the liberty to change the occurrences of safe in lines 590 and
591 to b, to make the code more similar to lines 584 and 585.
So approved, and congrats :-)
2018-07-27 02:24:49 -06:00
|
|
|
score += KnightOnQueen * popcount(b & safe);
|
2018-03-08 18:04:33 -07:00
|
|
|
|
|
|
|
b = (attackedBy[Us][BISHOP] & pos.attacks_from<BISHOP>(s))
|
|
|
|
| (attackedBy[Us][ROOK ] & pos.attacks_from<ROOK >(s));
|
2018-03-07 14:12:29 -07:00
|
|
|
|
Small reformat in evaluate threats (non functional)
When evaluating threat by safe pawn and pawn push the same expression is used.
STC
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 19444 W: 4540 L: 4309 D: 10595
http://tests.stockfishchess.org/tests/view/5b5a6e150ebc5902bdb8c5c0
Closes https://github.com/official-stockfish/Stockfish/pull/1709
No functional change.
--------------------
Comments by Stéphane Nicolet:
I don't measure any speed-up on my system, with two parallel benches at depth 22:
Total time (ms) : 74989
Nodes searched : 144830258
Nodes/second : 1931353
master
Total time (ms) : 75341
Nodes searched : 144830258
Nodes/second : 1922329
testedpatch
And anyway, like Stefan Geschwentner, I don't think that a 0.3% speed-up would
be enough to pass a [0..5] LTC test -- as a first approximation, we have this
rule of thumb that 1% speed-up gives about 1 Elo point.
However, considering the facts that the reformatting by itself is interesting,
that this is your first green test and that you played by the rules by running
the SPRT[0..5] test before opening the pull request, I will commit the change.
I will only take the liberty to change the occurrences of safe in lines 590 and
591 to b, to make the code more similar to lines 584 and 585.
So approved, and congrats :-)
2018-07-27 02:24:49 -06:00
|
|
|
score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
|
2018-03-07 14:12:29 -07:00
|
|
|
}
|
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
if (T)
|
2015-12-14 11:04:20 -07:00
|
|
|
Trace::add(THREAT, Us, score);
|
2013-10-18 09:42:52 -06:00
|
|
|
|
2015-12-14 11:04:20 -07:00
|
|
|
return score;
|
2013-10-18 09:42:52 -06:00
|
|
|
}
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::passed() evaluates the passed pawns and candidate passed
|
2017-01-19 10:16:23 -07:00
|
|
|
// pawns of the given color.
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
template<Tracing T> template<Color Us>
|
|
|
|
Score Evaluation<T>::passed() const {
|
2009-01-06 07:49:33 -07:00
|
|
|
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
2019-10-31 10:17:46 -06:00
|
|
|
constexpr Direction Up = pawn_push(Us);
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
auto king_proximity = [&](Color c, Square s) {
|
|
|
|
return std::min(distance(pos.square<KING>(c), s), 5);
|
|
|
|
};
|
|
|
|
|
2019-07-14 06:41:28 -06:00
|
|
|
Bitboard b, bb, squaresToQueen, unsafeSquares;
|
2011-05-02 01:43:16 -06:00
|
|
|
Score score = SCORE_ZERO;
|
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
b = pe->passed_pawns(Us);
|
2009-10-10 03:31:43 -06:00
|
|
|
|
2013-05-25 03:57:18 -06:00
|
|
|
while (b)
|
|
|
|
{
|
2012-07-08 01:30:37 -06:00
|
|
|
Square s = pop_lsb(&b);
|
2008-08-31 23:59:13 -06:00
|
|
|
|
2017-06-22 22:03:58 -06:00
|
|
|
assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
|
2009-01-06 07:49:33 -07:00
|
|
|
|
2018-01-28 06:56:45 -07:00
|
|
|
int r = relative_rank(Us, s);
|
2009-01-06 07:49:33 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
Score bonus = PassedRank[r];
|
2009-01-06 07:49:33 -07:00
|
|
|
|
Replace the PassedDanger array by an equation
This equation seems to do as well as the current PassedDanger array.
Master values were: 3, 7, 11, 20
The new values given by the equation are: 3, 6, 11, 18
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 84301 W: 18155 L: 18156 D: 47990
http://tests.stockfishchess.org/tests/view/5bda03180ebc595e0ae2518e
LTC:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 7940 W: 1358 L: 1217 D: 5365
http://tests.stockfishchess.org/tests/view/5bdc69880ebc595e0ae27d28
We stopped a LTC run after 70000 games:
LLR: 0.74 (-2.94,2.94) [0.00,4.00]
Total: 70257 W: 11319 L: 11064 D: 47874
http://tests.stockfishchess.org/tests/view/5bdca8420ebc595e0ae281a9
Bench: 3913185
2018-10-31 09:05:44 -06:00
|
|
|
if (r > RANK_3)
|
2009-10-10 03:31:43 -06:00
|
|
|
{
|
2019-07-14 06:40:45 -06:00
|
|
|
int w = 5 * r - 13;
|
2017-06-22 22:03:58 -06:00
|
|
|
Square blockSq = s + Up;
|
2009-10-11 03:12:53 -06:00
|
|
|
|
2013-12-02 11:04:09 -07:00
|
|
|
// Adjust bonus based on the king's proximity
|
2019-11-30 07:47:43 -07:00
|
|
|
bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
|
|
|
|
- king_proximity(Us, blockSq) * 2) * w);
|
2011-04-30 06:02:56 -06:00
|
|
|
|
|
|
|
// If blockSq is not the queening square then consider also a second push
|
2018-01-28 06:56:45 -07:00
|
|
|
if (r != RANK_7)
|
2018-02-20 09:10:37 -07:00
|
|
|
bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
|
2009-01-06 07:49:33 -07:00
|
|
|
|
2013-12-02 11:04:09 -07:00
|
|
|
// If the pawn is free to advance, then increase the bonus
|
2013-09-28 06:43:50 -06:00
|
|
|
if (pos.empty(blockSq))
|
2009-01-06 07:49:33 -07:00
|
|
|
{
|
2019-07-14 06:41:28 -06:00
|
|
|
squaresToQueen = forward_file_bb(Us, s);
|
2019-06-21 02:04:31 -06:00
|
|
|
unsafeSquares = passed_pawn_span(Us, s);
|
2014-07-14 07:15:07 -06:00
|
|
|
|
2019-05-17 05:38:23 -06:00
|
|
|
bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
|
2014-07-14 07:15:07 -06:00
|
|
|
|
|
|
|
if (!(pos.pieces(Them) & bb))
|
2019-07-16 02:14:09 -06:00
|
|
|
unsafeSquares &= attackedBy[Them][ALL_PIECES];
|
2019-06-21 02:04:31 -06:00
|
|
|
|
|
|
|
// If there are no enemy attacks on passed pawn span, assign a big bonus.
|
|
|
|
// Otherwise assign a smaller bonus if the path to queen is not attacked
|
|
|
|
// and even smaller bonus if it is attacked but block square is not.
|
|
|
|
int k = !unsafeSquares ? 35 :
|
|
|
|
!(unsafeSquares & squaresToQueen) ? 20 :
|
|
|
|
!(unsafeSquares & blockSq) ? 9 :
|
|
|
|
0 ;
|
2014-04-17 22:41:22 -06:00
|
|
|
|
Exclude passed pawns from Attacked2Unsupported
We recently added a bonus for double pawn attacks on unsupported enemy pawns,
on June 27. However, it is possible that the unsupported pawn may become a passer
by simply pushing forward out of the double attack. By rewarding double attacks,
we may inadvertently reward the creation of enemy passers, by encouraging both of
our would-be stoppers to attack the enemy pawn even if there is no opposing
friendly pawn on the same file.
Here, we revise this term to exclude passed pawns. In order to simplify the code
with this change included, we non-functionally rewrite Attacked2Unsupported to
be a penalty for enemy attacks on friendly pawns, rather than a bonus for our
attacks on enemy pawns. This allows us to exclude passed pawns with a simple
& ~e->passedPawns[Us], while passedPawns[Them] is not yet defined in this part
of the code.
This dramatically reduces the proportion of positions in which Attacked2Unsupported
is applied, to about a third of the original. To compensate, maintaining the same
average effect across our bench positions, we nearly triple Attacked2Unsupported
from S(0, 20) to S(0, 56). Although this pawn formation is rare, it is worth more
than half a pawn in the endgame!
STC: (stopped automatically by fishtest after 250,000 games)
LLR: -0.87 (-2.94,2.94) [0.50,4.50]
Total: 250000 W: 56585 L: 55383 D: 138032
http://tests.stockfishchess.org/tests/view/5d25795e0ebc5925cf0cfb51
LTC:
LLR: 2.96 (-2.94,2.94) [0.00,3.50]
Total: 81038 W: 13965 L: 13558 D: 53515
http://tests.stockfishchess.org/tests/view/5d25f3920ebc5925cf0d10dd
Closes https://github.com/official-stockfish/Stockfish/pull/2233
Bench: 3765158
2019-07-11 07:14:57 -06:00
|
|
|
// Assign a larger bonus if the block square is defended
|
2019-07-14 06:41:28 -06:00
|
|
|
if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
|
Simplify k-value for passers. Bench: 3854907 (#2182)
Stockfish evaluates passed pawns in part based on a variable k, which shapes the passed pawn bonus based on the number of squares between the current square and promotion square that are attacked by enemy pieces, and the number defended by friendly ones. Prior to this commit, we gave a large bonus when all squares between the pawn and the promotion square were defended, and if they were not, a somewhat smaller bonus if at least the pawn's next square was. However, this distinction does not appear to provide any Elo at STC or LTC.
Where do we go from here? Many promising Elo-gaining patches were attempted in the past few months to refine passed pawn calculation, by altering the definitions of unsafe and defended squares. Stockfish uses these definitions to choose the value of k, so those tests interact with this PR. Therefore, it may be worthwhile to retest previously promising but not-quite-passing tests in the vicinity of this patch.
STC:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 42344 W: 9455 L: 9374 D: 23515
http://tests.stockfishchess.org/tests/view/5cf83ede0ebc5925cf0904fb
LTC:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 69548 W: 11855 L: 11813 D: 45880
http://tests.stockfishchess.org/tests/view/5cf8698f0ebc5925cf0908c8
Bench: 3854907
2019-06-09 06:19:07 -06:00
|
|
|
k += 5;
|
2013-05-05 11:12:04 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
bonus += make_score(k * w, k * w);
|
2009-01-06 07:49:33 -07:00
|
|
|
}
|
2019-03-31 04:02:19 -06:00
|
|
|
} // r > RANK_3
|
2009-10-10 03:31:43 -06:00
|
|
|
|
2017-02-25 18:43:54 -07:00
|
|
|
// Scale down bonus for candidate passers which need more than one
|
2018-04-28 22:48:18 -06:00
|
|
|
// pawn push to become passed, or have a pawn in front of them.
|
2018-02-20 09:10:37 -07:00
|
|
|
if ( !pos.pawn_passed(Us, s + Up)
|
Just blockSq, not forward file. Bench: 3377831 (#2240)
This is another functional simplification to Stockfish passed pawn evaluation.
Stockfish evaluates some pawns which are not yet passed as "candidate" passed pawns, which are given half the bonus of fully passed ones. Prior to this commit, Stockfish considered a passed pawn to be a "candidate" if (a) it would not be a passed pawn if moved one square forward (the blocking square), or (b) there were other pawns (of either color) in front of it on the file. This latter condition used a fairly complicated method, forward_file_bb; here, rather than inspect the entire forward file, we simply re-use the blocking square. As a result, some pawns previously considered "candidates", but which are able to push forward, no longer have their bonus halved.
Simplification tests passed quickly at both STC and LTC. The results from both tests imply that this simplification is, most likely, additionally a small Elo gain, with a LTC likelihood of superiority of 87 percent.
STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 12908 W: 2909 L: 2770 D: 7229
http://tests.stockfishchess.org/tests/view/5d2a1c880ebc5925cf0d9006
LTC:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 20723 W: 3591 L: 3470 D: 13662
http://tests.stockfishchess.org/tests/view/5d2a21fd0ebc5925cf0d9118
Bench: 3377831
2019-07-14 06:42:30 -06:00
|
|
|
|| (pos.pieces(PAWN) & (s + Up)))
|
2018-02-20 09:10:37 -07:00
|
|
|
bonus = bonus / 2;
|
2017-01-19 10:16:23 -07:00
|
|
|
|
Equations for edges and corners.
This is a functional simplification that removes the large arrays in endgames.cpp.
It also fixes a recently introduced bug (960d59d54143d84aab26deae65279a611fc989f4) in KNBvK,
now using flip_file() instead of ~.
One fen added to bench to increase endgame coverage.
STC
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 174724 W: 33325 L: 33404 D: 107995
Ptnml(0-2): 2503, 19607, 43181, 19608, 2463
http://tests.stockfishchess.org/tests/view/5e6448ffe42a5c3b3ca2e287
LTC
LLR: 2.95 (-2.94,2.94) {-1.50,0.50}
Total: 35640 W: 4679 L: 4621 D: 26340
Ptnml(0-2): 189, 2991, 11424, 3005, 211
http://tests.stockfishchess.org/tests/view/5e650b24e42a5c3b3ca2e2d8
closes https://github.com/official-stockfish/Stockfish/pull/2577
Bench: 5527957
2020-03-09 15:11:08 -06:00
|
|
|
score += bonus - PassedFile * edge_distance(file_of(s));
|
2013-05-25 03:57:18 -06:00
|
|
|
}
|
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
if (T)
|
2016-02-07 13:58:20 -07:00
|
|
|
Trace::add(PASSED, Us, score);
|
2009-10-10 03:31:43 -06:00
|
|
|
|
2016-02-07 13:58:20 -07:00
|
|
|
return score;
|
2009-10-10 03:31:43 -06:00
|
|
|
}
|
|
|
|
|
2011-05-01 00:11:58 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::space() computes the space evaluation for a given side. The
|
2008-12-21 08:26:36 -07:00
|
|
|
// space evaluation is a simple bonus based on the number of safe squares
|
|
|
|
// available for minor pieces on the central four files on ranks 2--4. Safe
|
|
|
|
// squares one, two or three squares behind a friendly pawn are counted
|
2014-12-31 02:41:20 -07:00
|
|
|
// twice. Finally, the space bonus is multiplied by a weight. The aim is to
|
|
|
|
// improve play on game opening.
|
2017-06-21 15:01:59 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
template<Tracing T> template<Color Us>
|
|
|
|
Score Evaluation<T>::space() const {
|
2008-12-21 08:26:36 -07:00
|
|
|
|
2018-08-08 06:27:28 -06:00
|
|
|
if (pos.non_pawn_material() < SpaceThreshold)
|
|
|
|
return SCORE_ZERO;
|
|
|
|
|
2019-01-20 04:21:16 -07:00
|
|
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
2019-10-31 10:17:46 -06:00
|
|
|
constexpr Direction Down = -pawn_push(Us);
|
2018-03-18 16:38:58 -06:00
|
|
|
constexpr Bitboard SpaceMask =
|
2016-12-28 15:14:09 -07:00
|
|
|
Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
|
|
|
|
: CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
|
2008-12-21 08:26:36 -07:00
|
|
|
|
2018-04-28 22:48:18 -06:00
|
|
|
// Find the available squares for our pieces inside the area defined by SpaceMask
|
2015-11-28 02:57:45 -07:00
|
|
|
Bitboard safe = SpaceMask
|
2012-05-01 05:01:38 -06:00
|
|
|
& ~pos.pieces(Us, PAWN)
|
2018-04-09 17:28:26 -06:00
|
|
|
& ~attackedBy[Them][PAWN];
|
2008-12-21 08:26:36 -07:00
|
|
|
|
2010-05-11 02:07:17 -06:00
|
|
|
// Find all squares which are at most three squares behind some friendly pawn
|
2012-05-01 05:01:38 -06:00
|
|
|
Bitboard behind = pos.pieces(Us, PAWN);
|
2019-01-20 04:21:16 -07:00
|
|
|
behind |= shift<Down>(behind);
|
2019-03-31 04:02:19 -06:00
|
|
|
behind |= shift<Down+Down>(behind);
|
2008-12-21 08:26:36 -07:00
|
|
|
|
2019-07-14 11:13:06 -06:00
|
|
|
int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
|
2019-05-05 07:22:40 -06:00
|
|
|
int weight = pos.count<ALL_PIECES>(Us) - 1;
|
2018-02-20 09:10:37 -07:00
|
|
|
Score score = make_score(bonus * weight * weight / 16, 0);
|
2014-12-31 02:41:20 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
if (T)
|
|
|
|
Trace::add(SPACE, Us, score);
|
|
|
|
|
|
|
|
return score;
|
2008-12-21 08:26:36 -07:00
|
|
|
}
|
|
|
|
|
2015-10-15 22:27:52 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::initiative() computes the initiative correction value
|
|
|
|
// for the position. It is a second order bonus/malus based on the
|
|
|
|
// known attacking/defending status of the players.
|
2017-06-21 15:01:59 -06:00
|
|
|
|
|
|
|
template<Tracing T>
|
Dynamic Complexity based on psqt
Adjust initiative score by psqt/2 instead of materialScore/2 which simplifies #2516
Passed STC
http://tests.stockfishchess.org/tests/view/5e2e667dab2d69d58394fc73
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 23198 W: 4506 L: 4353 D: 14339
Ptnml(0-2): 396, 2615, 5380, 2728, 418
Passed LTC
http://tests.stockfishchess.org/tests/view/5e2ed75cab2d69d58394fcbf
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 8519 W: 1179 L: 1062 D: 6278
Ptnml(0-2): 50, 775, 2472, 843, 74
closes https://github.com/official-stockfish/Stockfish/pull/2522
Bench: 4684459
2020-01-27 07:25:41 -07:00
|
|
|
Score Evaluation<T>::initiative(Score score) const {
|
2015-10-15 22:27:52 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
|
|
|
|
- distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
|
|
|
|
|
2018-09-03 04:46:05 -06:00
|
|
|
bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
|
2018-09-01 02:39:29 -06:00
|
|
|
&& (pos.pieces(PAWN) & KingSide);
|
|
|
|
|
Remove passed_count from almostUnwinnable.
This simplification allows the almostUnwinnable flag to match endgames where the pawns are all on the same flank but are not symmetrical.
STC:
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 23356 W: 4543 L: 4395 D: 14418
Ptnml(0-2): 346, 2651, 5582, 2707, 392
https://tests.stockfishchess.org/tests/view/5e7b8f57e42a5c3b3ca2eb09
LTC:
LLR: 2.96 (-2.94,2.94) {-1.50,0.50}
Total: 31778 W: 4097 L: 4023 D: 23658
Ptnml(0-2): 199, 2853, 9729, 2891, 217
https://tests.stockfishchess.org/tests/view/5e7ba5ade42a5c3b3ca2eb16
closes https://github.com/official-stockfish/Stockfish/pull/2596
Bench 4777139
2020-03-25 10:06:25 -06:00
|
|
|
bool almostUnwinnable = outflanking < 0
|
2019-09-11 21:43:04 -06:00
|
|
|
&& !pawnsOnBothFlanks;
|
|
|
|
|
Reintroduce king infiltration
This patch reintroduces the recently simplified king infiltration bonus
in initiative calculation, doubling its effect, and compensating more.
passed STC
http://tests.stockfishchess.org/tests/view/5e3476f630ae32da08941d5c
LLR: 2.94 (-2.94,2.94) {-0.50,1.50}
Total: 75323 W: 14434 L: 14140 D: 46749
Ptnml(0-2): 1231, 8729, 17528, 8826, 1331
passed LTC
http://tests.stockfishchess.org/tests/view/5e377353e70d848499f638c1
LLR: 2.94 (-2.94,2.94) {0.25,1.75}
Total: 171466 W: 22223 L: 21561 D: 127682
Ptnml(0-2): 1204, 15951, 50831, 16397, 1312
closes https://github.com/official-stockfish/Stockfish/pull/2545
Brench: 4869669
2020-02-04 10:41:58 -07:00
|
|
|
bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
|
|
|
|
|| rank_of(pos.square<KING>(BLACK)) < RANK_5;
|
|
|
|
|
2015-10-15 22:27:52 -06:00
|
|
|
// Compute the initiative bonus for the attacking side
|
2019-03-24 10:41:25 -06:00
|
|
|
int complexity = 9 * pe->passed_count()
|
2019-01-20 04:20:21 -07:00
|
|
|
+ 11 * pos.count<PAWN>()
|
|
|
|
+ 9 * outflanking
|
2019-10-31 23:58:11 -06:00
|
|
|
+ 21 * pawnsOnBothFlanks
|
Reintroduce king infiltration
This patch reintroduces the recently simplified king infiltration bonus
in initiative calculation, doubling its effect, and compensating more.
passed STC
http://tests.stockfishchess.org/tests/view/5e3476f630ae32da08941d5c
LLR: 2.94 (-2.94,2.94) {-0.50,1.50}
Total: 75323 W: 14434 L: 14140 D: 46749
Ptnml(0-2): 1231, 8729, 17528, 8826, 1331
passed LTC
http://tests.stockfishchess.org/tests/view/5e377353e70d848499f638c1
LLR: 2.94 (-2.94,2.94) {0.25,1.75}
Total: 171466 W: 22223 L: 21561 D: 127682
Ptnml(0-2): 1204, 15951, 50831, 16397, 1312
closes https://github.com/official-stockfish/Stockfish/pull/2545
Brench: 4869669
2020-02-04 10:41:58 -07:00
|
|
|
+ 24 * infiltration
|
2019-10-31 23:58:11 -06:00
|
|
|
+ 51 * !pos.non_pawn_material()
|
|
|
|
- 43 * almostUnwinnable
|
Reintroduce king infiltration
This patch reintroduces the recently simplified king infiltration bonus
in initiative calculation, doubling its effect, and compensating more.
passed STC
http://tests.stockfishchess.org/tests/view/5e3476f630ae32da08941d5c
LLR: 2.94 (-2.94,2.94) {-0.50,1.50}
Total: 75323 W: 14434 L: 14140 D: 46749
Ptnml(0-2): 1231, 8729, 17528, 8826, 1331
passed LTC
http://tests.stockfishchess.org/tests/view/5e377353e70d848499f638c1
LLR: 2.94 (-2.94,2.94) {0.25,1.75}
Total: 171466 W: 22223 L: 21561 D: 127682
Ptnml(0-2): 1204, 15951, 50831, 16397, 1312
closes https://github.com/official-stockfish/Stockfish/pull/2545
Brench: 4869669
2020-02-04 10:41:58 -07:00
|
|
|
-110 ;
|
2015-10-15 22:27:52 -06:00
|
|
|
|
Dynamic complexity
Instead of computing the initiative bonus on the material score + dynamic score
compute it on (material score/2) + dynamic score,
Passed STC
http://tests.stockfishchess.org/tests/view/5e2c4945ab2d69d58394fa8f
LLR: 2.94 (-2.94,2.94) {-1.00,3.00}
Total: 39387 W: 7594 L: 7386 D: 24407
Ptnml(0-2): 658, 4519, 9165, 4649, 697
Passed LTC
http://tests.stockfishchess.org/tests/view/5e2c85ccab2d69d58394faa7
LLR: 2.95 (-2.94,2.94) {0.00,2.00}
Total: 32588 W: 4206 L: 3986 D: 24396
Ptnml(0-2): 244, 2909, 9738, 3111, 253
closes https://github.com/official-stockfish/Stockfish/pull/2516
Bench: 4765486
2020-01-25 05:59:42 -07:00
|
|
|
Value mg = mg_value(score);
|
|
|
|
Value eg = eg_value(score);
|
|
|
|
|
2019-09-14 16:32:39 -06:00
|
|
|
// Now apply the bonus: note that we find the attacking side by extracting the
|
|
|
|
// sign of the midgame or endgame values, and that we carefully cap the bonus
|
|
|
|
// so that the midgame and endgame scores do not change sign after the bonus.
|
|
|
|
int u = ((mg > 0) - (mg < 0)) * std::max(std::min(complexity + 50, 0), -abs(mg));
|
2018-02-20 16:52:26 -07:00
|
|
|
int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
|
2015-10-15 22:27:52 -06:00
|
|
|
|
2017-10-21 23:00:46 -06:00
|
|
|
if (T)
|
2019-09-14 16:32:39 -06:00
|
|
|
Trace::add(INITIATIVE, make_score(u, v));
|
2017-10-21 23:00:46 -06:00
|
|
|
|
2019-09-14 16:32:39 -06:00
|
|
|
return make_score(u, v);
|
2015-10-15 22:27:52 -06:00
|
|
|
}
|
|
|
|
|
2015-11-28 02:57:45 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::scale_factor() computes the scale factor for the winning side
|
2017-06-21 15:01:59 -06:00
|
|
|
|
|
|
|
template<Tracing T>
|
2018-02-20 09:10:37 -07:00
|
|
|
ScaleFactor Evaluation<T>::scale_factor(Value eg) const {
|
2015-11-28 02:57:45 -07:00
|
|
|
|
2016-02-25 11:38:35 -07:00
|
|
|
Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
|
2018-02-20 09:10:37 -07:00
|
|
|
int sf = me->scale_factor(pos, strongSide);
|
2015-11-28 02:57:45 -07:00
|
|
|
|
2018-04-28 23:23:32 -06:00
|
|
|
// If scale is not already specific, scale down the endgame via general heuristics
|
|
|
|
if (sf == SCALE_FACTOR_NORMAL)
|
2015-11-28 02:57:45 -07:00
|
|
|
{
|
Slight simplification in scale factor computation
[STC](http://tests.stockfishchess.org/tests/view/5b2614000ebc5902b8d17193)
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 17733 W: 3996 L: 3866 D: 9871
[LTC](http://tests.stockfishchess.org/tests/view/5b264d0f0ebc5902b8d17206)
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 55524 W: 9535 L: 9471 D: 36518
Use pawn count scaling also for opposite bishops endings with additional material, with a slope of 2 instead of 7. This simplifies slightly the code.
This PR is a functionally equivalent refactoring of the version which was submitted.
Four versions tried, 2 passed both STC and LTC. I picked the one which seemed more promising at LTC.
Slope 4 passed STC (-0.54 Elo), LTC not attempted
Slope 3 passed STC (+2.51 Elo), LTC (-0.44 Elo)
Slope 2 passed STC (+2.09 Elo), LTC (+0.04 Elo)
Slope 1 passed STC (+0.90 Elo), failed LTC (-3.40 Elo)
Bench: 4761613
2018-06-19 21:24:24 -06:00
|
|
|
if ( pos.opposite_bishops()
|
2019-03-31 04:02:19 -06:00
|
|
|
&& pos.non_pawn_material() == 2 * BishopValueMg)
|
2019-11-20 12:31:23 -07:00
|
|
|
sf = 22 ;
|
2018-04-28 23:23:32 -06:00
|
|
|
else
|
2019-09-15 15:18:54 -06:00
|
|
|
sf = std::min(sf, 36 + (pos.opposite_bishops() ? 2 : 7) * pos.count<PAWN>(strongSide));
|
2018-09-10 04:02:43 -06:00
|
|
|
|
2019-10-18 18:20:38 -06:00
|
|
|
sf = std::max(0, sf - (pos.rule50_count() - 12) / 4);
|
2015-11-28 02:57:45 -07:00
|
|
|
}
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
return ScaleFactor(sf);
|
2015-11-28 02:57:45 -07:00
|
|
|
}
|
|
|
|
|
2008-12-21 08:26:36 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Evaluation::value() is the main function of the class. It computes the various
|
|
|
|
// parts of the evaluation and returns the value of the position from the point
|
|
|
|
// of view of the side to move.
|
2014-04-12 00:32:52 -06:00
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
template<Tracing T>
|
|
|
|
Value Evaluation<T>::value() {
|
|
|
|
|
|
|
|
assert(!pos.checkers());
|
|
|
|
|
|
|
|
// Probe the material hash table
|
|
|
|
me = Material::probe(pos);
|
|
|
|
|
|
|
|
// If we have a specialized evaluation function for the current material
|
|
|
|
// configuration, call it and return.
|
|
|
|
if (me->specialized_eval_exists())
|
|
|
|
return me->evaluate(pos);
|
|
|
|
|
|
|
|
// Initialize score by reading the incrementally updated scores included in
|
|
|
|
// the position object (material + piece square tables) and the material
|
|
|
|
// imbalance. Score is computed internally from the white point of view.
|
Use per-thread dynamic contempt
We now use per-thread dynamic contempt. This patch has the following
effects:
* for Threads=1: **non-functional**
* for Threads>1:
* with MultiPV=1: **no regression, little to no ELO gain**
* with MultiPV>1: **clear improvement over master**
First, I tried testing at standard MultiPV=1 play with [0,5] bounds.
This yielded 2 yellow and 1 red test:
5+0.05, Threads=5:
LLR: -2.96 (-2.94,2.94) [0.00,5.00]
Total: 82689 W: 16439 L: 16190 D: 50060
http://tests.stockfishchess.org/tests/view/5aa93a5a0ebc5902952892e6
5+0.05, Threads=8:
LLR: -2.96 (-2.94,2.94) [0.00,5.00]
Total: 27164 W: 4974 L: 4983 D: 17207
http://tests.stockfishchess.org/tests/view/5ab2639b0ebc5902a6fbefd5
5+0.5, Threads=16:
LLR: -2.97 (-2.94,2.94) [0.00,5.00]
Total: 41396 W: 7127 L: 7082 D: 27187
http://tests.stockfishchess.org/tests/view/5ab124220ebc59029516cb62
Then, I tested with Skill Level=17 (implicitly MutliPV=4), showing
a clear improvement:
5+0.05, Threads=5:
LLR: 2.96 (-2.94,2.94) [0.00,5.00]
Total: 3498 W: 1316 L: 1135 D: 1047
http://tests.stockfishchess.org/tests/view/5ab4b6580ebc5902932aeca2
Next, I tested the patch with MultiPV=1 again, this time checking for
non-regression ([-3, 1]):
5+0.5, Threads=5:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 65575 W: 12786 L: 12745 D: 40044
http://tests.stockfishchess.org/tests/view/5ab4e8500ebc5902932aecb3
Finally, I ran some tests with fixed number of games, checking if
reverting dynamic contempt gains more elo with Skill Level=17 (i.e.
MultiPV) than applying the "prevScore" fix and this patch. These tests
showed, that this patch gains 15 ELO when playing with Skill Level=17:
5+0.05, Threads=3, "revert dynamic contempt" vs. "WITHOUT this patch":
ELO: -11.43 +-4.1 (95%) LOS: 0.0%
Total: 20000 W: 7085 L: 7743 D: 5172
http://tests.stockfishchess.org/tests/view/5ab636450ebc590295d88536
5+0.05, Threads=3, "revert dynamic contempt" vs. "WITH this patch":
ELO: -26.42 +-4.1 (95%) LOS: 0.0%
Total: 20000 W: 6661 L: 8179 D: 5160
http://tests.stockfishchess.org/tests/view/5ab62e680ebc590295d88524
---
***FAQ***
**Why should this be commited?**
I believe that the gain for multi-thread MultiPV search is a sufficient
justification for this otherwise neutral change. I also believe this
implementation of dynamic contempt is more logical, although this may
be just my opinion.
**Why is per-thread contempt better at MultiPV?**
A likely explanation for the gain in MultiPV mode is that during
search each thread independently switches between rootMoves and via
the shared contempt score skews each other's evaluation.
**Why were the tests done with Skill Level=17?**
This was originally suggested by @Hanamuke and the idea is that with
Skill Level Stockfish sometimes plays also moves it thinks are slightly
sub-optimal and thus the quality of all moves offered by the MultiPV
search is checked by the test.
**Why are the ELO differences so huge?**
This is most likely because of the nature of Skill Level mode --
since it slower and weaker than normal mode, bugs in evaluation have
much greater effect.
---
Closes https://github.com/official-stockfish/Stockfish/pull/1515.
No functional change -- in single thread mode.
2018-03-30 02:47:05 -06:00
|
|
|
Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
|
2017-06-21 15:01:59 -06:00
|
|
|
|
|
|
|
// Probe the pawn hash table
|
|
|
|
pe = Pawns::probe(pos);
|
2018-02-20 09:10:37 -07:00
|
|
|
score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
|
2017-06-21 15:01:59 -06:00
|
|
|
|
|
|
|
// Early exit if score is high
|
|
|
|
Value v = (mg_value(score) + eg_value(score)) / 2;
|
2019-05-02 11:36:25 -06:00
|
|
|
if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
|
2017-06-21 15:01:59 -06:00
|
|
|
return pos.side_to_move() == WHITE ? v : -v;
|
|
|
|
|
|
|
|
// Main evaluation begins here
|
|
|
|
|
|
|
|
initialize<WHITE>();
|
|
|
|
initialize<BLACK>();
|
2014-04-12 00:32:52 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
// Pieces should be evaluated first (populate attack tables)
|
|
|
|
score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
|
|
|
|
+ pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
|
|
|
|
+ pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
|
|
|
|
+ pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
|
2017-06-21 15:01:59 -06:00
|
|
|
|
|
|
|
score += mobility[WHITE] - mobility[BLACK];
|
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
score += king< WHITE>() - king< BLACK>()
|
|
|
|
+ threats<WHITE>() - threats<BLACK>()
|
|
|
|
+ passed< WHITE>() - passed< BLACK>()
|
|
|
|
+ space< WHITE>() - space< BLACK>();
|
2017-06-21 15:01:59 -06:00
|
|
|
|
Dynamic Complexity based on psqt
Adjust initiative score by psqt/2 instead of materialScore/2 which simplifies #2516
Passed STC
http://tests.stockfishchess.org/tests/view/5e2e667dab2d69d58394fc73
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 23198 W: 4506 L: 4353 D: 14339
Ptnml(0-2): 396, 2615, 5380, 2728, 418
Passed LTC
http://tests.stockfishchess.org/tests/view/5e2ed75cab2d69d58394fcbf
LLR: 2.94 (-2.94,2.94) {-1.50,0.50}
Total: 8519 W: 1179 L: 1062 D: 6278
Ptnml(0-2): 50, 775, 2472, 843, 74
closes https://github.com/official-stockfish/Stockfish/pull/2522
Bench: 4684459
2020-01-27 07:25:41 -07:00
|
|
|
score += initiative(score);
|
2017-06-21 15:01:59 -06:00
|
|
|
|
|
|
|
// Interpolate between a middlegame and a (scaled by 'sf') endgame score
|
2018-02-20 09:10:37 -07:00
|
|
|
ScaleFactor sf = scale_factor(eg_value(score));
|
2017-06-21 15:01:59 -06:00
|
|
|
v = mg_value(score) * int(me->game_phase())
|
|
|
|
+ eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
|
|
|
|
|
2019-01-01 06:13:08 -07:00
|
|
|
v /= PHASE_MIDGAME;
|
2017-06-21 15:01:59 -06:00
|
|
|
|
|
|
|
// In case of tracing add all remaining individual evaluation terms
|
|
|
|
if (T)
|
|
|
|
{
|
|
|
|
Trace::add(MATERIAL, pos.psq_score());
|
|
|
|
Trace::add(IMBALANCE, me->imbalance());
|
2018-02-20 09:10:37 -07:00
|
|
|
Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
|
2017-06-21 15:01:59 -06:00
|
|
|
Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
|
|
|
|
Trace::add(TOTAL, score);
|
|
|
|
}
|
|
|
|
|
2020-03-01 01:31:17 -07:00
|
|
|
return (pos.side_to_move() == WHITE ? v : -v) + Tempo; // Side to move point of view
|
2015-08-25 09:12:51 -06:00
|
|
|
}
|
2015-02-13 03:54:46 -07:00
|
|
|
|
2017-06-21 15:01:59 -06:00
|
|
|
} // namespace
|
|
|
|
|
2015-02-13 03:54:46 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
/// 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.
|
2015-02-13 03:54:46 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
Value Eval::evaluate(const Position& pos) {
|
2018-02-20 17:07:35 -07:00
|
|
|
return Evaluation<NO_TRACE>(pos).value();
|
2017-06-21 15:01:59 -06:00
|
|
|
}
|
2013-06-01 03:48:38 -06:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
|
2015-08-25 09:12:51 -06:00
|
|
|
/// trace() is like evaluate(), but instead of returning a value, it returns
|
|
|
|
/// a string (suitable for outputting to stdout) that contains the detailed
|
|
|
|
/// descriptions and values of each evaluation term. Useful for debugging.
|
2014-04-12 00:32:52 -06:00
|
|
|
|
2015-08-25 09:12:51 -06:00
|
|
|
std::string Eval::trace(const Position& pos) {
|
2014-04-12 00:32:52 -06:00
|
|
|
|
2019-11-27 11:03:23 -07:00
|
|
|
if (pos.checkers())
|
|
|
|
return "Total evaluation: none (in check)";
|
|
|
|
|
2015-08-25 09:12:51 -06:00
|
|
|
std::memset(scores, 0, sizeof(scores));
|
2014-04-12 00:32:52 -06:00
|
|
|
|
Use per-thread dynamic contempt
We now use per-thread dynamic contempt. This patch has the following
effects:
* for Threads=1: **non-functional**
* for Threads>1:
* with MultiPV=1: **no regression, little to no ELO gain**
* with MultiPV>1: **clear improvement over master**
First, I tried testing at standard MultiPV=1 play with [0,5] bounds.
This yielded 2 yellow and 1 red test:
5+0.05, Threads=5:
LLR: -2.96 (-2.94,2.94) [0.00,5.00]
Total: 82689 W: 16439 L: 16190 D: 50060
http://tests.stockfishchess.org/tests/view/5aa93a5a0ebc5902952892e6
5+0.05, Threads=8:
LLR: -2.96 (-2.94,2.94) [0.00,5.00]
Total: 27164 W: 4974 L: 4983 D: 17207
http://tests.stockfishchess.org/tests/view/5ab2639b0ebc5902a6fbefd5
5+0.5, Threads=16:
LLR: -2.97 (-2.94,2.94) [0.00,5.00]
Total: 41396 W: 7127 L: 7082 D: 27187
http://tests.stockfishchess.org/tests/view/5ab124220ebc59029516cb62
Then, I tested with Skill Level=17 (implicitly MutliPV=4), showing
a clear improvement:
5+0.05, Threads=5:
LLR: 2.96 (-2.94,2.94) [0.00,5.00]
Total: 3498 W: 1316 L: 1135 D: 1047
http://tests.stockfishchess.org/tests/view/5ab4b6580ebc5902932aeca2
Next, I tested the patch with MultiPV=1 again, this time checking for
non-regression ([-3, 1]):
5+0.5, Threads=5:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 65575 W: 12786 L: 12745 D: 40044
http://tests.stockfishchess.org/tests/view/5ab4e8500ebc5902932aecb3
Finally, I ran some tests with fixed number of games, checking if
reverting dynamic contempt gains more elo with Skill Level=17 (i.e.
MultiPV) than applying the "prevScore" fix and this patch. These tests
showed, that this patch gains 15 ELO when playing with Skill Level=17:
5+0.05, Threads=3, "revert dynamic contempt" vs. "WITHOUT this patch":
ELO: -11.43 +-4.1 (95%) LOS: 0.0%
Total: 20000 W: 7085 L: 7743 D: 5172
http://tests.stockfishchess.org/tests/view/5ab636450ebc590295d88536
5+0.05, Threads=3, "revert dynamic contempt" vs. "WITH this patch":
ELO: -26.42 +-4.1 (95%) LOS: 0.0%
Total: 20000 W: 6661 L: 8179 D: 5160
http://tests.stockfishchess.org/tests/view/5ab62e680ebc590295d88524
---
***FAQ***
**Why should this be commited?**
I believe that the gain for multi-thread MultiPV search is a sufficient
justification for this otherwise neutral change. I also believe this
implementation of dynamic contempt is more logical, although this may
be just my opinion.
**Why is per-thread contempt better at MultiPV?**
A likely explanation for the gain in MultiPV mode is that during
search each thread independently switches between rootMoves and via
the shared contempt score skews each other's evaluation.
**Why were the tests done with Skill Level=17?**
This was originally suggested by @Hanamuke and the idea is that with
Skill Level Stockfish sometimes plays also moves it thinks are slightly
sub-optimal and thus the quality of all moves offered by the MultiPV
search is checked by the test.
**Why are the ELO differences so huge?**
This is most likely because of the nature of Skill Level mode --
since it slower and weaker than normal mode, bugs in evaluation have
much greater effect.
---
Closes https://github.com/official-stockfish/Stockfish/pull/1515.
No functional change -- in single thread mode.
2018-03-30 02:47:05 -06:00
|
|
|
pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
|
2018-02-08 17:10:27 -07:00
|
|
|
|
2018-02-20 17:07:35 -07:00
|
|
|
Value v = Evaluation<TRACE>(pos).value();
|
2018-02-08 17:10:27 -07:00
|
|
|
|
2018-02-20 09:10:37 -07:00
|
|
|
v = pos.side_to_move() == WHITE ? v : -v; // Trace scores are from white's point of view
|
2014-04-12 00:32:52 -06:00
|
|
|
|
2015-08-25 09:12:51 -06:00
|
|
|
std::stringstream ss;
|
|
|
|
ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
|
2018-02-20 09:10:37 -07:00
|
|
|
<< " Term | White | Black | Total \n"
|
|
|
|
<< " | MG EG | MG EG | MG EG \n"
|
|
|
|
<< " ------------+-------------+-------------+------------\n"
|
|
|
|
<< " Material | " << Term(MATERIAL)
|
|
|
|
<< " Imbalance | " << Term(IMBALANCE)
|
|
|
|
<< " Pawns | " << Term(PAWN)
|
|
|
|
<< " Knights | " << Term(KNIGHT)
|
|
|
|
<< " Bishops | " << Term(BISHOP)
|
|
|
|
<< " Rooks | " << Term(ROOK)
|
|
|
|
<< " Queens | " << Term(QUEEN)
|
|
|
|
<< " Mobility | " << Term(MOBILITY)
|
|
|
|
<< " King safety | " << Term(KING)
|
|
|
|
<< " Threats | " << Term(THREAT)
|
|
|
|
<< " Passed | " << Term(PASSED)
|
|
|
|
<< " Space | " << Term(SPACE)
|
2019-02-08 02:36:03 -07:00
|
|
|
<< " Initiative | " << Term(INITIATIVE)
|
2018-02-20 09:10:37 -07:00
|
|
|
<< " ------------+-------------+-------------+------------\n"
|
|
|
|
<< " Total | " << Term(TOTAL);
|
|
|
|
|
|
|
|
ss << "\nTotal evaluation: " << to_cp(v) << " (white side)\n";
|
2014-04-12 00:32:52 -06:00
|
|
|
|
2015-08-25 09:12:51 -06:00
|
|
|
return ss.str();
|
|
|
|
}
|