Subversion Repositories Games.Chess Giants

Rev

Rev 169 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  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-2015 Marco Costalba, Joona Kiiski, Tord Romstad
  5.   Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
  6.  
  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
  9.   the Free Software Foundation, either version 3 of the License, or
  10.   (at your option) any later version.
  11.  
  12.   Stockfish is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License
  18.   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19. */
  20.  
  21. #ifndef ENDGAME_H_INCLUDED
  22. #define ENDGAME_H_INCLUDED
  23.  
  24. #include <map>
  25. #include <memory>
  26. #include <string>
  27. #include <type_traits>
  28. #include <utility>
  29.  
  30. #include "position.h"
  31. #include "types.h"
  32.  
  33.  
  34. /// EndgameCode lists all supported endgame functions by corresponding codes
  35.  
  36. enum EndgameCode {
  37.  
  38.   EVALUATION_FUNCTIONS,
  39.   KNNK,  // KNN vs K
  40.   KXK,   // Generic "mate lone king" eval
  41.   KBNK,  // KBN vs K
  42.   KPK,   // KP vs K
  43.   KRKP,  // KR vs KP
  44.   KRKB,  // KR vs KB
  45.   KRKN,  // KR vs KN
  46.   KQKP,  // KQ vs KP
  47.   KQKR,  // KQ vs KR
  48.  
  49.   SCALING_FUNCTIONS,
  50.   KBPsK,   // KB and pawns vs K
  51.   KQKRPs,  // KQ vs KR and pawns
  52.   KRPKR,   // KRP vs KR
  53.   KRPKB,   // KRP vs KB
  54.   KRPPKRP, // KRPP vs KRP
  55.   KPsK,    // K and pawns vs K
  56.   KBPKB,   // KBP vs KB
  57.   KBPPKB,  // KBPP vs KB
  58.   KBPKN,   // KBP vs KN
  59.   KNPK,    // KNP vs K
  60.   KNPKB,   // KNP vs KB
  61.   KPKP     // KP vs KP
  62. };
  63.  
  64.  
  65. /// Endgame functions can be of two types depending on whether they return a
  66. /// Value or a ScaleFactor.
  67.  
  68. template<EndgameCode E> using
  69. eg_type = typename std::conditional<(E < SCALING_FUNCTIONS), Value, ScaleFactor>::type;
  70.  
  71.  
  72. /// Base and derived functors for endgame evaluation and scaling functions
  73.  
  74. template<typename T>
  75. struct EndgameBase {
  76.  
  77.   explicit EndgameBase(Color c) : strongSide(c), weakSide(~c) {}
  78.   virtual ~EndgameBase() = default;
  79.   virtual T operator()(const Position&) const = 0;
  80.  
  81.   const Color strongSide, weakSide;
  82. };
  83.  
  84.  
  85. template<EndgameCode E, typename T = eg_type<E>>
  86. struct Endgame : public EndgameBase<T> {
  87.  
  88.   explicit Endgame(Color c) : EndgameBase<T>(c) {}
  89.   T operator()(const Position&) const override;
  90. };
  91.  
  92.  
  93. /// The Endgames class stores the pointers to endgame evaluation and scaling
  94. /// base objects in two std::map. We use polymorphism to invoke the actual
  95. /// endgame function by calling its virtual operator().
  96.  
  97. class Endgames {
  98.  
  99.   template<typename T> using Ptr = std::unique_ptr<EndgameBase<T>>;
  100.   template<typename T> using Map = std::map<Key, Ptr<T>>;
  101.  
  102.   template<typename T>
  103.   Map<T>& map() {
  104.     return std::get<std::is_same<T, ScaleFactor>::value>(maps);
  105.   }
  106.  
  107.   template<EndgameCode E, typename T = eg_type<E>>
  108.   void add(const std::string& code) {
  109.  
  110.     StateInfo st;
  111.     map<T>()[Position().set(code, WHITE, &st).material_key()] = Ptr<T>(new Endgame<E>(WHITE));
  112.     map<T>()[Position().set(code, BLACK, &st).material_key()] = Ptr<T>(new Endgame<E>(BLACK));
  113.   }
  114.  
  115.   std::pair<Map<Value>, Map<ScaleFactor>> maps;
  116.  
  117. public:
  118.   Endgames() {
  119.  
  120.     add<KPK>("KPK");
  121.     add<KNNK>("KNNK");
  122.     add<KBNK>("KBNK");
  123.     add<KRKP>("KRKP");
  124.     add<KRKB>("KRKB");
  125.     add<KRKN>("KRKN");
  126.     add<KQKP>("KQKP");
  127.     add<KQKR>("KQKR");
  128.  
  129.     add<KNPK>("KNPK");
  130.     add<KNPKB>("KNPKB");
  131.     add<KRPKR>("KRPKR");
  132.     add<KRPKB>("KRPKB");
  133.     add<KBPKB>("KBPKB");
  134.     add<KBPKN>("KBPKN");
  135.     add<KBPPKB>("KBPPKB");
  136.     add<KRPPKRP>("KRPPKRP");
  137.   }
  138.  
  139.   template<typename T>
  140.   const EndgameBase<T>* probe(Key key) {
  141.     return map<T>().count(key) ? map<T>()[key].get() : nullptr;
  142.   }
  143. };
  144.  
  145. #endif // #ifndef ENDGAME_H_INCLUDED
  146.