Subversion Repositories Games.Chess Giants

Rev

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-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
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
  const int PushToEdges[SQUARE_NB] = {
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
  const int PushToCorners[SQUARE_NB] = {
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
  const int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
59
  constexpr int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
60
  const int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 };
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
  const int KRPPKRPScaleFactors[RANK_NB] = { 0, 9, 10, 14, 21, 44, 0, 0 };
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 (wksq < psq && file_of(wksq) == file_of(psq))
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.  The
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
      // reasonably well.
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