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);
69 KBPKScalingFunction ScaleKBPK = KBPKScalingFunction(WHITE);
70 KBPKScalingFunction ScaleKKBP = KBPKScalingFunction(BLACK);
73 KQKRPScalingFunction ScaleKQKRP = KQKRPScalingFunction(WHITE);
74 KQKRPScalingFunction ScaleKRPKQ = KQKRPScalingFunction(BLACK);
77 KRPKRScalingFunction ScaleKRPKR = KRPKRScalingFunction(WHITE);
78 KRPKRScalingFunction ScaleKRKRP = KRPKRScalingFunction(BLACK);
81 KRPPKRPScalingFunction ScaleKRPPKRP = KRPPKRPScalingFunction(WHITE);
82 KRPPKRPScalingFunction ScaleKRPKRPP = KRPPKRPScalingFunction(BLACK);
84 // King and pawns vs king:
85 KPsKScalingFunction ScaleKPsK = KPsKScalingFunction(WHITE);
86 KPsKScalingFunction ScaleKKPs = KPsKScalingFunction(BLACK);
89 KBPKBScalingFunction ScaleKBPKB = KBPKBScalingFunction(WHITE);
90 KBPKBScalingFunction ScaleKBKBP = KBPKBScalingFunction(BLACK);
93 KBPKNScalingFunction ScaleKBPKN = KBPKNScalingFunction(WHITE);
94 KBPKNScalingFunction ScaleKNKBP = KBPKNScalingFunction(BLACK);
97 KNPKScalingFunction ScaleKNPK = KNPKScalingFunction(WHITE);
98 KNPKScalingFunction ScaleKKNP = KNPKScalingFunction(BLACK);
101 KPKPScalingFunction ScaleKPKPw = KPKPScalingFunction(WHITE);
102 KPKPScalingFunction ScaleKPKPb = KPKPScalingFunction(BLACK);
106 //// Local definitions
111 // Table used to drive the defending king towards the edge of the board
112 // in KX vs K and KQ vs KR endgames:
113 const uint8_t MateTable[64] = {
114 100, 90, 80, 70, 70, 80, 90, 100,
115 90, 70, 60, 50, 50, 60, 70, 90,
116 80, 60, 40, 30, 30, 40, 60, 80,
117 70, 50, 30, 20, 20, 30, 50, 70,
118 70, 50, 30, 20, 20, 30, 50, 70,
119 80, 60, 40, 30, 30, 40, 60, 80,
120 90, 70, 60, 50, 50, 60, 70, 90,
121 100, 90, 80, 70, 70, 80, 90, 100,
124 // Table used to drive the defending king towards a corner square of the
125 // right color in KBN vs K endgames:
126 const uint8_t KBNKMateTable[64] = {
127 200, 190, 180, 170, 160, 150, 140, 130,
128 190, 180, 170, 160, 150, 140, 130, 140,
129 180, 170, 155, 140, 140, 125, 140, 150,
130 170, 160, 140, 120, 110, 140, 150, 160,
131 160, 150, 140, 110, 120, 140, 160, 170,
132 150, 140, 125, 140, 140, 155, 170, 180,
133 140, 130, 140, 150, 160, 170, 180, 190,
134 130, 140, 150, 160, 170, 180, 190, 200
137 // The attacking side is given a descending bonus based on distance between
138 // the two kings in basic endgames:
139 const int DistanceBonus[8] = {0, 0, 100, 80, 60, 40, 20, 10};
141 // Bitbase for KP vs K:
142 uint8_t KPKBitbase[24576];
144 // Penalty for big distance between king and knight for the defending king
145 // and knight in KR vs KN endgames:
146 const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
148 // Various inline functions for accessing the above arrays:
150 inline Value mate_table(Square s) {
151 return Value(MateTable[s]);
154 inline Value kbnk_mate_table(Square s) {
155 return Value(KBNKMateTable[s]);
158 inline Value distance_bonus(int d) {
159 return Value(DistanceBonus[d]);
162 inline Value krkn_king_knight_distance_penalty(int d) {
163 return Value(KRKNKingKnightDistancePenalty[d]);
166 // Function for probing the KP vs K bitbase:
167 int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm);
178 EndgameEvaluationFunction::EndgameEvaluationFunction(Color c) {
180 weakerSide = opposite_color(strongerSide);
183 KXKEvaluationFunction::KXKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
184 KBNKEvaluationFunction::KBNKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
185 KPKEvaluationFunction::KPKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
186 KRKPEvaluationFunction::KRKPEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
187 KRKBEvaluationFunction::KRKBEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
188 KRKNEvaluationFunction::KRKNEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
189 KQKREvaluationFunction::KQKREvaluationFunction(Color c) : EndgameEvaluationFunction(c) { }
192 ScalingFunction::ScalingFunction(Color c) {
194 weakerSide = opposite_color(c);
197 KBPKScalingFunction::KBPKScalingFunction(Color c) : ScalingFunction(c) { }
198 KQKRPScalingFunction::KQKRPScalingFunction(Color c) : ScalingFunction(c) { }
199 KRPKRScalingFunction::KRPKRScalingFunction(Color c) : ScalingFunction(c) { }
200 KRPPKRPScalingFunction::KRPPKRPScalingFunction(Color c) : ScalingFunction(c) { }
201 KPsKScalingFunction::KPsKScalingFunction(Color c) : ScalingFunction(c) { }
202 KBPKBScalingFunction::KBPKBScalingFunction(Color c) : ScalingFunction(c) { }
203 KBPKNScalingFunction::KBPKNScalingFunction(Color c) : ScalingFunction(c) { }
204 KNPKScalingFunction::KNPKScalingFunction(Color c) : ScalingFunction(c) { }
205 KPKPScalingFunction::KPKPScalingFunction(Color c) : ScalingFunction(c) { }
208 /// Mate with KX vs K. This function is used to evaluate positions with
209 /// King and plenty of material vs a lone king. It simply gives the
210 /// attacking side a bonus for driving the defending king towards the edge
211 /// of the board, and for keeping the distance between the two kings small.
213 Value KXKEvaluationFunction::apply(const Position &pos) {
215 assert(pos.non_pawn_material(weakerSide) == Value(0));
216 assert(pos.piece_count(weakerSide, PAWN) == Value(0));
218 Square winnerKSq = pos.king_square(strongerSide);
219 Square loserKSq = pos.king_square(weakerSide);
222 pos.non_pawn_material(strongerSide) +
223 pos.piece_count(strongerSide, PAWN) * PawnValueEndgame +
224 mate_table(loserKSq) +
225 distance_bonus(square_distance(winnerKSq, loserKSq));
227 if(pos.piece_count(strongerSide, QUEEN) > 0 || pos.piece_count(strongerSide, ROOK) > 0 ||
228 pos.piece_count(strongerSide, BISHOP) > 1)
229 // TODO: check for two equal-colored bishops!
230 result += VALUE_KNOWN_WIN;
232 return (strongerSide == pos.side_to_move())? result : -result;
236 /// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
237 /// defending king towards a corner square of the right color.
239 Value KBNKEvaluationFunction::apply(const Position &pos) {
241 assert(pos.non_pawn_material(weakerSide) == Value(0));
242 assert(pos.piece_count(weakerSide, PAWN) == Value(0));
243 assert(pos.non_pawn_material(strongerSide) ==
244 KnightValueMidgame + BishopValueMidgame);
245 assert(pos.piece_count(strongerSide, BISHOP) == 1);
246 assert(pos.piece_count(strongerSide, KNIGHT) == 1);
247 assert(pos.piece_count(strongerSide, PAWN) == 0);
249 Square winnerKSq = pos.king_square(strongerSide);
250 Square loserKSq = pos.king_square(weakerSide);
251 Square bishopSquare = pos.piece_list(strongerSide, BISHOP, 0);
253 if(square_color(bishopSquare) == BLACK) {
254 winnerKSq = flop_square(winnerKSq);
255 loserKSq = flop_square(loserKSq);
259 VALUE_KNOWN_WIN + distance_bonus(square_distance(winnerKSq, loserKSq)) +
260 kbnk_mate_table(loserKSq);
262 return (strongerSide == pos.side_to_move())? result : -result;
266 /// KP vs K. This endgame is evaluated with the help of a bitbase.
268 Value KPKEvaluationFunction::apply(const Position &pos) {
270 assert(pos.non_pawn_material(strongerSide) == Value(0));
271 assert(pos.non_pawn_material(weakerSide) == Value(0));
272 assert(pos.piece_count(strongerSide, PAWN) == 1);
273 assert(pos.piece_count(weakerSide, PAWN) == 0);
275 Square wksq, bksq, wpsq;
278 if(strongerSide == WHITE) {
279 wksq = pos.king_square(WHITE);
280 bksq = pos.king_square(BLACK);
281 wpsq = pos.piece_list(WHITE, PAWN, 0);
282 stm = pos.side_to_move();
285 wksq = flip_square(pos.king_square(BLACK));
286 bksq = flip_square(pos.king_square(WHITE));
287 wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
288 stm = opposite_color(pos.side_to_move());
291 if(square_file(wpsq) >= FILE_E) {
292 wksq = flop_square(wksq);
293 bksq = flop_square(bksq);
294 wpsq = flop_square(wpsq);
297 if(probe_kpk(wksq, wpsq, bksq, stm)) {
299 VALUE_KNOWN_WIN + PawnValueEndgame + Value(square_rank(wpsq));
300 return (strongerSide == pos.side_to_move())? result : -result;
307 /// KR vs KP. This is a somewhat tricky endgame to evaluate precisely without
308 /// a bitbase. The function below returns drawish scores when the pawn is
309 /// far advanced with support of the king, while the attacking king is far
312 Value KRKPEvaluationFunction::apply(const Position &pos) {
314 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
315 assert(pos.piece_count(strongerSide, PAWN) == 0);
316 assert(pos.non_pawn_material(weakerSide) == 0);
317 assert(pos.piece_count(weakerSide, PAWN) == 1);
319 Square wksq, wrsq, bksq, bpsq;
320 int tempo = (pos.side_to_move() == strongerSide);
322 wksq = pos.king_square(strongerSide);
323 wrsq = pos.piece_list(strongerSide, ROOK, 0);
324 bksq = pos.king_square(weakerSide);
325 bpsq = pos.piece_list(weakerSide, PAWN, 0);
327 if(strongerSide == BLACK) {
328 wksq = flip_square(wksq);
329 wrsq = flip_square(wrsq);
330 bksq = flip_square(bksq);
331 bpsq = flip_square(bpsq);
334 Square queeningSq = make_square(square_file(bpsq), RANK_1);
337 // If the stronger side's king is in front of the pawn, it's a win:
338 if(wksq < bpsq && square_file(wksq) == square_file(bpsq))
339 result = RookValueEndgame - Value(square_distance(wksq, bpsq));
341 // If the weaker side's king is too far from the pawn and the rook,
343 else if(square_distance(bksq, bpsq) - (tempo^1) >= 3 &&
344 square_distance(bksq, wrsq) >= 3)
345 result = RookValueEndgame - Value(square_distance(wksq, bpsq));
347 // If the pawn is far advanced and supported by the defending king,
348 // the position is drawish:
349 else if(square_rank(bksq) <= RANK_3 && square_distance(bksq, bpsq) == 1 &&
350 square_rank(wksq) >= RANK_4 &&
351 square_distance(wksq, bpsq) - tempo > 2)
352 result = Value(80 - square_distance(wksq, bpsq) * 8);
356 - Value(square_distance(wksq, bpsq + DELTA_S) * 8)
357 + Value(square_distance(bksq, bpsq + DELTA_S) * 8)
358 + Value(square_distance(bpsq, queeningSq) * 8);
360 return (strongerSide == pos.side_to_move())? result : -result;
364 /// KR vs KB. This is very simple, and always returns drawish scores. The
365 /// score is slightly bigger when the defending king is close to the edge.
367 Value KRKBEvaluationFunction::apply(const Position &pos) {
369 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
370 assert(pos.piece_count(strongerSide, PAWN) == 0);
371 assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
372 assert(pos.piece_count(weakerSide, PAWN) == 0);
373 assert(pos.piece_count(weakerSide, BISHOP) == 1);
375 Value result = mate_table(pos.king_square(weakerSide));
376 return (pos.side_to_move() == strongerSide)? result : -result;
380 /// KR vs KN. The attacking side has slightly better winning chances than
381 /// in KR vs KB, particularly if the king and the knight are far apart.
383 Value KRKNEvaluationFunction::apply(const Position &pos) {
385 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
386 assert(pos.piece_count(strongerSide, PAWN) == 0);
387 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
388 assert(pos.piece_count(weakerSide, PAWN) == 0);
389 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
391 Square defendingKSq = pos.king_square(weakerSide);
392 Square nSq = pos.piece_list(weakerSide, KNIGHT, 0);
394 Value result = Value(10) + mate_table(defendingKSq) +
395 krkn_king_knight_distance_penalty(square_distance(defendingKSq, nSq));
397 return (strongerSide == pos.side_to_move())? result : -result;
401 /// KQ vs KR. This is almost identical to KX vs K: We give the attacking
402 /// king a bonus for having the kings close together, and for forcing the
403 /// defending king towards the edge. If we also take care to avoid null move
404 /// for the defending side in the search, this is usually sufficient to be
405 /// able to win KQ vs KR.
407 Value KQKREvaluationFunction::apply(const Position &pos) {
408 assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
409 assert(pos.piece_count(strongerSide, PAWN) == 0);
410 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
411 assert(pos.piece_count(weakerSide, PAWN) == 0);
413 Square winnerKSq = pos.king_square(strongerSide);
414 Square loserKSq = pos.king_square(weakerSide);
416 Value result = QueenValueEndgame - RookValueEndgame +
417 mate_table(loserKSq) + distance_bonus(square_distance(winnerKSq, loserKSq));
419 return (strongerSide == pos.side_to_move())? result : -result;
423 /// KBPKScalingFunction scales endgames where the stronger side has king,
424 /// bishop and one or more pawns. It checks for draws with rook pawns and a
425 /// bishop of the wrong color. If such a draw is detected, ScaleFactor(0) is
426 /// returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
429 ScaleFactor KBPKScalingFunction::apply(const Position &pos) {
430 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
431 assert(pos.piece_count(strongerSide, BISHOP) == 1);
432 assert(pos.piece_count(strongerSide, PAWN) >= 1);
434 // No assertions about the material of weakerSide, because we want draws to
435 // be detected even when the weaker side has some pawns.
437 Bitboard pawns = pos.pawns(strongerSide);
438 File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
440 if((pawnFile == FILE_A || pawnFile == FILE_H) &&
441 (pawns & ~file_bb(pawnFile)) == EmptyBoardBB) {
442 // All pawns are on a single rook file.
444 Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
446 relative_square(strongerSide, make_square(pawnFile, RANK_8));
447 Square kingSq = pos.king_square(weakerSide);
449 if(square_color(queeningSq) != square_color(bishopSq) &&
450 file_distance(square_file(kingSq), pawnFile) <= 1) {
451 // The bishop has the wrong color, and the defending king is on the
452 // file of the pawn(s) or the neighboring file. Find the rank of the
456 if(strongerSide == WHITE) {
457 for(rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--);
458 assert(rank >= RANK_2 && rank <= RANK_7);
461 for(rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++);
462 rank = Rank(rank^7); // HACK
463 assert(rank >= RANK_2 && rank <= RANK_7);
465 // If the defending king has distance 1 to the promotion square or
466 // is placed somewhere in front of the pawn, it's a draw.
467 if(square_distance(kingSq, queeningSq) <= 1 ||
468 relative_rank(strongerSide, kingSq) >= rank)
469 return ScaleFactor(0);
472 return SCALE_FACTOR_NONE;
476 /// KQKRPScalingFunction scales endgames where the stronger side has only
477 /// king and queen, while the weaker side has at least a rook and a pawn.
478 /// It tests for fortress draws with a rook on the third rank defended by
481 ScaleFactor KQKRPScalingFunction::apply(const Position &pos) {
482 assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
483 assert(pos.piece_count(strongerSide, QUEEN) == 1);
484 assert(pos.piece_count(strongerSide, PAWN) == 0);
485 assert(pos.piece_count(weakerSide, ROOK) == 1);
486 assert(pos.piece_count(weakerSide, PAWN) >= 1);
488 Square kingSq = pos.king_square(weakerSide);
489 if(relative_rank(weakerSide, kingSq) <= RANK_2 &&
490 relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4 &&
491 (pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) &&
492 (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) &&
493 (pos.piece_attacks<KING>(kingSq) & pos.pawns(weakerSide))) {
494 Square rsq = pos.piece_list(weakerSide, ROOK, 0);
495 if(pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide))
496 return ScaleFactor(0);
498 return SCALE_FACTOR_NONE;
502 /// KRPKRScalingFunction scales KRP vs KR endgames. This function knows a
503 /// handful of the most important classes of drawn positions, but is far
504 /// from perfect. It would probably be a good idea to add more knowledge
507 /// It would also be nice to rewrite the actual code for this function,
508 /// which is mostly copied from Glaurung 1.x, and not very pretty.
510 ScaleFactor KRPKRScalingFunction::apply(const Position &pos) {
511 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
512 assert(pos.piece_count(strongerSide, PAWN) == 1);
513 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
514 assert(pos.piece_count(weakerSide, PAWN) == 0);
516 Square wksq = pos.king_square(strongerSide);
517 Square wrsq = pos.piece_list(strongerSide, ROOK, 0);
518 Square wpsq = pos.piece_list(strongerSide, PAWN, 0);
519 Square bksq = pos.king_square(weakerSide);
520 Square brsq = pos.piece_list(weakerSide, ROOK, 0);
522 // Orient the board in such a way that the stronger side is white, and the
523 // pawn is on the left half of the board:
524 if(strongerSide == BLACK) {
525 wksq = flip_square(wksq);
526 wrsq = flip_square(wrsq);
527 wpsq = flip_square(wpsq);
528 bksq = flip_square(bksq);
529 brsq = flip_square(brsq);
531 if(square_file(wpsq) > FILE_D) {
532 wksq = flop_square(wksq);
533 wrsq = flop_square(wrsq);
534 wpsq = flop_square(wpsq);
535 bksq = flop_square(bksq);
536 brsq = flop_square(brsq);
539 File f = square_file(wpsq);
540 Rank r = square_rank(wpsq);
541 Square queeningSq = make_square(f, RANK_8);
542 int tempo = (pos.side_to_move() == strongerSide);
544 // If the pawn is not too far advanced and the defending king defends the
545 // queening square, use the third-rank defence:
546 if(r <= RANK_5 && square_distance(bksq, queeningSq) <= 1 && wksq <= SQ_H5 &&
547 (square_rank(brsq) == RANK_6 || (r <= RANK_3 &&
548 square_rank(wrsq) != RANK_6)))
549 return ScaleFactor(0);
551 // The defending side saves a draw by checking from behind in case the pawn
552 // has advanced to the 6th rank with the king behind.
553 if(r == RANK_6 && square_distance(bksq, queeningSq) <= 1 &&
554 square_rank(wksq) + tempo <= RANK_6 &&
555 (square_rank(brsq) == RANK_1 ||
556 (!tempo && abs(square_file(brsq) - f) >= 3)))
557 return ScaleFactor(0);
559 if(r >= RANK_6 && bksq == queeningSq && square_rank(brsq) == RANK_1 &&
560 (!tempo || square_distance(wksq, wpsq) >= 2))
561 return ScaleFactor(0);
563 // White pawn on a7 and rook on a8 is a draw if black's king is on g7 or h7
564 // and the black rook is behind the pawn.
565 if(wpsq == SQ_A7 && wrsq == SQ_A8 && (bksq == SQ_H7 || bksq == SQ_G7) &&
566 square_file(brsq) == FILE_A &&
567 (square_rank(brsq) <= RANK_3 || square_file(wksq) >= FILE_D ||
568 square_rank(wksq) <= RANK_5))
569 return ScaleFactor(0);
571 // If the defending king blocks the pawn and the attacking king is too far
572 // away, it's a draw.
573 if(r <= RANK_5 && bksq == wpsq + DELTA_N &&
574 square_distance(wksq, wpsq) - tempo >= 2 &&
575 square_distance(wksq, brsq) - tempo >= 2)
576 return ScaleFactor(0);
578 // Pawn on the 7th rank supported by the rook from behind usually wins if the
579 // attacking king is closer to the queening square than the defending king,
580 // and the defending king cannot gain tempi by threatening the attacking
582 if(r == RANK_7 && f != FILE_A && square_file(wrsq) == f
583 && wrsq != queeningSq
584 && (square_distance(wksq, queeningSq) <
585 square_distance(bksq, queeningSq) - 2 + tempo)
586 && (square_distance(wksq, queeningSq) <
587 square_distance(bksq, wrsq) + tempo))
588 return ScaleFactor(SCALE_FACTOR_MAX
589 - 2 * square_distance(wksq, queeningSq));
591 // Similar to the above, but with the pawn further back:
592 if(f != FILE_A && square_file(wrsq) == f && wrsq < wpsq
593 && (square_distance(wksq, queeningSq) <
594 square_distance(bksq, queeningSq) - 2 + tempo)
595 && (square_distance(wksq, wpsq + DELTA_N) <
596 square_distance(bksq, wpsq + DELTA_N) - 2 + tempo)
597 && (square_distance(bksq, wrsq) + tempo >= 3
598 || (square_distance(wksq, queeningSq) <
599 square_distance(bksq, wrsq) + tempo
600 && (square_distance(wksq, wpsq + DELTA_N) <
601 square_distance(bksq, wrsq) + tempo))))
603 ScaleFactor(SCALE_FACTOR_MAX
604 - (8 * square_distance(wpsq, queeningSq) +
605 2 * square_distance(wksq, queeningSq)));
607 return SCALE_FACTOR_NONE;
611 /// KRPPKRPScalingFunction scales KRPP vs KRP endgames. There is only a
612 /// single pattern: If the stronger side has no pawns and the defending king
613 /// is actively placed, the position is drawish.
615 ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) {
616 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
617 assert(pos.piece_count(strongerSide, PAWN) == 2);
618 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
619 assert(pos.piece_count(weakerSide, PAWN) == 1);
621 Square wpsq1 = pos.piece_list(strongerSide, PAWN, 0);
622 Square wpsq2 = pos.piece_list(strongerSide, PAWN, 1);
623 Square bksq = pos.king_square(weakerSide);
625 // Does the stronger side have a passed pawn?
626 if(pos.pawn_is_passed(strongerSide, wpsq1) ||
627 pos.pawn_is_passed(strongerSide, wpsq2))
628 return SCALE_FACTOR_NONE;
630 Rank r = Max(relative_rank(strongerSide, wpsq1), relative_rank(strongerSide, wpsq2));
632 if(file_distance(bksq, wpsq1) <= 1 && file_distance(bksq, wpsq2) <= 1
633 && relative_rank(strongerSide, bksq) > r) {
636 case RANK_2: return ScaleFactor(10);
637 case RANK_3: return ScaleFactor(10);
638 case RANK_4: return ScaleFactor(15);
639 case RANK_5: return ScaleFactor(20);
640 case RANK_6: return ScaleFactor(40);
641 default: assert(false);
645 return SCALE_FACTOR_NONE;
649 /// KPsKScalingFunction scales endgames with king and two or more pawns
650 /// against king. There is just a single rule here: If all pawns are on
651 /// the same rook file and are blocked by the defending king, it's a draw.
653 ScaleFactor KPsKScalingFunction::apply(const Position &pos) {
654 assert(pos.non_pawn_material(strongerSide) == Value(0));
655 assert(pos.piece_count(strongerSide, PAWN) >= 2);
656 assert(pos.non_pawn_material(weakerSide) == Value(0));
657 assert(pos.piece_count(weakerSide, PAWN) == 0);
659 Bitboard pawns = pos.pawns(strongerSide);
661 // Are all pawns on the 'a' file?
662 if((pawns & ~FileABB) == EmptyBoardBB) {
663 // Does the defending king block the pawns?
664 Square ksq = pos.king_square(weakerSide);
665 if(square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1)
666 return ScaleFactor(0);
667 else if(square_file(ksq) == FILE_A &&
668 (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB)
669 return ScaleFactor(0);
671 return SCALE_FACTOR_NONE;
673 // Are all pawns on the 'h' file?
674 else if((pawns & ~FileHBB) == EmptyBoardBB) {
675 // Does the defending king block the pawns?
676 Square ksq = pos.king_square(weakerSide);
677 if(square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1)
678 return ScaleFactor(0);
679 else if(square_file(ksq) == FILE_H &&
680 (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB)
681 return ScaleFactor(0);
683 return SCALE_FACTOR_NONE;
686 return SCALE_FACTOR_NONE;
690 /// KBPKBScalingFunction scales KBP vs KB endgames. There are two rules:
691 /// If the defending king is somewhere along the path of the pawn, and the
692 /// square of the king is not of the same color as the stronger side's bishop,
693 /// it's a draw. If the two bishops have opposite color, it's almost always
696 ScaleFactor KBPKBScalingFunction::apply(const Position &pos) {
697 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
698 assert(pos.piece_count(strongerSide, BISHOP) == 1);
699 assert(pos.piece_count(strongerSide, PAWN) == 1);
700 assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
701 assert(pos.piece_count(weakerSide, BISHOP) == 1);
702 assert(pos.piece_count(weakerSide, PAWN) == 0);
704 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
705 Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
706 Square weakerBishopSq = pos.piece_list(weakerSide, BISHOP, 0);
707 Square weakerKingSq = pos.king_square(weakerSide);
709 // Case 1: Defending king blocks the pawn, and cannot be driven away.
710 if(square_file(weakerKingSq) == square_file(pawnSq)
711 && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
712 && (square_color(weakerKingSq) != square_color(strongerBishopSq)
713 || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
714 return ScaleFactor(0);
716 // Case 2: Opposite colored bishops.
717 if(square_color(strongerBishopSq) != square_color(weakerBishopSq)) {
719 // We assume that the position is drawn in the following three situations:
721 // a. The pawn is on rank 5 or further back.
722 // b. The defending king is somewhere in the pawn's path.
723 // c. The defending bishop attacks some square along the pawn's path,
724 // and is at least three squares away from the pawn.
726 // These rules are probably not perfect, but in practice they work
729 if(relative_rank(strongerSide, pawnSq) <= RANK_5)
730 return ScaleFactor(0);
733 ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S);
734 if(ray & pos.kings(weakerSide))
735 return ScaleFactor(0);
736 if((pos.piece_attacks<BISHOP>(weakerBishopSq) & ray)
737 && square_distance(weakerBishopSq, pawnSq) >= 3)
738 return ScaleFactor(0);
741 return SCALE_FACTOR_NONE;
745 /// KBPKNScalingFunction scales KBP vs KN endgames. There is a single rule:
746 /// If the defending king is somewhere along the path of the pawn, and the
747 /// square of the king is not of the same color as the stronger side's bishop,
750 ScaleFactor KBPKNScalingFunction::apply(const Position &pos) {
751 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
752 assert(pos.piece_count(strongerSide, BISHOP) == 1);
753 assert(pos.piece_count(strongerSide, PAWN) == 1);
754 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
755 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
756 assert(pos.piece_count(weakerSide, PAWN) == 0);
758 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
759 Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
760 Square weakerKingSq = pos.king_square(weakerSide);
762 if(square_file(weakerKingSq) == square_file(pawnSq)
763 && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
764 && (square_color(weakerKingSq) != square_color(strongerBishopSq)
765 || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
766 return ScaleFactor(0);
768 return SCALE_FACTOR_NONE;
772 /// KNPKScalingFunction scales KNP vs K endgames. There is a single rule:
773 /// If the pawn is a rook pawn on the 7th rank and the defending king prevents
774 /// the pawn from advancing, the position is drawn.
776 ScaleFactor KNPKScalingFunction::apply(const Position &pos) {
777 assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame);
778 assert(pos.piece_count(strongerSide, KNIGHT) == 1);
779 assert(pos.piece_count(strongerSide, PAWN) == 1);
780 assert(pos.non_pawn_material(weakerSide) == Value(0));
781 assert(pos.piece_count(weakerSide, PAWN) == 0);
783 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
784 Square weakerKingSq = pos.king_square(weakerSide);
786 if(pawnSq == relative_square(strongerSide, SQ_A7) &&
787 square_distance(weakerKingSq, relative_square(strongerSide, SQ_A8)) <= 1)
788 return ScaleFactor(0);
790 if(pawnSq == relative_square(strongerSide, SQ_H7) &&
791 square_distance(weakerKingSq, relative_square(strongerSide, SQ_H8)) <= 1)
792 return ScaleFactor(0);
794 return SCALE_FACTOR_NONE;
798 /// KPKPScalingFunction scales KP vs KP endgames. This is done by removing
799 /// the weakest side's pawn and probing the KP vs K bitbase: If the weakest
800 /// side has a draw without the pawn, she probably has at least a draw with
801 /// the pawn as well. The exception is when the stronger side's pawn is far
802 /// advanced and not on a rook file; in this case it is often possible to win
803 /// (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1).
805 ScaleFactor KPKPScalingFunction::apply(const Position &pos) {
806 assert(pos.non_pawn_material(strongerSide) == Value(0));
807 assert(pos.non_pawn_material(weakerSide) == Value(0));
808 assert(pos.piece_count(WHITE, PAWN) == 1);
809 assert(pos.piece_count(BLACK, PAWN) == 1);
811 Square wksq, bksq, wpsq;
814 if(strongerSide == WHITE) {
815 wksq = pos.king_square(WHITE);
816 bksq = pos.king_square(BLACK);
817 wpsq = pos.piece_list(WHITE, PAWN, 0);
818 stm = pos.side_to_move();
821 wksq = flip_square(pos.king_square(BLACK));
822 bksq = flip_square(pos.king_square(WHITE));
823 wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
824 stm = opposite_color(pos.side_to_move());
827 if(square_file(wpsq) >= FILE_E) {
828 wksq = flop_square(wksq);
829 bksq = flop_square(bksq);
830 wpsq = flop_square(wpsq);
833 // If the pawn has advanced to the fifth rank or further, and is not a
834 // rook pawn, it's too dangerous to assume that it's at least a draw.
835 if(square_rank(wpsq) >= RANK_5 && square_file(wpsq) != FILE_A)
836 return SCALE_FACTOR_NONE;
838 // Probe the KPK bitbase with the weakest side's pawn removed. If it's a
839 // draw, it's probably at least a draw even with the pawn.
840 if(probe_kpk(wksq, wpsq, bksq, stm))
841 return SCALE_FACTOR_NONE;
843 return ScaleFactor(0);
847 /// init_bitbases() is called during program initialization, and simply loads
848 /// bitbases from disk into memory. At the moment, there is only the bitbase
849 /// for KP vs K, but we may decide to add other bitbases later.
851 void init_bitbases() {
852 generate_kpk_bitbase(KPKBitbase);
858 // Probe the KP vs K bitbase:
860 int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm) {
861 int wp = int(square_file(wpsq)) + (int(square_rank(wpsq)) - 1) * 4;
862 int index = int(stm) + 2*int(bksq) + 128*int(wksq) + 8192*wp;
864 assert(index >= 0 && index < 24576*8);
865 return KPKBitbase[index/8] & (1 << (index&7));