1
0
Fork 0

Introduce bad outpost penalty

In some French games, Stockfish likes to bring the Knight to a bad outpost spot. This is evident in TCEC S18 Superfinal Game 63, where there is a Knight outpost on the queenside but is actually useless. Stockfish is effectively playing a piece down while holding ground against Leela's break on the kingside.

This patch turns the +56 mg bonus for a Knight outpost into a -7 mg penalty if it satisfies the following conditions:

* The outpost square is not on the CenterFiles (i.e. not on files C,D,E and F)
* The knight is not attacking non pawn enemies.
* The side where the outpost is located contains only few enemies, with a particular conditional_more_than_two() implementation

Thank you to apospa...@gmail.com for bringing this to our attention and for providing insights.
See https://groups.google.com/forum/?fromgroups=#!topic/fishcooking/dEXNzSIBgZU
Reference game: https://tcec-chess.com/#div=sf&game=63&season=18

Passed STC:
LLR: 2.93 (-2.94,2.94) {-0.50,1.50}
Total: 6960 W: 1454 L: 1247 D: 4259
Ptnml(0-2): 115, 739, 1610, 856, 160
https://tests.stockfishchess.org/tests/view/5f08221059f6f0353289477e

Passed LTC:
LLR: 2.98 (-2.94,2.94) {0.25,1.75}
Total: 21440 W: 2767 L: 2543 D: 16130
Ptnml(0-2): 122, 1904, 6462, 2092, 140
https://tests.stockfishchess.org/tests/view/5f0838ed59f6f035328947a2

various related tests show strong test results, but so far no generalizations or simplifications of conditional_more_than_two() are found. See PR for details.

closes https://github.com/official-stockfish/Stockfish/pull/2803

Bench: 4366686
pull/2806/head
SFisGOD 2020-07-08 10:09:32 +08:00 committed by Joost VandeVondele
parent 5e91c5dcc8
commit 1f3bd968bb
2 changed files with 15 additions and 1 deletions

View File

@ -130,6 +130,13 @@ constexpr bool more_than_one(Bitboard b) {
return b & (b - 1);
}
/// Counts the occupation of the bitboard depending on the occupation of SQ_A1
/// as in `b & (1ULL << SQ_A1) ? more_than_two(b) : more_than_one(b)`
constexpr bool conditional_more_than_two(Bitboard b) {
return b & (b - 1) & (b - 2);
}
constexpr bool opposite_colors(Square s1, Square s2) {
return (s1 + rank_of(s1) + s2 + rank_of(s2)) & 1;
}

View File

@ -134,6 +134,7 @@ namespace {
};
// Assorted bonuses and penalties
constexpr Score BadOutpost = S( -7, 36);
constexpr Score BishopOnKingRing = S( 24, 0);
constexpr Score BishopPawns = S( 3, 7);
constexpr Score BishopXRayPawns = S( 4, 5);
@ -310,7 +311,13 @@ namespace {
{
// Bonus if piece is on an outpost square or can reach one
bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
if (bb & s)
if ( Pt == KNIGHT
&& bb & s & ~CenterFiles
&& !(b & pos.pieces(Them) & ~pos.pieces(PAWN))
&& !conditional_more_than_two(
pos.pieces(Them) & ~pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide)))
score += BadOutpost;
else if (bb & s)
score += Outpost[Pt == BISHOP];
else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
score += ReachableOutpost;