Rev 169 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 169 | Rev 185 | ||
---|---|---|---|
Line 4... | Line 4... | ||
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
5 | Copyright (C) 2015- |
5 | Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad |
6 | 6 | ||
7 | Stockfish is free software: you can redistribute it and/or modify |
7 | Stockfish is free software: you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation, either version 3 of the License, or |
9 | the Free Software Foundation, either version 3 of the License, or |
10 | (at your option) any later version. |
10 | (at your option) any later version. |
Line 29... | Line 29... | ||
29 | 29 | ||
30 | namespace { |
30 | namespace { |
31 | 31 | ||
32 | // Table used to drive the king towards the edge of the board |
32 | // Table used to drive the king towards the edge of the board |
33 | // in KX vs K and KQ vs KR endgames. |
33 | // in KX vs K and KQ vs KR endgames. |
34 |
|
34 | constexpr int PushToEdges[SQUARE_NB] = { |
35 | 100, 90, 80, 70, 70, 80, 90, 100, |
35 | 100, 90, 80, 70, 70, 80, 90, 100, |
36 | 90, 70, 60, 50, 50, 60, 70, 90, |
36 | 90, 70, 60, 50, 50, 60, 70, 90, |
37 | 80, 60, 40, 30, 30, 40, 60, 80, |
37 | 80, 60, 40, 30, 30, 40, 60, 80, |
38 | 70, 50, 30, 20, 20, 30, 50, 70, |
38 | 70, 50, 30, 20, 20, 30, 50, 70, |
39 | 70, 50, 30, 20, 20, 30, 50, 70, |
39 | 70, 50, 30, 20, 20, 30, 50, 70, |
Line 42... | Line 42... | ||
42 | 100, 90, 80, 70, 70, 80, 90, 100 |
42 | 100, 90, 80, 70, 70, 80, 90, 100 |
43 | }; |
43 | }; |
44 | 44 | ||
45 | // Table used to drive the king towards a corner square of the |
45 | // Table used to drive the king towards a corner square of the |
46 | // right color in KBN vs K endgames. |
46 | // right color in KBN vs K endgames. |
47 |
|
47 | constexpr int PushToCorners[SQUARE_NB] = { |
48 | 200, 190, 180, 170, 160, 150, 140, 130, |
48 | 200, 190, 180, 170, 160, 150, 140, 130, |
49 | 190, 180, 170, 160, 150, 140, 130, 140, |
49 | 190, 180, 170, 160, 150, 140, 130, 140, |
50 | 180, 170, 155, 140, 140, 125, 140, 150, |
50 | 180, 170, 155, 140, 140, 125, 140, 150, |
51 | 170, 160, 140, 120, 110, 140, 150, 160, |
51 | 170, 160, 140, 120, 110, 140, 150, 160, |
52 | 160, 150, 140, 110, 120, 140, 160, 170, |
52 | 160, 150, 140, 110, 120, 140, 160, 170, |
Line 54... | Line 54... | ||
54 | 140, 130, 140, 150, 160, 170, 180, 190, |
54 | 140, 130, 140, 150, 160, 170, 180, 190, |
55 | 130, 140, 150, 160, 170, 180, 190, 200 |
55 | 130, 140, 150, 160, 170, 180, 190, 200 |
56 | }; |
56 | }; |
57 | 57 | ||
58 | // Tables used to drive a piece towards or away from another piece |
58 | // Tables used to drive a piece towards or away from another piece |
59 |
|
59 | constexpr int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 }; |
60 |
|
60 | constexpr int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 }; |
61 | 61 | ||
62 | // Pawn Rank based scaling factors used in KRPPKRP endgame |
62 | // Pawn Rank based scaling factors used in KRPPKRP endgame |
63 |
|
63 | constexpr int KRPPKRPScaleFactors[RANK_NB] = { 0, 9, 10, 14, 21, 44, 0, 0 }; |
64 | 64 | ||
65 | #ifndef NDEBUG |
65 | #ifndef NDEBUG |
66 | bool verify_material(const Position& pos, Color c, Value npm, int pawnsCnt) { |
66 | bool verify_material(const Position& pos, Color c, Value npm, int pawnsCnt) { |
67 | return pos.non_pawn_material(c) == npm && pos.count<PAWN>(c) == pawnsCnt; |
67 | return pos.non_pawn_material(c) == npm && pos.count<PAWN>(c) == pawnsCnt; |
68 | } |
68 | } |
Line 82... | Line 82... | ||
82 | 82 | ||
83 | return sq; |
83 | return sq; |
84 | } |
84 | } |
85 | 85 | ||
86 | } // namespace |
86 | } // namespace |
87 | - | ||
88 | - | ||
89 | /// Endgames members definitions |
- | |
90 | - | ||
91 | Endgames::Endgames() { |
- | |
92 | - | ||
93 | add<KPK>("KPK"); |
- | |
94 | add<KNNK>("KNNK"); |
- | |
95 | add<KBNK>("KBNK"); |
- | |
96 | add<KRKP>("KRKP"); |
- | |
97 | add<KRKB>("KRKB"); |
- | |
98 | add<KRKN>("KRKN"); |
- | |
99 | add<KQKP>("KQKP"); |
- | |
100 | add<KQKR>("KQKR"); |
- | |
101 | - | ||
102 | add<KNPK>("KNPK"); |
- | |
103 | add<KNPKB>("KNPKB"); |
- | |
104 | add<KRPKR>("KRPKR"); |
- | |
105 | add<KRPKB>("KRPKB"); |
- | |
106 | add<KBPKB>("KBPKB"); |
- | |
107 | add<KBPKN>("KBPKN"); |
- | |
108 | add<KBPPKB>("KBPPKB"); |
- | |
109 | add<KRPPKRP>("KRPPKRP"); |
- | |
110 | } |
- | |
111 | 87 | ||
112 | 88 | ||
113 | /// Mate with KX vs K. This function is used to evaluate positions with |
89 | /// Mate with KX vs K. This function is used to evaluate positions with |
114 | /// king and plenty of material vs a lone king. It simply gives the |
90 | /// king and plenty of material vs a lone king. It simply gives the |
115 | /// attacking side a bonus for driving the defending king towards the edge |
91 | /// attacking side a bonus for driving the defending king towards the edge |
Line 212... | Line 188... | ||
212 | 188 | ||
213 | Square queeningSq = make_square(file_of(psq), RANK_1); |
189 | Square queeningSq = make_square(file_of(psq), RANK_1); |
214 | Value result; |
190 | Value result; |
215 | 191 | ||
216 | // If the stronger side's king is in front of the pawn, it's a win |
192 | // If the stronger side's king is in front of the pawn, it's a win |
217 | if ( |
193 | if (forward_file_bb(WHITE, wksq) & psq) |
218 | result = RookValueEg - distance(wksq, psq); |
194 | result = RookValueEg - distance(wksq, psq); |
219 | 195 | ||
220 | // If the weaker side's king is too far from the pawn and the rook, |
196 | // If the weaker side's king is too far from the pawn and the rook, |
221 | // it's a win. |
197 | // it's a win. |
222 | else if ( distance(bksq, psq) >= 3 + (pos.side_to_move() == weakSide) |
198 | else if ( distance(bksq, psq) >= 3 + (pos.side_to_move() == weakSide) |
Line 238... | Line 214... | ||
238 | 214 | ||
239 | return strongSide == pos.side_to_move() ? result : -result; |
215 | return strongSide == pos.side_to_move() ? result : -result; |
240 | } |
216 | } |
241 | 217 | ||
242 | 218 | ||
243 | /// KR vs KB. This is very simple, and always returns drawish scores. |
219 | /// KR vs KB. This is very simple, and always returns drawish scores. The |
244 | /// score is slightly bigger when the defending king is close to the edge. |
220 | /// score is slightly bigger when the defending king is close to the edge. |
245 | template<> |
221 | template<> |
246 | Value Endgame<KRKB>::operator()(const Position& pos) const { |
222 | Value Endgame<KRKB>::operator()(const Position& pos) const { |
247 | 223 | ||
248 | assert(verify_material(pos, strongSide, RookValueMg, 0)); |
224 | assert(verify_material(pos, strongSide, RookValueMg, 0)); |
Line 629... | Line 605... | ||
629 | || relative_rank(strongSide, weakKingSq) <= RANK_6)) |
605 | || relative_rank(strongSide, weakKingSq) <= RANK_6)) |
630 | return SCALE_FACTOR_DRAW; |
606 | return SCALE_FACTOR_DRAW; |
631 | 607 | ||
632 | // Case 2: Opposite colored bishops |
608 | // Case 2: Opposite colored bishops |
633 | if (opposite_colors(strongBishopSq, weakBishopSq)) |
609 | if (opposite_colors(strongBishopSq, weakBishopSq)) |
634 | { |
- | |
635 | // We assume that the position is drawn in the following three situations: |
- | |
636 | // |
- | |
637 | // a. The pawn is on rank 5 or further back. |
- | |
638 | // b. The defending king is somewhere in the pawn's path. |
- | |
639 | // c. The defending bishop attacks some square along the pawn's path, |
- | |
640 | // and is at least three squares away from the pawn. |
- | |
641 | // |
- | |
642 | // These rules are probably not perfect, but in practice they work |
- | |
643 |
|
610 | return SCALE_FACTOR_DRAW; |
644 | 611 | ||
645 | if (relative_rank(strongSide, pawnSq) <= RANK_5) |
- | |
646 | return SCALE_FACTOR_DRAW; |
- | |
647 | - | ||
648 | Bitboard path = forward_file_bb(strongSide, pawnSq); |
- | |
649 | - | ||
650 | if (path & pos.pieces(weakSide, KING)) |
- | |
651 | return SCALE_FACTOR_DRAW; |
- | |
652 | - | ||
653 | if ( (pos.attacks_from<BISHOP>(weakBishopSq) & path) |
- | |
654 | && distance(weakBishopSq, pawnSq) >= 3) |
- | |
655 | return SCALE_FACTOR_DRAW; |
- | |
656 | } |
- | |
657 | return SCALE_FACTOR_NONE; |
612 | return SCALE_FACTOR_NONE; |
658 | } |
613 | } |
659 | 614 | ||
660 | 615 | ||
661 | /// KBPP vs KB. It detects a few basic draws with opposite-colored bishops |
616 | /// KBPP vs KB. It detects a few basic draws with opposite-colored bishops |