2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
4 Copyright (C) 2008 Marco Costalba
6 Stockfish is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 Stockfish is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
32 //// Constants and variables
35 /// Evaluation functions
37 // Generic "mate lone king" eval:
38 KXKEvaluationFunction EvaluateKXK = KXKEvaluationFunction(WHITE);
39 KXKEvaluationFunction EvaluateKKX = KXKEvaluationFunction(BLACK);
42 KBNKEvaluationFunction EvaluateKBNK = KBNKEvaluationFunction(WHITE);
43 KBNKEvaluationFunction EvaluateKKBN = KBNKEvaluationFunction(BLACK);
46 KPKEvaluationFunction EvaluateKPK = KPKEvaluationFunction(WHITE);
47 KPKEvaluationFunction EvaluateKKP = KPKEvaluationFunction(BLACK);
50 KRKPEvaluationFunction EvaluateKRKP = KRKPEvaluationFunction(WHITE);
51 KRKPEvaluationFunction EvaluateKPKR = KRKPEvaluationFunction(BLACK);
54 KRKBEvaluationFunction EvaluateKRKB = KRKBEvaluationFunction(WHITE);
55 KRKBEvaluationFunction EvaluateKBKR = KRKBEvaluationFunction(BLACK);
58 KRKNEvaluationFunction EvaluateKRKN = KRKNEvaluationFunction(WHITE);
59 KRKNEvaluationFunction EvaluateKNKR = KRKNEvaluationFunction(BLACK);
62 KQKREvaluationFunction EvaluateKQKR = KQKREvaluationFunction(WHITE);
63 KQKREvaluationFunction EvaluateKRKQ = KQKREvaluationFunction(BLACK);
66 KBBKNEvaluationFunction EvaluateKBBKN = KBBKNEvaluationFunction(WHITE);
67 KBBKNEvaluationFunction EvaluateKNKBB = KBBKNEvaluationFunction(BLACK);
69 // K and two minors vs K and one or two minors:
70 KmmKmEvaluationFunction EvaluateKmmKm = KmmKmEvaluationFunction(WHITE);
76 KBPKScalingFunction ScaleKBPK = KBPKScalingFunction(WHITE);
77 KBPKScalingFunction ScaleKKBP = KBPKScalingFunction(BLACK);
80 KQKRPScalingFunction ScaleKQKRP = KQKRPScalingFunction(WHITE);
81 KQKRPScalingFunction ScaleKRPKQ = KQKRPScalingFunction(BLACK);
84 KRPKRScalingFunction ScaleKRPKR = KRPKRScalingFunction(WHITE);
85 KRPKRScalingFunction ScaleKRKRP = KRPKRScalingFunction(BLACK);
88 KRPPKRPScalingFunction ScaleKRPPKRP = KRPPKRPScalingFunction(WHITE);
89 KRPPKRPScalingFunction ScaleKRPKRPP = KRPPKRPScalingFunction(BLACK);
91 // King and pawns vs king:
92 KPsKScalingFunction ScaleKPsK = KPsKScalingFunction(WHITE);
93 KPsKScalingFunction ScaleKKPs = KPsKScalingFunction(BLACK);
96 KBPKBScalingFunction ScaleKBPKB = KBPKBScalingFunction(WHITE);
97 KBPKBScalingFunction ScaleKBKBP = KBPKBScalingFunction(BLACK);
100 KBPKNScalingFunction ScaleKBPKN = KBPKNScalingFunction(WHITE);
101 KBPKNScalingFunction ScaleKNKBP = KBPKNScalingFunction(BLACK);
104 KNPKScalingFunction ScaleKNPK = KNPKScalingFunction(WHITE);
105 KNPKScalingFunction ScaleKKNP = KNPKScalingFunction(BLACK);
108 KPKPScalingFunction ScaleKPKPw = KPKPScalingFunction(WHITE);
109 KPKPScalingFunction ScaleKPKPb = KPKPScalingFunction(BLACK);
113 //// Local definitions
118 // Table used to drive the defending king towards the edge of the board
119 // in KX vs K and KQ vs KR endgames:
120 const uint8_t MateTable[64] = {
121 100, 90, 80, 70, 70, 80, 90, 100,
122 90, 70, 60, 50, 50, 60, 70, 90,
123 80, 60, 40, 30, 30, 40, 60, 80,
124 70, 50, 30, 20, 20, 30, 50, 70,
125 70, 50, 30, 20, 20, 30, 50, 70,
126 80, 60, 40, 30, 30, 40, 60, 80,
127 90, 70, 60, 50, 50, 60, 70, 90,
128 100, 90, 80, 70, 70, 80, 90, 100,
131 // Table used to drive the defending king towards a corner square of the
132 // right color in KBN vs K endgames:
133 const uint8_t KBNKMateTable[64] = {
134 200, 190, 180, 170, 160, 150, 140, 130,
135 190, 180, 170, 160, 150, 140, 130, 140,
136 180, 170, 155, 140, 140, 125, 140, 150,
137 170, 160, 140, 120, 110, 140, 150, 160,
138 160, 150, 140, 110, 120, 140, 160, 170,
139 150, 140, 125, 140, 140, 155, 170, 180,
140 140, 130, 140, 150, 160, 170, 180, 190,
141 130, 140, 150, 160, 170, 180, 190, 200
144 // The attacking side is given a descending bonus based on distance between
145 // the two kings in basic endgames:
146 const int DistanceBonus[8] = {0, 0, 100, 80, 60, 40, 20, 10};
148 // Bitbase for KP vs K:
149 uint8_t KPKBitbase[24576];
151 // Penalty for big distance between king and knight for the defending king
152 // and knight in KR vs KN endgames:
153 const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
155 // Various inline functions for accessing the above arrays:
157 inline Value mate_table(Square s) {
158 return Value(MateTable[s]);
161 inline Value kbnk_mate_table(Square s) {
162 return Value(KBNKMateTable[s]);
165 inline Value distance_bonus(int d) {
166 return Value(DistanceBonus[d]);
169 inline Value krkn_king_knight_distance_penalty(int d) {
170 return Value(KRKNKingKnightDistancePenalty[d]);
173 // Function for probing the KP vs K bitbase:
174 int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm);
185 EndgameEvaluationFunction::EndgameEvaluationFunction(Color c) {
187 weakerSide = opposite_color(strongerSide);
190 KXKEvaluationFunction::KXKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
191 KBNKEvaluationFunction::KBNKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
192 KPKEvaluationFunction::KPKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
193 KRKPEvaluationFunction::KRKPEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
194 KRKBEvaluationFunction::KRKBEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
195 KRKNEvaluationFunction::KRKNEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
196 KQKREvaluationFunction::KQKREvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
197 KBBKNEvaluationFunction::KBBKNEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
198 KmmKmEvaluationFunction::KmmKmEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
201 ScalingFunction::ScalingFunction(Color c) {
203 weakerSide = opposite_color(c);
206 KBPKScalingFunction::KBPKScalingFunction(Color c) : ScalingFunction(c) { }
207 KQKRPScalingFunction::KQKRPScalingFunction(Color c) : ScalingFunction(c) { }
208 KRPKRScalingFunction::KRPKRScalingFunction(Color c) : ScalingFunction(c) { }
209 KRPPKRPScalingFunction::KRPPKRPScalingFunction(Color c) : ScalingFunction(c) { }
210 KPsKScalingFunction::KPsKScalingFunction(Color c) : ScalingFunction(c) { }
211 KBPKBScalingFunction::KBPKBScalingFunction(Color c) : ScalingFunction(c) { }
212 KBPKNScalingFunction::KBPKNScalingFunction(Color c) : ScalingFunction(c) { }
213 KNPKScalingFunction::KNPKScalingFunction(Color c) : ScalingFunction(c) { }
214 KPKPScalingFunction::KPKPScalingFunction(Color c) : ScalingFunction(c) { }
217 /// Mate with KX vs K. This function is used to evaluate positions with
218 /// King and plenty of material vs a lone king. It simply gives the
219 /// attacking side a bonus for driving the defending king towards the edge
220 /// of the board, and for keeping the distance between the two kings small.
222 Value KXKEvaluationFunction::apply(const Position &pos) {
224 assert(pos.non_pawn_material(weakerSide) == Value(0));
225 assert(pos.piece_count(weakerSide, PAWN) == Value(0));
227 Square winnerKSq = pos.king_square(strongerSide);
228 Square loserKSq = pos.king_square(weakerSide);
231 pos.non_pawn_material(strongerSide) +
232 pos.piece_count(strongerSide, PAWN) * PawnValueEndgame +
233 mate_table(loserKSq) +
234 distance_bonus(square_distance(winnerKSq, loserKSq));
236 if(pos.piece_count(strongerSide, QUEEN) > 0 || pos.piece_count(strongerSide, ROOK) > 0 ||
237 pos.piece_count(strongerSide, BISHOP) > 1)
238 // TODO: check for two equal-colored bishops!
239 result += VALUE_KNOWN_WIN;
241 return (strongerSide == pos.side_to_move())? result : -result;
245 /// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
246 /// defending king towards a corner square of the right color.
248 Value KBNKEvaluationFunction::apply(const Position &pos) {
250 assert(pos.non_pawn_material(weakerSide) == Value(0));
251 assert(pos.piece_count(weakerSide, PAWN) == Value(0));
252 assert(pos.non_pawn_material(strongerSide) ==
253 KnightValueMidgame + BishopValueMidgame);
254 assert(pos.piece_count(strongerSide, BISHOP) == 1);
255 assert(pos.piece_count(strongerSide, KNIGHT) == 1);
256 assert(pos.piece_count(strongerSide, PAWN) == 0);
258 Square winnerKSq = pos.king_square(strongerSide);
259 Square loserKSq = pos.king_square(weakerSide);
260 Square bishopSquare = pos.piece_list(strongerSide, BISHOP, 0);
262 if(square_color(bishopSquare) == BLACK) {
263 winnerKSq = flop_square(winnerKSq);
264 loserKSq = flop_square(loserKSq);
268 VALUE_KNOWN_WIN + distance_bonus(square_distance(winnerKSq, loserKSq)) +
269 kbnk_mate_table(loserKSq);
271 return (strongerSide == pos.side_to_move())? result : -result;
275 /// KP vs K. This endgame is evaluated with the help of a bitbase.
277 Value KPKEvaluationFunction::apply(const Position &pos) {
279 assert(pos.non_pawn_material(strongerSide) == Value(0));
280 assert(pos.non_pawn_material(weakerSide) == Value(0));
281 assert(pos.piece_count(strongerSide, PAWN) == 1);
282 assert(pos.piece_count(weakerSide, PAWN) == 0);
284 Square wksq, bksq, wpsq;
287 if(strongerSide == WHITE) {
288 wksq = pos.king_square(WHITE);
289 bksq = pos.king_square(BLACK);
290 wpsq = pos.piece_list(WHITE, PAWN, 0);
291 stm = pos.side_to_move();
294 wksq = flip_square(pos.king_square(BLACK));
295 bksq = flip_square(pos.king_square(WHITE));
296 wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
297 stm = opposite_color(pos.side_to_move());
300 if(square_file(wpsq) >= FILE_E) {
301 wksq = flop_square(wksq);
302 bksq = flop_square(bksq);
303 wpsq = flop_square(wpsq);
306 if(probe_kpk(wksq, wpsq, bksq, stm)) {
308 VALUE_KNOWN_WIN + PawnValueEndgame + Value(square_rank(wpsq));
309 return (strongerSide == pos.side_to_move())? result : -result;
316 /// KR vs KP. This is a somewhat tricky endgame to evaluate precisely without
317 /// a bitbase. The function below returns drawish scores when the pawn is
318 /// far advanced with support of the king, while the attacking king is far
321 Value KRKPEvaluationFunction::apply(const Position &pos) {
323 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
324 assert(pos.piece_count(strongerSide, PAWN) == 0);
325 assert(pos.non_pawn_material(weakerSide) == 0);
326 assert(pos.piece_count(weakerSide, PAWN) == 1);
328 Square wksq, wrsq, bksq, bpsq;
329 int tempo = (pos.side_to_move() == strongerSide);
331 wksq = pos.king_square(strongerSide);
332 wrsq = pos.piece_list(strongerSide, ROOK, 0);
333 bksq = pos.king_square(weakerSide);
334 bpsq = pos.piece_list(weakerSide, PAWN, 0);
336 if(strongerSide == BLACK) {
337 wksq = flip_square(wksq);
338 wrsq = flip_square(wrsq);
339 bksq = flip_square(bksq);
340 bpsq = flip_square(bpsq);
343 Square queeningSq = make_square(square_file(bpsq), RANK_1);
346 // If the stronger side's king is in front of the pawn, it's a win:
347 if(wksq < bpsq && square_file(wksq) == square_file(bpsq))
348 result = RookValueEndgame - Value(square_distance(wksq, bpsq));
350 // If the weaker side's king is too far from the pawn and the rook,
352 else if(square_distance(bksq, bpsq) - (tempo^1) >= 3 &&
353 square_distance(bksq, wrsq) >= 3)
354 result = RookValueEndgame - Value(square_distance(wksq, bpsq));
356 // If the pawn is far advanced and supported by the defending king,
357 // the position is drawish:
358 else if(square_rank(bksq) <= RANK_3 && square_distance(bksq, bpsq) == 1 &&
359 square_rank(wksq) >= RANK_4 &&
360 square_distance(wksq, bpsq) - tempo > 2)
361 result = Value(80 - square_distance(wksq, bpsq) * 8);
365 - Value(square_distance(wksq, bpsq + DELTA_S) * 8)
366 + Value(square_distance(bksq, bpsq + DELTA_S) * 8)
367 + Value(square_distance(bpsq, queeningSq) * 8);
369 return (strongerSide == pos.side_to_move())? result : -result;
373 /// KR vs KB. This is very simple, and always returns drawish scores. The
374 /// score is slightly bigger when the defending king is close to the edge.
376 Value KRKBEvaluationFunction::apply(const Position &pos) {
378 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
379 assert(pos.piece_count(strongerSide, PAWN) == 0);
380 assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
381 assert(pos.piece_count(weakerSide, PAWN) == 0);
382 assert(pos.piece_count(weakerSide, BISHOP) == 1);
384 Value result = mate_table(pos.king_square(weakerSide));
385 return (pos.side_to_move() == strongerSide)? result : -result;
389 /// KR vs KN. The attacking side has slightly better winning chances than
390 /// in KR vs KB, particularly if the king and the knight are far apart.
392 Value KRKNEvaluationFunction::apply(const Position &pos) {
394 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
395 assert(pos.piece_count(strongerSide, PAWN) == 0);
396 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
397 assert(pos.piece_count(weakerSide, PAWN) == 0);
398 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
400 Square defendingKSq = pos.king_square(weakerSide);
401 Square nSq = pos.piece_list(weakerSide, KNIGHT, 0);
403 Value result = Value(10) + mate_table(defendingKSq) +
404 krkn_king_knight_distance_penalty(square_distance(defendingKSq, nSq));
406 return (strongerSide == pos.side_to_move())? result : -result;
410 /// KQ vs KR. This is almost identical to KX vs K: We give the attacking
411 /// king a bonus for having the kings close together, and for forcing the
412 /// defending king towards the edge. If we also take care to avoid null move
413 /// for the defending side in the search, this is usually sufficient to be
414 /// able to win KQ vs KR.
416 Value KQKREvaluationFunction::apply(const Position &pos) {
417 assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
418 assert(pos.piece_count(strongerSide, PAWN) == 0);
419 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
420 assert(pos.piece_count(weakerSide, PAWN) == 0);
422 Square winnerKSq = pos.king_square(strongerSide);
423 Square loserKSq = pos.king_square(weakerSide);
425 Value result = QueenValueEndgame - RookValueEndgame +
426 mate_table(loserKSq) + distance_bonus(square_distance(winnerKSq, loserKSq));
428 return (strongerSide == pos.side_to_move())? result : -result;
432 Value KBBKNEvaluationFunction::apply(const Position &pos) {
433 assert(pos.piece_count(strongerSide, BISHOP) == 2);
434 assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
435 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
436 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
437 assert(pos.pawns() == EmptyBoardBB);
439 Value result = BishopValueEndgame;
440 Square wksq = pos.king_square(strongerSide);
441 Square bksq = pos.king_square(weakerSide);
442 Square nsq = pos.piece_list(weakerSide, KNIGHT, 0);
444 // Bonus for attacking king close to defending king
445 result += distance_bonus(square_distance(wksq, bksq));
447 // Bonus for driving the defending king and knight apart
448 result += Value(square_distance(bksq, nsq) * 32);
450 // Bonus for restricting the knight's mobility
451 result += Value((8 - count_1s_max_15(pos.piece_attacks<KNIGHT>(nsq))) * 8);
453 return (strongerSide == pos.side_to_move())? result : -result;
457 Value KmmKmEvaluationFunction::apply(const Position &pos) {
462 /// KBPKScalingFunction scales endgames where the stronger side has king,
463 /// bishop and one or more pawns. It checks for draws with rook pawns and a
464 /// bishop of the wrong color. If such a draw is detected, ScaleFactor(0) is
465 /// returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
468 ScaleFactor KBPKScalingFunction::apply(const Position &pos) {
469 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
470 assert(pos.piece_count(strongerSide, BISHOP) == 1);
471 assert(pos.piece_count(strongerSide, PAWN) >= 1);
473 // No assertions about the material of weakerSide, because we want draws to
474 // be detected even when the weaker side has some pawns.
476 Bitboard pawns = pos.pawns(strongerSide);
477 File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
479 if((pawnFile == FILE_A || pawnFile == FILE_H) &&
480 (pawns & ~file_bb(pawnFile)) == EmptyBoardBB) {
481 // All pawns are on a single rook file.
483 Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
485 relative_square(strongerSide, make_square(pawnFile, RANK_8));
486 Square kingSq = pos.king_square(weakerSide);
488 if(square_color(queeningSq) != square_color(bishopSq) &&
489 file_distance(square_file(kingSq), pawnFile) <= 1) {
490 // The bishop has the wrong color, and the defending king is on the
491 // file of the pawn(s) or the neighboring file. Find the rank of the
495 if(strongerSide == WHITE) {
496 for(rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--);
497 assert(rank >= RANK_2 && rank <= RANK_7);
500 for(rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++);
501 rank = Rank(rank^7); // HACK
502 assert(rank >= RANK_2 && rank <= RANK_7);
504 // If the defending king has distance 1 to the promotion square or
505 // is placed somewhere in front of the pawn, it's a draw.
506 if(square_distance(kingSq, queeningSq) <= 1 ||
507 relative_rank(strongerSide, kingSq) >= rank)
508 return ScaleFactor(0);
511 return SCALE_FACTOR_NONE;
515 /// KQKRPScalingFunction scales endgames where the stronger side has only
516 /// king and queen, while the weaker side has at least a rook and a pawn.
517 /// It tests for fortress draws with a rook on the third rank defended by
520 ScaleFactor KQKRPScalingFunction::apply(const Position &pos) {
521 assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
522 assert(pos.piece_count(strongerSide, QUEEN) == 1);
523 assert(pos.piece_count(strongerSide, PAWN) == 0);
524 assert(pos.piece_count(weakerSide, ROOK) == 1);
525 assert(pos.piece_count(weakerSide, PAWN) >= 1);
527 Square kingSq = pos.king_square(weakerSide);
528 if(relative_rank(weakerSide, kingSq) <= RANK_2 &&
529 relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4 &&
530 (pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) &&
531 (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) &&
532 (pos.piece_attacks<KING>(kingSq) & pos.pawns(weakerSide))) {
533 Square rsq = pos.piece_list(weakerSide, ROOK, 0);
534 if(pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide))
535 return ScaleFactor(0);
537 return SCALE_FACTOR_NONE;
541 /// KRPKRScalingFunction scales KRP vs KR endgames. This function knows a
542 /// handful of the most important classes of drawn positions, but is far
543 /// from perfect. It would probably be a good idea to add more knowledge
546 /// It would also be nice to rewrite the actual code for this function,
547 /// which is mostly copied from Glaurung 1.x, and not very pretty.
549 ScaleFactor KRPKRScalingFunction::apply(const Position &pos) {
550 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
551 assert(pos.piece_count(strongerSide, PAWN) == 1);
552 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
553 assert(pos.piece_count(weakerSide, PAWN) == 0);
555 Square wksq = pos.king_square(strongerSide);
556 Square wrsq = pos.piece_list(strongerSide, ROOK, 0);
557 Square wpsq = pos.piece_list(strongerSide, PAWN, 0);
558 Square bksq = pos.king_square(weakerSide);
559 Square brsq = pos.piece_list(weakerSide, ROOK, 0);
561 // Orient the board in such a way that the stronger side is white, and the
562 // pawn is on the left half of the board:
563 if(strongerSide == BLACK) {
564 wksq = flip_square(wksq);
565 wrsq = flip_square(wrsq);
566 wpsq = flip_square(wpsq);
567 bksq = flip_square(bksq);
568 brsq = flip_square(brsq);
570 if(square_file(wpsq) > FILE_D) {
571 wksq = flop_square(wksq);
572 wrsq = flop_square(wrsq);
573 wpsq = flop_square(wpsq);
574 bksq = flop_square(bksq);
575 brsq = flop_square(brsq);
578 File f = square_file(wpsq);
579 Rank r = square_rank(wpsq);
580 Square queeningSq = make_square(f, RANK_8);
581 int tempo = (pos.side_to_move() == strongerSide);
583 // If the pawn is not too far advanced and the defending king defends the
584 // queening square, use the third-rank defence:
585 if(r <= RANK_5 && square_distance(bksq, queeningSq) <= 1 && wksq <= SQ_H5 &&
586 (square_rank(brsq) == RANK_6 || (r <= RANK_3 &&
587 square_rank(wrsq) != RANK_6)))
588 return ScaleFactor(0);
590 // The defending side saves a draw by checking from behind in case the pawn
591 // has advanced to the 6th rank with the king behind.
592 if(r == RANK_6 && square_distance(bksq, queeningSq) <= 1 &&
593 square_rank(wksq) + tempo <= RANK_6 &&
594 (square_rank(brsq) == RANK_1 ||
595 (!tempo && abs(square_file(brsq) - f) >= 3)))
596 return ScaleFactor(0);
598 if(r >= RANK_6 && bksq == queeningSq && square_rank(brsq) == RANK_1 &&
599 (!tempo || square_distance(wksq, wpsq) >= 2))
600 return ScaleFactor(0);
602 // White pawn on a7 and rook on a8 is a draw if black's king is on g7 or h7
603 // and the black rook is behind the pawn.
604 if(wpsq == SQ_A7 && wrsq == SQ_A8 && (bksq == SQ_H7 || bksq == SQ_G7) &&
605 square_file(brsq) == FILE_A &&
606 (square_rank(brsq) <= RANK_3 || square_file(wksq) >= FILE_D ||
607 square_rank(wksq) <= RANK_5))
608 return ScaleFactor(0);
610 // If the defending king blocks the pawn and the attacking king is too far
611 // away, it's a draw.
612 if(r <= RANK_5 && bksq == wpsq + DELTA_N &&
613 square_distance(wksq, wpsq) - tempo >= 2 &&
614 square_distance(wksq, brsq) - tempo >= 2)
615 return ScaleFactor(0);
617 // Pawn on the 7th rank supported by the rook from behind usually wins if the
618 // attacking king is closer to the queening square than the defending king,
619 // and the defending king cannot gain tempi by threatening the attacking
621 if(r == RANK_7 && f != FILE_A && square_file(wrsq) == f
622 && wrsq != queeningSq
623 && (square_distance(wksq, queeningSq) <
624 square_distance(bksq, queeningSq) - 2 + tempo)
625 && (square_distance(wksq, queeningSq) <
626 square_distance(bksq, wrsq) + tempo))
627 return ScaleFactor(SCALE_FACTOR_MAX
628 - 2 * square_distance(wksq, queeningSq));
630 // Similar to the above, but with the pawn further back:
631 if(f != FILE_A && square_file(wrsq) == f && wrsq < wpsq
632 && (square_distance(wksq, queeningSq) <
633 square_distance(bksq, queeningSq) - 2 + tempo)
634 && (square_distance(wksq, wpsq + DELTA_N) <
635 square_distance(bksq, wpsq + DELTA_N) - 2 + tempo)
636 && (square_distance(bksq, wrsq) + tempo >= 3
637 || (square_distance(wksq, queeningSq) <
638 square_distance(bksq, wrsq) + tempo
639 && (square_distance(wksq, wpsq + DELTA_N) <
640 square_distance(bksq, wrsq) + tempo))))
642 ScaleFactor(SCALE_FACTOR_MAX
643 - (8 * square_distance(wpsq, queeningSq) +
644 2 * square_distance(wksq, queeningSq)));
646 // If the pawn is not far advanced, and the defending king is somewhere in
647 // the pawn's path, it's probably a draw:
648 if(r <= RANK_4 && bksq > wpsq) {
649 if(square_file(bksq) == square_file(wpsq))
650 return ScaleFactor(10);
651 if(abs(square_file(bksq) - square_file(wpsq)) == 1
652 && square_distance(wksq, bksq) > 2)
653 return ScaleFactor(24 - 2 * square_distance(wksq, bksq));
656 return SCALE_FACTOR_NONE;
660 /// KRPPKRPScalingFunction scales KRPP vs KRP endgames. There is only a
661 /// single pattern: If the stronger side has no pawns and the defending king
662 /// is actively placed, the position is drawish.
664 ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) {
665 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
666 assert(pos.piece_count(strongerSide, PAWN) == 2);
667 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
668 assert(pos.piece_count(weakerSide, PAWN) == 1);
670 Square wpsq1 = pos.piece_list(strongerSide, PAWN, 0);
671 Square wpsq2 = pos.piece_list(strongerSide, PAWN, 1);
672 Square bksq = pos.king_square(weakerSide);
674 // Does the stronger side have a passed pawn?
675 if(pos.pawn_is_passed(strongerSide, wpsq1) ||
676 pos.pawn_is_passed(strongerSide, wpsq2))
677 return SCALE_FACTOR_NONE;
679 Rank r = Max(relative_rank(strongerSide, wpsq1), relative_rank(strongerSide, wpsq2));
681 if(file_distance(bksq, wpsq1) <= 1 && file_distance(bksq, wpsq2) <= 1
682 && relative_rank(strongerSide, bksq) > r) {
685 case RANK_2: return ScaleFactor(10);
686 case RANK_3: return ScaleFactor(10);
687 case RANK_4: return ScaleFactor(15);
688 case RANK_5: return ScaleFactor(20);
689 case RANK_6: return ScaleFactor(40);
690 default: assert(false);
694 return SCALE_FACTOR_NONE;
698 /// KPsKScalingFunction scales endgames with king and two or more pawns
699 /// against king. There is just a single rule here: If all pawns are on
700 /// the same rook file and are blocked by the defending king, it's a draw.
702 ScaleFactor KPsKScalingFunction::apply(const Position &pos) {
703 assert(pos.non_pawn_material(strongerSide) == Value(0));
704 assert(pos.piece_count(strongerSide, PAWN) >= 2);
705 assert(pos.non_pawn_material(weakerSide) == Value(0));
706 assert(pos.piece_count(weakerSide, PAWN) == 0);
708 Bitboard pawns = pos.pawns(strongerSide);
710 // Are all pawns on the 'a' file?
711 if((pawns & ~FileABB) == EmptyBoardBB) {
712 // Does the defending king block the pawns?
713 Square ksq = pos.king_square(weakerSide);
714 if(square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1)
715 return ScaleFactor(0);
716 else if(square_file(ksq) == FILE_A &&
717 (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB)
718 return ScaleFactor(0);
720 return SCALE_FACTOR_NONE;
722 // Are all pawns on the 'h' file?
723 else if((pawns & ~FileHBB) == EmptyBoardBB) {
724 // Does the defending king block the pawns?
725 Square ksq = pos.king_square(weakerSide);
726 if(square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1)
727 return ScaleFactor(0);
728 else if(square_file(ksq) == FILE_H &&
729 (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB)
730 return ScaleFactor(0);
732 return SCALE_FACTOR_NONE;
735 return SCALE_FACTOR_NONE;
739 /// KBPKBScalingFunction scales KBP vs KB endgames. There are two rules:
740 /// If the defending king is somewhere along the path of the pawn, and the
741 /// square of the king is not of the same color as the stronger side's bishop,
742 /// it's a draw. If the two bishops have opposite color, it's almost always
745 ScaleFactor KBPKBScalingFunction::apply(const Position &pos) {
746 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
747 assert(pos.piece_count(strongerSide, BISHOP) == 1);
748 assert(pos.piece_count(strongerSide, PAWN) == 1);
749 assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
750 assert(pos.piece_count(weakerSide, BISHOP) == 1);
751 assert(pos.piece_count(weakerSide, PAWN) == 0);
753 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
754 Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
755 Square weakerBishopSq = pos.piece_list(weakerSide, BISHOP, 0);
756 Square weakerKingSq = pos.king_square(weakerSide);
758 // Case 1: Defending king blocks the pawn, and cannot be driven away.
759 if(square_file(weakerKingSq) == square_file(pawnSq)
760 && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
761 && (square_color(weakerKingSq) != square_color(strongerBishopSq)
762 || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
763 return ScaleFactor(0);
765 // Case 2: Opposite colored bishops.
766 if(square_color(strongerBishopSq) != square_color(weakerBishopSq)) {
768 // We assume that the position is drawn in the following three situations:
770 // a. The pawn is on rank 5 or further back.
771 // b. The defending king is somewhere in the pawn's path.
772 // c. The defending bishop attacks some square along the pawn's path,
773 // and is at least three squares away from the pawn.
775 // These rules are probably not perfect, but in practice they work
778 if(relative_rank(strongerSide, pawnSq) <= RANK_5)
779 return ScaleFactor(0);
782 ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S);
783 if(ray & pos.kings(weakerSide))
784 return ScaleFactor(0);
785 if((pos.piece_attacks<BISHOP>(weakerBishopSq) & ray)
786 && square_distance(weakerBishopSq, pawnSq) >= 3)
787 return ScaleFactor(0);
790 return SCALE_FACTOR_NONE;
794 /// KBPKNScalingFunction scales KBP vs KN endgames. There is a single rule:
795 /// If the defending king is somewhere along the path of the pawn, and the
796 /// square of the king is not of the same color as the stronger side's bishop,
799 ScaleFactor KBPKNScalingFunction::apply(const Position &pos) {
800 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
801 assert(pos.piece_count(strongerSide, BISHOP) == 1);
802 assert(pos.piece_count(strongerSide, PAWN) == 1);
803 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
804 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
805 assert(pos.piece_count(weakerSide, PAWN) == 0);
807 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
808 Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
809 Square weakerKingSq = pos.king_square(weakerSide);
811 if(square_file(weakerKingSq) == square_file(pawnSq)
812 && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
813 && (square_color(weakerKingSq) != square_color(strongerBishopSq)
814 || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
815 return ScaleFactor(0);
817 return SCALE_FACTOR_NONE;
821 /// KNPKScalingFunction scales KNP vs K endgames. There is a single rule:
822 /// If the pawn is a rook pawn on the 7th rank and the defending king prevents
823 /// the pawn from advancing, the position is drawn.
825 ScaleFactor KNPKScalingFunction::apply(const Position &pos) {
826 assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame);
827 assert(pos.piece_count(strongerSide, KNIGHT) == 1);
828 assert(pos.piece_count(strongerSide, PAWN) == 1);
829 assert(pos.non_pawn_material(weakerSide) == Value(0));
830 assert(pos.piece_count(weakerSide, PAWN) == 0);
832 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
833 Square weakerKingSq = pos.king_square(weakerSide);
835 if(pawnSq == relative_square(strongerSide, SQ_A7) &&
836 square_distance(weakerKingSq, relative_square(strongerSide, SQ_A8)) <= 1)
837 return ScaleFactor(0);
839 if(pawnSq == relative_square(strongerSide, SQ_H7) &&
840 square_distance(weakerKingSq, relative_square(strongerSide, SQ_H8)) <= 1)
841 return ScaleFactor(0);
843 return SCALE_FACTOR_NONE;
847 /// KPKPScalingFunction scales KP vs KP endgames. This is done by removing
848 /// the weakest side's pawn and probing the KP vs K bitbase: If the weakest
849 /// side has a draw without the pawn, she probably has at least a draw with
850 /// the pawn as well. The exception is when the stronger side's pawn is far
851 /// advanced and not on a rook file; in this case it is often possible to win
852 /// (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1).
854 ScaleFactor KPKPScalingFunction::apply(const Position &pos) {
855 assert(pos.non_pawn_material(strongerSide) == Value(0));
856 assert(pos.non_pawn_material(weakerSide) == Value(0));
857 assert(pos.piece_count(WHITE, PAWN) == 1);
858 assert(pos.piece_count(BLACK, PAWN) == 1);
860 Square wksq, bksq, wpsq;
863 if(strongerSide == WHITE) {
864 wksq = pos.king_square(WHITE);
865 bksq = pos.king_square(BLACK);
866 wpsq = pos.piece_list(WHITE, PAWN, 0);
867 stm = pos.side_to_move();
870 wksq = flip_square(pos.king_square(BLACK));
871 bksq = flip_square(pos.king_square(WHITE));
872 wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
873 stm = opposite_color(pos.side_to_move());
876 if(square_file(wpsq) >= FILE_E) {
877 wksq = flop_square(wksq);
878 bksq = flop_square(bksq);
879 wpsq = flop_square(wpsq);
882 // If the pawn has advanced to the fifth rank or further, and is not a
883 // rook pawn, it's too dangerous to assume that it's at least a draw.
884 if(square_rank(wpsq) >= RANK_5 && square_file(wpsq) != FILE_A)
885 return SCALE_FACTOR_NONE;
887 // Probe the KPK bitbase with the weakest side's pawn removed. If it's a
888 // draw, it's probably at least a draw even with the pawn.
889 if(probe_kpk(wksq, wpsq, bksq, stm))
890 return SCALE_FACTOR_NONE;
892 return ScaleFactor(0);
896 /// init_bitbases() is called during program initialization, and simply loads
897 /// bitbases from disk into memory. At the moment, there is only the bitbase
898 /// for KP vs K, but we may decide to add other bitbases later.
900 void init_bitbases() {
901 generate_kpk_bitbase(KPKBitbase);
907 // Probe the KP vs K bitbase:
909 int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm) {
910 int wp = int(square_file(wpsq)) + (int(square_rank(wpsq)) - 1) * 4;
911 int index = int(stm) + 2*int(bksq) + 128*int(wksq) + 8192*wp;
913 assert(index >= 0 && index < 24576*8);
914 return KPKBitbase[index/8] & (1 << (index&7));