Skip to content

Commit a35258d

Browse files
committed
in progress
1 parent 2dee851 commit a35258d

File tree

3 files changed

+80
-20
lines changed

3 files changed

+80
-20
lines changed

.clang-format

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ AlignConsecutiveAssignments: true
88
AlignConsecutiveDeclarations: true
99
AlignTrailingComments: true
1010
AlignOperands: true
11-
AllowShortBlocksOnASingleLine: true
12-
AllowShortCaseLabelsOnASingleLine: true
11+
AllowShortBlocksOnASingleLine: false
12+
AllowShortCaseLabelsOnASingleLine: false
1313
AllowShortFunctionsOnASingleLine: Inline
14-
AllowShortIfStatementsOnASingleLine: true
15-
AllowShortLoopsOnASingleLine: true
14+
AllowShortIfStatementsOnASingleLine: false
15+
AllowShortLoopsOnASingleLine: false
1616
BinPackArguments: false
1717
BinPackParameters: false
1818
BraceWrapping:

src/eval.cpp

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ std::pair<bool, Value> checkGameStatus(Position& board) {
1919
) {
2020
return {true, DRAW_VALUE};
2121
}
22-
if (board.isRepetition()) { return {true, DRAW_VALUE}; }
22+
if (board.isRepetition()) {
23+
return {true, DRAW_VALUE};
24+
}
2325
// Game is not over
2426
return {false, 0};
2527
}
@@ -76,7 +78,9 @@ class Evaluator {
7678
{TYPE_PAWN, TYPE_KNIGHT, TYPE_BISHOP, TYPE_ROOK, TYPE_QUEEN, TYPE_KING}) {
7779
Bitboard bb = pos.pieces(pt, C);
7880
// Count non pawn material
79-
if (pt != TYPE_PAWN) { cache.nonPawnMaterial[C] += PIECE_VALUE[pt] * bb.count(); }
81+
if (pt != TYPE_PAWN) {
82+
cache.nonPawnMaterial[C] += PIECE_VALUE[pt] * bb.count();
83+
}
8084
// Count piece square table score
8185
while (bb) {
8286
Square sq = bb.pop();
@@ -149,6 +153,14 @@ class Evaluator {
149153
bool supported = (bool) (cache.attackedBy[C][Pawn] & sqbb);
150154
total += OUTPOST_BONUS[PT == Bishop][supported];
151155
}
156+
// Penalty for being far away from king
157+
int kingDistance = 0;
158+
if (PT == Knight) {
159+
kingDistance = chess::dist::knight(sq, pos.kingSq(C));
160+
} else {
161+
kingDistance = chess::dist::chebyshev(sq, pos.kingSq(C));
162+
}
163+
total -= KING_DISTANCE_PENALTY * kingDistance;
152164

153165
// todo this hurts performance too
154166
// if (PT == Bishop) {
@@ -171,22 +183,23 @@ class Evaluator {
171183
total += OPEN_ROOK_BONUS[0];
172184
}
173185
}
174-
// todo this drags down performance, investigate some time
186+
187+
// // todo this drags down performance, investigate some time
175188
// // Penalty for being trapped by the king, and even more
176189
// // if the king cannot castle
177190
// if (attackMap.count() <= 3) {
178191
// chess::File f = sq.file();
179192
// chess::File kingFile = pos.kingSq(C).file();
180-
// if ((f > chess::File::FILE_E && kingFile >= chess::File::FILE_E) ||
181-
// (f < chess::File::FILE_D && kingFile <= chess::File::FILE_D)) {
193+
// if ((kingFile < chess::File::FILE_E) == (f < kingFile)) {
182194
// total -= TRAPPED_ROOK_PENALTY;
183-
// if (!pos.castlingRights().has(C)) { total -= TRAPPED_ROOK_PENALTY; }
184195
// }
185196
// }
186197
}
187198
if (PT == Queen) {
188199
Bitboard potentialPinners = pos.pieces(TYPE_ROOK, _C) | pos.pieces(TYPE_BISHOP, _C);
189-
if ((bool) (attackMap & potentialPinners)) { total -= WEAK_QUEEN_PENALTY; }
200+
if ((bool) (attackMap & potentialPinners)) {
201+
total -= WEAK_QUEEN_PENALTY;
202+
}
190203
}
191204
}
192205

@@ -223,12 +236,18 @@ class Evaluator {
223236
const Bitboard doubled =
224237
ours & (C == White ? (sq.rank().bb() << 8) : (sq.rank().bb() >> 8));
225238
// Punish isolated pawns
226-
if (!neighbors) { total -= ISOLATED_PAWN_PENALTY; }
239+
if (!neighbors) {
240+
total -= ISOLATED_PAWN_PENALTY;
241+
}
227242
// Punish doubled and unspported pawns
228-
if (doubled && !supported) { total -= DOUBLED_PAWN_PENALTY; }
243+
if (doubled && !supported) {
244+
total -= DOUBLED_PAWN_PENALTY;
245+
}
229246

230247
// Cache passed pawns so we can evaluate them later
231-
if (!stoppers && !doubled) { cache.passedPawns[C].set(sq.index()); }
248+
if (!stoppers && !doubled) {
249+
cache.passedPawns[C].set(sq.index());
250+
}
232251
}
233252

