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 EvaluationFunction<KXK> EvaluateKXK(WHITE), EvaluateKKX(BLACK);
40 // K and two minors vs K and one or two minors
41 EvaluationFunction<KmmKm> EvaluateKmmKm(WHITE);
43 EvaluationFunction<KBNK> EvaluateKBNK(WHITE), EvaluateKKBN(BLACK); // KBN vs K
44 EvaluationFunction<KPK> EvaluateKPK(WHITE), EvaluateKKP(BLACK); // KP vs K
45 EvaluationFunction<KRKP> EvaluateKRKP(WHITE), EvaluateKPKR(BLACK); // KR vs KP
46 EvaluationFunction<KRKB> EvaluateKRKB(WHITE), EvaluateKBKR(BLACK); // KR vs KB
47 EvaluationFunction<KRKN> EvaluateKRKN(WHITE), EvaluateKNKR(BLACK); // KR vs KN
48 EvaluationFunction<KQKR> EvaluateKQKR(WHITE), EvaluateKRKQ(BLACK); // KQ vs KR
49 EvaluationFunction<KBBKN> EvaluateKBBKN(WHITE), EvaluateKNKBB(BLACK); // KBB vs KN
55 KBPKScalingFunction ScaleKBPK = KBPKScalingFunction(WHITE);
56 KBPKScalingFunction ScaleKKBP = KBPKScalingFunction(BLACK);
59 KQKRPScalingFunction ScaleKQKRP = KQKRPScalingFunction(WHITE);
60 KQKRPScalingFunction ScaleKRPKQ = KQKRPScalingFunction(BLACK);
63 KRPKRScalingFunction ScaleKRPKR = KRPKRScalingFunction(WHITE);
64 KRPKRScalingFunction ScaleKRKRP = KRPKRScalingFunction(BLACK);
67 KRPPKRPScalingFunction ScaleKRPPKRP = KRPPKRPScalingFunction(WHITE);
68 KRPPKRPScalingFunction ScaleKRPKRPP = KRPPKRPScalingFunction(BLACK);
70 // King and pawns vs king
71 KPsKScalingFunction ScaleKPsK = KPsKScalingFunction(WHITE);
72 KPsKScalingFunction ScaleKKPs = KPsKScalingFunction(BLACK);
75 KBPKBScalingFunction ScaleKBPKB = KBPKBScalingFunction(WHITE);
76 KBPKBScalingFunction ScaleKBKBP = KBPKBScalingFunction(BLACK);
79 KBPKNScalingFunction ScaleKBPKN = KBPKNScalingFunction(WHITE);
80 KBPKNScalingFunction ScaleKNKBP = KBPKNScalingFunction(BLACK);
83 KNPKScalingFunction ScaleKNPK = KNPKScalingFunction(WHITE);
84 KNPKScalingFunction ScaleKKNP = KNPKScalingFunction(BLACK);
87 KPKPScalingFunction ScaleKPKPw = KPKPScalingFunction(WHITE);
88 KPKPScalingFunction ScaleKPKPb = KPKPScalingFunction(BLACK);
92 //// Local definitions
97 // Table used to drive the defending king towards the edge of the board
98 // in KX vs K and KQ vs KR endgames.
99 const uint8_t MateTable[64] = {
100 100, 90, 80, 70, 70, 80, 90, 100,
101 90, 70, 60, 50, 50, 60, 70, 90,
102 80, 60, 40, 30, 30, 40, 60, 80,
103 70, 50, 30, 20, 20, 30, 50, 70,
104 70, 50, 30, 20, 20, 30, 50, 70,
105 80, 60, 40, 30, 30, 40, 60, 80,
106 90, 70, 60, 50, 50, 60, 70, 90,
107 100, 90, 80, 70, 70, 80, 90, 100,
110 // Table used to drive the defending king towards a corner square of the
111 // right color in KBN vs K endgames.
112 const uint8_t KBNKMateTable[64] = {
113 200, 190, 180, 170, 160, 150, 140, 130,
114 190, 180, 170, 160, 150, 140, 130, 140,
115 180, 170, 155, 140, 140, 125, 140, 150,
116 170, 160, 140, 120, 110, 140, 150, 160,
117 160, 150, 140, 110, 120, 140, 160, 170,
118 150, 140, 125, 140, 140, 155, 170, 180,
119 140, 130, 140, 150, 160, 170, 180, 190,
120 130, 140, 150, 160, 170, 180, 190, 200
123 // The attacking side is given a descending bonus based on distance between
124 // the two kings in basic endgames.
125 const int DistanceBonus[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
127 // Bitbase for KP vs K
128 uint8_t KPKBitbase[24576];
130 // Penalty for big distance between king and knight for the defending king
131 // and knight in KR vs KN endgames.
132 const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
134 // Various inline functions for accessing the above arrays
135 inline Value mate_table(Square s) {
136 return Value(MateTable[s]);
139 inline Value kbnk_mate_table(Square s) {
140 return Value(KBNKMateTable[s]);
143 inline Value distance_bonus(int d) {
144 return Value(DistanceBonus[d]);
147 inline Value krkn_king_knight_distance_penalty(int d) {
148 return Value(KRKNKingKnightDistancePenalty[d]);
151 // Function for probing the KP vs K bitbase
152 int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm);
163 EndgameEvaluationFunction::EndgameEvaluationFunction(Color c) : strongerSide(c) {
164 weakerSide = opposite_color(strongerSide);
167 ScalingFunction::ScalingFunction(Color c) : strongerSide(c) {
168 weakerSide = opposite_color(c);
171 KBPKScalingFunction::KBPKScalingFunction(Color c) : ScalingFunction(c) {}
172 KQKRPScalingFunction::KQKRPScalingFunction(Color c) : ScalingFunction(c) {}
173 KRPKRScalingFunction::KRPKRScalingFunction(Color c) : ScalingFunction(c) {}
174 KRPPKRPScalingFunction::KRPPKRPScalingFunction(Color c) : ScalingFunction(c) {}
175 KPsKScalingFunction::KPsKScalingFunction(Color c) : ScalingFunction(c) {}
176 KBPKBScalingFunction::KBPKBScalingFunction(Color c) : ScalingFunction(c) {}
177 KBPKNScalingFunction::KBPKNScalingFunction(Color c) : ScalingFunction(c) {}
178 KNPKScalingFunction::KNPKScalingFunction(Color c) : ScalingFunction(c) {}
179 KPKPScalingFunction::KPKPScalingFunction(Color c) : ScalingFunction(c) {}
182 /// Mate with KX vs K. This function is used to evaluate positions with
183 /// King and plenty of material vs a lone king. It simply gives the
184 /// attacking side a bonus for driving the defending king towards the edge
185 /// of the board, and for keeping the distance between the two kings small.
187 Value EvaluationFunction<KXK>::apply(const Position& pos) {
189 assert(pos.non_pawn_material(weakerSide) == Value(0));
190 assert(pos.piece_count(weakerSide, PAWN) == Value(0));
192 Square winnerKSq = pos.king_square(strongerSide);
193 Square loserKSq = pos.king_square(weakerSide);
195 Value result = pos.non_pawn_material(strongerSide)
196 + pos.piece_count(strongerSide, PAWN) * PawnValueEndgame
197 + mate_table(loserKSq)
198 + distance_bonus(square_distance(winnerKSq, loserKSq));
200 if ( pos.piece_count(strongerSide, QUEEN) > 0
201 || pos.piece_count(strongerSide, ROOK) > 0
202 || pos.piece_count(strongerSide, BISHOP) > 1)
203 // TODO: check for two equal-colored bishops!
204 result += VALUE_KNOWN_WIN;
206 return (strongerSide == pos.side_to_move() ? result : -result);
210 /// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
211 /// defending king towards a corner square of the right color.
213 Value EvaluationFunction<KBNK>::apply(const Position& pos) {
215 assert(pos.non_pawn_material(weakerSide) == Value(0));
216 assert(pos.piece_count(weakerSide, PAWN) == Value(0));
217 assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame + BishopValueMidgame);
218 assert(pos.piece_count(strongerSide, BISHOP) == 1);
219 assert(pos.piece_count(strongerSide, KNIGHT) == 1);
220 assert(pos.piece_count(strongerSide, PAWN) == 0);
222 Square winnerKSq = pos.king_square(strongerSide);
223 Square loserKSq = pos.king_square(weakerSide);
224 Square bishopSquare = pos.piece_list(strongerSide, BISHOP, 0);
226 if (square_color(bishopSquare) == BLACK)
228 winnerKSq = flop_square(winnerKSq);
229 loserKSq = flop_square(loserKSq);
232 Value result = VALUE_KNOWN_WIN
233 + distance_bonus(square_distance(winnerKSq, loserKSq))
234 + kbnk_mate_table(loserKSq);
236 return (strongerSide == pos.side_to_move() ? result : -result);
240 /// KP vs K. This endgame is evaluated with the help of a bitbase.
242 Value EvaluationFunction<KPK>::apply(const Position& pos) {
244 assert(pos.non_pawn_material(strongerSide) == Value(0));
245 assert(pos.non_pawn_material(weakerSide) == Value(0));
246 assert(pos.piece_count(strongerSide, PAWN) == 1);
247 assert(pos.piece_count(weakerSide, PAWN) == 0);
249 Square wksq, bksq, wpsq;
252 if (strongerSide == WHITE)
254 wksq = pos.king_square(WHITE);
255 bksq = pos.king_square(BLACK);
256 wpsq = pos.piece_list(WHITE, PAWN, 0);
257 stm = pos.side_to_move();
261 wksq = flip_square(pos.king_square(BLACK));
262 bksq = flip_square(pos.king_square(WHITE));
263 wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
264 stm = opposite_color(pos.side_to_move());
267 if (square_file(wpsq) >= FILE_E)
269 wksq = flop_square(wksq);
270 bksq = flop_square(bksq);
271 wpsq = flop_square(wpsq);
274 if (!probe_kpk(wksq, wpsq, bksq, stm))
277 Value result = VALUE_KNOWN_WIN
279 + Value(square_rank(wpsq));
281 return (strongerSide == pos.side_to_move() ? result : -result);
285 /// KR vs KP. This is a somewhat tricky endgame to evaluate precisely without
286 /// a bitbase. The function below returns drawish scores when the pawn is
287 /// far advanced with support of the king, while the attacking king is far
290 Value EvaluationFunction<KRKP>::apply(const Position& pos) {
292 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
293 assert(pos.piece_count(strongerSide, PAWN) == 0);
294 assert(pos.non_pawn_material(weakerSide) == 0);
295 assert(pos.piece_count(weakerSide, PAWN) == 1);
297 Square wksq, wrsq, bksq, bpsq;
298 int tempo = (pos.side_to_move() == strongerSide);
300 wksq = pos.king_square(strongerSide);
301 wrsq = pos.piece_list(strongerSide, ROOK, 0);
302 bksq = pos.king_square(weakerSide);
303 bpsq = pos.piece_list(weakerSide, PAWN, 0);
305 if (strongerSide == BLACK)
307 wksq = flip_square(wksq);
308 wrsq = flip_square(wrsq);
309 bksq = flip_square(bksq);
310 bpsq = flip_square(bpsq);
313 Square queeningSq = make_square(square_file(bpsq), RANK_1);
316 // If the stronger side's king is in front of the pawn, it's a win
317 if (wksq < bpsq && square_file(wksq) == square_file(bpsq))
318 result = RookValueEndgame - Value(square_distance(wksq, bpsq));
320 // If the weaker side's king is too far from the pawn and the rook,
322 else if ( square_distance(bksq, bpsq) - (tempo^1) >= 3
323 && square_distance(bksq, wrsq) >= 3)
324 result = RookValueEndgame - Value(square_distance(wksq, bpsq));
326 // If the pawn is far advanced and supported by the defending king,
327 // the position is drawish
328 else if ( square_rank(bksq) <= RANK_3
329 && square_distance(bksq, bpsq) == 1
330 && square_rank(wksq) >= RANK_4
331 && square_distance(wksq, bpsq) - tempo > 2)
332 result = Value(80 - square_distance(wksq, bpsq) * 8);
336 - Value(square_distance(wksq, bpsq + DELTA_S) * 8)
337 + Value(square_distance(bksq, bpsq + DELTA_S) * 8)
338 + Value(square_distance(bpsq, queeningSq) * 8);
340 return (strongerSide == pos.side_to_move() ? result : -result);
344 /// KR vs KB. This is very simple, and always returns drawish scores. The
345 /// score is slightly bigger when the defending king is close to the edge.
347 Value EvaluationFunction<KRKB>::apply(const Position& pos) {
349 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
350 assert(pos.piece_count(strongerSide, PAWN) == 0);
351 assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
352 assert(pos.piece_count(weakerSide, PAWN) == 0);
353 assert(pos.piece_count(weakerSide, BISHOP) == 1);
355 Value result = mate_table(pos.king_square(weakerSide));
356 return (pos.side_to_move() == strongerSide ? result : -result);
360 /// KR vs KN. The attacking side has slightly better winning chances than
361 /// in KR vs KB, particularly if the king and the knight are far apart.
363 Value EvaluationFunction<KRKN>::apply(const Position& pos) {
365 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
366 assert(pos.piece_count(strongerSide, PAWN) == 0);
367 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
368 assert(pos.piece_count(weakerSide, PAWN) == 0);
369 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
371 Square defendingKSq = pos.king_square(weakerSide);
372 Square nSq = pos.piece_list(weakerSide, KNIGHT, 0);
374 Value result = Value(10) + mate_table(defendingKSq) +
375 krkn_king_knight_distance_penalty(square_distance(defendingKSq, nSq));
377 return (strongerSide == pos.side_to_move())? result : -result;
381 /// KQ vs KR. This is almost identical to KX vs K: We give the attacking
382 /// king a bonus for having the kings close together, and for forcing the
383 /// defending king towards the edge. If we also take care to avoid null move
384 /// for the defending side in the search, this is usually sufficient to be
385 /// able to win KQ vs KR.
387 Value EvaluationFunction<KQKR>::apply(const Position& pos) {
389 assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
390 assert(pos.piece_count(strongerSide, PAWN) == 0);
391 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
392 assert(pos.piece_count(weakerSide, PAWN) == 0);
394 Square winnerKSq = pos.king_square(strongerSide);
395 Square loserKSq = pos.king_square(weakerSide);
397 Value result = QueenValueEndgame
399 + mate_table(loserKSq)
400 + distance_bonus(square_distance(winnerKSq, loserKSq));
402 return (strongerSide == pos.side_to_move())? result : -result;
406 Value EvaluationFunction<KBBKN>::apply(const Position& pos) {
408 assert(pos.piece_count(strongerSide, BISHOP) == 2);
409 assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
410 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
411 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
412 assert(pos.pawns() == EmptyBoardBB);
414 Value result = BishopValueEndgame;
415 Square wksq = pos.king_square(strongerSide);
416 Square bksq = pos.king_square(weakerSide);
417 Square nsq = pos.piece_list(weakerSide, KNIGHT, 0);
419 // Bonus for attacking king close to defending king
420 result += distance_bonus(square_distance(wksq, bksq));
422 // Bonus for driving the defending king and knight apart
423 result += Value(square_distance(bksq, nsq) * 32);
425 // Bonus for restricting the knight's mobility
426 result += Value((8 - count_1s_max_15(pos.piece_attacks<KNIGHT>(nsq))) * 8);
428 return (strongerSide == pos.side_to_move() ? result : -result);
432 Value EvaluationFunction<KmmKm>::apply(const Position &pos) {
437 /// KBPKScalingFunction scales endgames where the stronger side has king,
438 /// bishop and one or more pawns. It checks for draws with rook pawns and a
439 /// bishop of the wrong color. If such a draw is detected, ScaleFactor(0) is
440 /// returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
443 ScaleFactor KBPKScalingFunction::apply(const Position& pos) {
445 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
446 assert(pos.piece_count(strongerSide, BISHOP) == 1);
447 assert(pos.piece_count(strongerSide, PAWN) >= 1);
449 // No assertions about the material of weakerSide, because we want draws to
450 // be detected even when the weaker side has some pawns.
452 Bitboard pawns = pos.pawns(strongerSide);
453 File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
455 // All pawns are on a single rook file ?
456 if ( (pawnFile == FILE_A || pawnFile == FILE_H)
457 && (pawns & ~file_bb(pawnFile)) == EmptyBoardBB)
459 Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
460 Square queeningSq = relative_square(strongerSide, make_square(pawnFile, RANK_8));
461 Square kingSq = pos.king_square(weakerSide);
463 if ( square_color(queeningSq) != square_color(bishopSq)
464 && file_distance(square_file(kingSq), pawnFile) <= 1)
466 // The bishop has the wrong color, and the defending king is on the
467 // file of the pawn(s) or the neighboring file. Find the rank of the
471 if (strongerSide == WHITE)
473 for (rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--) {}
474 assert(rank >= RANK_2 && rank <= RANK_7);
478 for(rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++) {}
479 rank = Rank(rank^7); // HACK to get the relative rank
480 assert(rank >= RANK_2 && rank <= RANK_7);
482 // If the defending king has distance 1 to the promotion square or
483 // is placed somewhere in front of the pawn, it's a draw.
484 if ( square_distance(kingSq, queeningSq) <= 1
485 || relative_rank(strongerSide, kingSq) >= rank)
486 return ScaleFactor(0);
489 return SCALE_FACTOR_NONE;
493 /// KQKRPScalingFunction scales endgames where the stronger side has only
494 /// king and queen, while the weaker side has at least a rook and a pawn.
495 /// It tests for fortress draws with a rook on the third rank defended by
498 ScaleFactor KQKRPScalingFunction::apply(const Position& pos) {
500 assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
501 assert(pos.piece_count(strongerSide, QUEEN) == 1);
502 assert(pos.piece_count(strongerSide, PAWN) == 0);
503 assert(pos.piece_count(weakerSide, ROOK) == 1);
504 assert(pos.piece_count(weakerSide, PAWN) >= 1);
506 Square kingSq = pos.king_square(weakerSide);
507 if ( relative_rank(weakerSide, kingSq) <= RANK_2
508 && relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4
509 && (pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3))
510 && (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2))
511 && (pos.piece_attacks<KING>(kingSq) & pos.pawns(weakerSide)))
513 Square rsq = pos.piece_list(weakerSide, ROOK, 0);
514 if (pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide))
515 return ScaleFactor(0);
517 return SCALE_FACTOR_NONE;
521 /// KRPKRScalingFunction scales KRP vs KR endgames. This function knows a
522 /// handful of the most important classes of drawn positions, but is far
523 /// from perfect. It would probably be a good idea to add more knowledge
526 /// It would also be nice to rewrite the actual code for this function,
527 /// which is mostly copied from Glaurung 1.x, and not very pretty.
529 ScaleFactor KRPKRScalingFunction::apply(const Position &pos) {
531 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
532 assert(pos.piece_count(strongerSide, PAWN) == 1);
533 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
534 assert(pos.piece_count(weakerSide, PAWN) == 0);
536 Square wksq = pos.king_square(strongerSide);
537 Square wrsq = pos.piece_list(strongerSide, ROOK, 0);
538 Square wpsq = pos.piece_list(strongerSide, PAWN, 0);
539 Square bksq = pos.king_square(weakerSide);
540 Square brsq = pos.piece_list(weakerSide, ROOK, 0);
542 // Orient the board in such a way that the stronger side is white, and the
543 // pawn is on the left half of the board.
544 if (strongerSide == BLACK)
546 wksq = flip_square(wksq);
547 wrsq = flip_square(wrsq);
548 wpsq = flip_square(wpsq);
549 bksq = flip_square(bksq);
550 brsq = flip_square(brsq);
552 if (square_file(wpsq) > FILE_D)
554 wksq = flop_square(wksq);
555 wrsq = flop_square(wrsq);
556 wpsq = flop_square(wpsq);
557 bksq = flop_square(bksq);
558 brsq = flop_square(brsq);
561 File f = square_file(wpsq);
562 Rank r = square_rank(wpsq);
563 Square queeningSq = make_square(f, RANK_8);
564 int tempo = (pos.side_to_move() == strongerSide);
566 // If the pawn is not too far advanced and the defending king defends the
567 // queening square, use the third-rank defence.
569 && square_distance(bksq, queeningSq) <= 1
571 && (square_rank(brsq) == RANK_6 || (r <= RANK_3 && square_rank(wrsq) != RANK_6)))
572 return ScaleFactor(0);
574 // The defending side saves a draw by checking from behind in case the pawn
575 // has advanced to the 6th rank with the king behind.
577 && square_distance(bksq, queeningSq) <= 1
578 && square_rank(wksq) + tempo <= RANK_6
579 && (square_rank(brsq) == RANK_1 || (!tempo && abs(square_file(brsq) - f) >= 3)))
580 return ScaleFactor(0);
583 && bksq == queeningSq
584 && square_rank(brsq) == RANK_1
585 && (!tempo || square_distance(wksq, wpsq) >= 2))
586 return ScaleFactor(0);
588 // White pawn on a7 and rook on a8 is a draw if black's king is on g7 or h7
589 // and the black rook is behind the pawn.
592 && (bksq == SQ_H7 || bksq == SQ_G7)
593 && square_file(brsq) == FILE_A
594 && (square_rank(brsq) <= RANK_3 || square_file(wksq) >= FILE_D || square_rank(wksq) <= RANK_5))
595 return ScaleFactor(0);
597 // If the defending king blocks the pawn and the attacking king is too far
598 // away, it's a draw.
600 && bksq == wpsq + DELTA_N
601 && square_distance(wksq, wpsq) - tempo >= 2
602 && square_distance(wksq, brsq) - tempo >= 2)
603 return ScaleFactor(0);
605 // Pawn on the 7th rank supported by the rook from behind usually wins if the
606 // attacking king is closer to the queening square than the defending king,
607 // and the defending king cannot gain tempi by threatening the attacking rook.
610 && square_file(wrsq) == f
611 && wrsq != queeningSq
612 && (square_distance(wksq, queeningSq) < square_distance(bksq, queeningSq) - 2 + tempo)
613 && (square_distance(wksq, queeningSq) < square_distance(bksq, wrsq) + tempo))
614 return ScaleFactor(SCALE_FACTOR_MAX - 2 * square_distance(wksq, queeningSq));
616 // Similar to the above, but with the pawn further back
618 && square_file(wrsq) == f
620 && (square_distance(wksq, queeningSq) < square_distance(bksq, queeningSq) - 2 + tempo)
621 && (square_distance(wksq, wpsq + DELTA_N) < square_distance(bksq, wpsq + DELTA_N) - 2 + tempo)
622 && ( square_distance(bksq, wrsq) + tempo >= 3
623 || ( square_distance(wksq, queeningSq) < square_distance(bksq, wrsq) + tempo
624 && (square_distance(wksq, wpsq + DELTA_N) < square_distance(bksq, wrsq) + tempo))))
625 return ScaleFactor( SCALE_FACTOR_MAX
626 - (8 * square_distance(wpsq, queeningSq)
627 + 2 * square_distance(wksq, queeningSq)));
629 // If the pawn is not far advanced, and the defending king is somewhere in
630 // the pawn's path, it's probably a draw.
631 if (r <= RANK_4 && bksq > wpsq)
633 if (square_file(bksq) == square_file(wpsq))
634 return ScaleFactor(10);
635 if ( abs(square_file(bksq) - square_file(wpsq)) == 1
636 && square_distance(wksq, bksq) > 2)
637 return ScaleFactor(24 - 2 * square_distance(wksq, bksq));
639 return SCALE_FACTOR_NONE;
643 /// KRPPKRPScalingFunction scales KRPP vs KRP endgames. There is only a
644 /// single pattern: If the stronger side has no pawns and the defending king
645 /// is actively placed, the position is drawish.
647 ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) {
649 assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
650 assert(pos.piece_count(strongerSide, PAWN) == 2);
651 assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
652 assert(pos.piece_count(weakerSide, PAWN) == 1);
654 Square wpsq1 = pos.piece_list(strongerSide, PAWN, 0);
655 Square wpsq2 = pos.piece_list(strongerSide, PAWN, 1);
656 Square bksq = pos.king_square(weakerSide);
658 // Does the stronger side have a passed pawn?
659 if ( pos.pawn_is_passed(strongerSide, wpsq1)
660 || pos.pawn_is_passed(strongerSide, wpsq2))
661 return SCALE_FACTOR_NONE;
663 Rank r = Max(relative_rank(strongerSide, wpsq1), relative_rank(strongerSide, wpsq2));
665 if ( file_distance(bksq, wpsq1) <= 1
666 && file_distance(bksq, wpsq2) <= 1
667 && relative_rank(strongerSide, bksq) > r)
670 case RANK_2: return ScaleFactor(10);
671 case RANK_3: return ScaleFactor(10);
672 case RANK_4: return ScaleFactor(15);
673 case RANK_5: return ScaleFactor(20);
674 case RANK_6: return ScaleFactor(40);
675 default: assert(false);
678 return SCALE_FACTOR_NONE;
682 /// KPsKScalingFunction scales endgames with king and two or more pawns
683 /// against king. There is just a single rule here: If all pawns are on
684 /// the same rook file and are blocked by the defending king, it's a draw.
686 ScaleFactor KPsKScalingFunction::apply(const Position &pos) {
688 assert(pos.non_pawn_material(strongerSide) == Value(0));
689 assert(pos.piece_count(strongerSide, PAWN) >= 2);
690 assert(pos.non_pawn_material(weakerSide) == Value(0));
691 assert(pos.piece_count(weakerSide, PAWN) == 0);
693 Bitboard pawns = pos.pawns(strongerSide);
695 // Are all pawns on the 'a' file?
696 if ((pawns & ~FileABB) == EmptyBoardBB)
698 // Does the defending king block the pawns?
699 Square ksq = pos.king_square(weakerSide);
700 if (square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1)
701 return ScaleFactor(0);
702 else if( square_file(ksq) == FILE_A
703 && (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB)
704 return ScaleFactor(0);
706 return SCALE_FACTOR_NONE;
708 // Are all pawns on the 'h' file?
709 else if ((pawns & ~FileHBB) == EmptyBoardBB)
711 // Does the defending king block the pawns?
712 Square ksq = pos.king_square(weakerSide);
713 if (square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1)
714 return ScaleFactor(0);
715 else if ( square_file(ksq) == FILE_H
716 && (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB)
717 return ScaleFactor(0);
719 return SCALE_FACTOR_NONE;
722 return SCALE_FACTOR_NONE;
726 /// KBPKBScalingFunction scales KBP vs KB endgames. There are two rules:
727 /// If the defending king is somewhere along the path of the pawn, and the
728 /// square of the king is not of the same color as the stronger side's bishop,
729 /// it's a draw. If the two bishops have opposite color, it's almost always
732 ScaleFactor KBPKBScalingFunction::apply(const Position &pos) {
734 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
735 assert(pos.piece_count(strongerSide, BISHOP) == 1);
736 assert(pos.piece_count(strongerSide, PAWN) == 1);
737 assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
738 assert(pos.piece_count(weakerSide, BISHOP) == 1);
739 assert(pos.piece_count(weakerSide, PAWN) == 0);
741 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
742 Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
743 Square weakerBishopSq = pos.piece_list(weakerSide, BISHOP, 0);
744 Square weakerKingSq = pos.king_square(weakerSide);
746 // Case 1: Defending king blocks the pawn, and cannot be driven away
747 if ( square_file(weakerKingSq) == square_file(pawnSq)
748 && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
749 && ( square_color(weakerKingSq) != square_color(strongerBishopSq)
750 || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
751 return ScaleFactor(0);
753 // Case 2: Opposite colored bishops
754 if (square_color(strongerBishopSq) != square_color(weakerBishopSq))
756 // We assume that the position is drawn in the following three situations:
758 // a. The pawn is on rank 5 or further back.
759 // b. The defending king is somewhere in the pawn's path.
760 // c. The defending bishop attacks some square along the pawn's path,
761 // and is at least three squares away from the pawn.
763 // These rules are probably not perfect, but in practice they work
766 if (relative_rank(strongerSide, pawnSq) <= RANK_5)
767 return ScaleFactor(0);
770 Bitboard ray = ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S);
771 if (ray & pos.kings(weakerSide))
772 return ScaleFactor(0);
773 if( (pos.piece_attacks<BISHOP>(weakerBishopSq) & ray)
774 && square_distance(weakerBishopSq, pawnSq) >= 3)
775 return ScaleFactor(0);
778 return SCALE_FACTOR_NONE;
782 /// KBPKNScalingFunction scales KBP vs KN endgames. There is a single rule:
783 /// If the defending king is somewhere along the path of the pawn, and the
784 /// square of the king is not of the same color as the stronger side's bishop,
787 ScaleFactor KBPKNScalingFunction::apply(const Position &pos) {
789 assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
790 assert(pos.piece_count(strongerSide, BISHOP) == 1);
791 assert(pos.piece_count(strongerSide, PAWN) == 1);
792 assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
793 assert(pos.piece_count(weakerSide, KNIGHT) == 1);
794 assert(pos.piece_count(weakerSide, PAWN) == 0);
796 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
797 Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
798 Square weakerKingSq = pos.king_square(weakerSide);
800 if ( square_file(weakerKingSq) == square_file(pawnSq)
801 && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
802 && ( square_color(weakerKingSq) != square_color(strongerBishopSq)
803 || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
804 return ScaleFactor(0);
806 return SCALE_FACTOR_NONE;
810 /// KNPKScalingFunction scales KNP vs K endgames. There is a single rule:
811 /// If the pawn is a rook pawn on the 7th rank and the defending king prevents
812 /// the pawn from advancing, the position is drawn.
814 ScaleFactor KNPKScalingFunction::apply(const Position &pos) {
816 assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame);
817 assert(pos.piece_count(strongerSide, KNIGHT) == 1);
818 assert(pos.piece_count(strongerSide, PAWN) == 1);
819 assert(pos.non_pawn_material(weakerSide) == Value(0));
820 assert(pos.piece_count(weakerSide, PAWN) == 0);
822 Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
823 Square weakerKingSq = pos.king_square(weakerSide);
825 if ( pawnSq == relative_square(strongerSide, SQ_A7)
826 && square_distance(weakerKingSq, relative_square(strongerSide, SQ_A8)) <= 1)
827 return ScaleFactor(0);
829 if ( pawnSq == relative_square(strongerSide, SQ_H7)
830 && square_distance(weakerKingSq, relative_square(strongerSide, SQ_H8)) <= 1)
831 return ScaleFactor(0);
833 return SCALE_FACTOR_NONE;
837 /// KPKPScalingFunction scales KP vs KP endgames. This is done by removing
838 /// the weakest side's pawn and probing the KP vs K bitbase: If the weakest
839 /// side has a draw without the pawn, she probably has at least a draw with
840 /// the pawn as well. The exception is when the stronger side's pawn is far
841 /// advanced and not on a rook file; in this case it is often possible to win
842 /// (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1).
844 ScaleFactor KPKPScalingFunction::apply(const Position &pos) {
846 assert(pos.non_pawn_material(strongerSide) == Value(0));
847 assert(pos.non_pawn_material(weakerSide) == Value(0));
848 assert(pos.piece_count(WHITE, PAWN) == 1);
849 assert(pos.piece_count(BLACK, PAWN) == 1);
851 Square wksq, bksq, wpsq;
854 if (strongerSide == WHITE)
856 wksq = pos.king_square(WHITE);
857 bksq = pos.king_square(BLACK);
858 wpsq = pos.piece_list(WHITE, PAWN, 0);
859 stm = pos.side_to_move();
863 wksq = flip_square(pos.king_square(BLACK));
864 bksq = flip_square(pos.king_square(WHITE));
865 wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
866 stm = opposite_color(pos.side_to_move());
869 if (square_file(wpsq) >= FILE_E)
871 wksq = flop_square(wksq);
872 bksq = flop_square(bksq);
873 wpsq = flop_square(wpsq);
876 // If the pawn has advanced to the fifth rank or further, and is not a
877 // rook pawn, it's too dangerous to assume that it's at least a draw.
878 if ( square_rank(wpsq) >= RANK_5
879 && square_file(wpsq) != FILE_A)
880 return SCALE_FACTOR_NONE;
882 // Probe the KPK bitbase with the weakest side's pawn removed. If it's a
883 // draw, it's probably at least a draw even with the pawn.
884 if (probe_kpk(wksq, wpsq, bksq, stm))
885 return SCALE_FACTOR_NONE;
887 return ScaleFactor(0);
891 /// init_bitbases() is called during program initialization, and simply loads
892 /// bitbases from disk into memory. At the moment, there is only the bitbase
893 /// for KP vs K, but we may decide to add other bitbases later.
895 void init_bitbases() {
896 generate_kpk_bitbase(KPKBitbase);
902 // Probe the KP vs K bitbase:
904 int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm) {
906 int wp = int(square_file(wpsq)) + (int(square_rank(wpsq)) - 1) * 4;
907 int index = int(stm) + 2*int(bksq) + 128*int(wksq) + 8192*wp;
909 assert(index >= 0 && index < 24576*8);
910 return KPKBitbase[index/8] & (1 << (index&7));