234253
return total;
@@ -248,6 +267,19 @@ class Evaluator {
248267
return total;
249268
}
250269

270+
/**
271+
* Space advantage
272+
*/
273+
template <EvalColor C> Score _space() {
274+
if ((int) (cache.nonPawnMaterial[White] + cache.nonPawnMaterial[Black]).mg < 6100) {
275+
return S(0, 0);
276+
}
277+
const Bitboard squares =
278+
SPACE_FOR_MINORS[C] & (~cache.attackedBy[_C][Pawn]) & ~(pos.pieces(TYPE_PAWN, C));
279+
const int weight = pos.us(C).count() - pos.countPieces(TYPE_PAWN, C) - 1;
280+
return SPACE_BONUS * (weight * weight * squares.count() / 16);
281+
}
282+
251283
/**
252284
* Estimate game phase from material. This must be called after
253285
* `_check_material`.
@@ -260,6 +292,25 @@ class Evaluator {
260292
return ((m - ENDGAME_LIMIT) * ALL_GAME_PHASES) / (MIDGAME_LIMIT - ENDGAME_LIMIT);
261293
}
262294

295+
/**
296+
* Scales down endgame evaluation with simple heuristics.
297+
*/
298+
int _endgameScaler() {
299+
// Gather basic information
300+
int wp = pos.countPieces(TYPE_PAWN, WHITE), bp = pos.countPieces(TYPE_PAWN, BLACK);
301+
int wb = pos.countPieces(TYPE_BISHOP, WHITE), bb = pos.countPieces(TYPE_BISHOP, BLACK);
302+
303+
Score npm = cache.nonPawnMaterial[White] + cache.nonPawnMaterial[Black];
304+
if (wb == 1 && bb == 1 && ((int) npm.eg <= 720)) {
305+
// Check opposite colors
306+
Square w = Square(pos.pieces(TYPE_BISHOP, WHITE).lsb());
307+
Square b = Square(pos.pieces(TYPE_BISHOP, BLACK).lsb());
308+
if (!Square::same_color(w, b))
309+
return std::min(std::max(std::abs(wp - bp) - 2, 0) * 14, 64);
310+
}
311+
return 64;
312+
}
313+
263314
public:
264315
Value operator()() {
265316
// First, check material and cache the results
@@ -278,12 +329,14 @@ class Evaluator {
278329
total += _piece<White, Rook>() - _piece<Black, Rook>();
279330
total += _piece<White, Queen>() - _piece<Black, Queen>();
280331
total += _pawns<White>() - _pawns<Black>();
332+
// total += _space<White>() - _space<Black>(); // todo this doesn't help
281333
total += _passed<White>() - _passed<Black>();
282334

283335
total += _king<White>() - _king<Black>();
284336

285-
int phase = _phase();
286-
Value v = total.fuse(phase);
337+
int phase = _phase();
338+
total.eg = (int) (total.eg) * _endgameScaler() / 64;
339+
Value v = total.fuse(phase);
287340

288341
if (pos.sideToMove() == BLACK) {
289342
v = ~v; // flip the score so it is always POV

src/evalconstants.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,18 @@ constexpr S MOBILITY_BONUS[6][32] = {
110110
};
111111

112112
constexpr S OUTPOST_BONUS[2][2] = {
113-
{S( 11, 3), S( 18, 6)}, // Knight
114-
{S( 5, 1), S( 8, 3)} // Bishop
113+
{S( 15, 10), S( 60, 32)}, // Knight
114+
{S( 10, 5), S( 15, 2)} // Bishop
115115
};
116116
constexpr S ISOLATED_PAWN_PENALTY = S(3, 8);
117117
constexpr S DOUBLED_PAWN_PENALTY = S(5, 23);
118118
constexpr S MINOR_KING_PROTECTOR = S(3, 4);
119119
constexpr S WEAK_QUEEN_PENALTY = S(27, 5);
120-
constexpr S TRAPPED_ROOK_PENALTY = S(30, 2);
121-
constexpr S OPEN_ROOK_BONUS[2] = {S( 9, 4), S( 22, 10)};
120+
constexpr S TRAPPED_ROOK_PENALTY = S(25, 5);
121+
constexpr S OPEN_ROOK_BONUS[2] = {S( 10, 4), S( 22, 10)};
122122
constexpr S BISHOP_PAWN_PENALTY = S( 2, 10);
123+
constexpr S KING_DISTANCE_PENALTY = S( 3, 4);
124+
constexpr S SPACE_BONUS = S(1, 0);
123125

124126
constexpr S PASSED_PAWN_BONUS[] = {
125127
S( 0, 0),S(148,130),S( 84, 88),S( 31, 36),S( 8, 20),S( 5, 16),S( 0, 8),S( 0, 0)
@@ -152,6 +154,11 @@ constexpr Bitboard OUTPOST_SQUARES[2] = {
152154
0x007E7E7E00000000,
153155
};
154156

157+
constexpr Bitboard SPACE_FOR_MINORS[2] = {
158+
0x3C3C3C3C00000000,
159+
0x000000003C3C3C3C
160+
};
161+
155162
/**
156163
* King rings are 3x3 arears around the king.
157164
*/

0 commit comments

Comments
 (0)