Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Sat, 9 Feb 2019 23:39:54 +0000 (00:39 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sat, 9 Feb 2019 23:39:54 +0000 (00:39 +0100)
1  2 
src/endgame.cpp
src/endgame.h
src/evaluate.h
src/material.cpp

diff --cc src/endgame.cpp
Simple merge
diff --cc src/endgame.h
@@@ -121,10 -115,29 +122,35 @@@ class Endgames 
    std::pair<Map<Value>, Map<ScaleFactor>> maps;
  
  public:
-   Endgames();
+   Endgames() {
+     add<KPK>("KPK");
+     add<KNNK>("KNNK");
+     add<KBNK>("KBNK");
+     add<KRKP>("KRKP");
+     add<KRKB>("KRKB");
+     add<KRKN>("KRKN");
+     add<KQKP>("KQKP");
+     add<KQKR>("KQKR");
++    // Fairy piece endgames
++    add<KNSK>("KNSK");
++    add<KNFK>("KNFK");
++    add<KNSFKR>("KNSFKR");
++    add<KSFK>("KSFK");
++
+     add<KNPK>("KNPK");
+     add<KNPKB>("KNPKB");
+     add<KRPKR>("KRPKR");
+     add<KRPKB>("KRPKB");
+     add<KBPKB>("KBPKB");
+     add<KBPKN>("KBPKN");
+     add<KBPPKB>("KBPPKB");
+     add<KRPPKRP>("KRPPKRP");
+   }
  
    template<typename T>
-   EndgameBase<T>* probe(Key key) {
+   const EndgameBase<T>* probe(Key key) {
      return map<T>().count(key) ? map<T>()[key].get() : nullptr;
    }
  };
diff --cc src/evaluate.h
Simple merge
@@@ -144,99 -135,76 +144,99 @@@ Entry* probe(const Position& pos) 
    Value npm = std::max(EndgameLimit, std::min(npm_w + npm_b, MidgameLimit));
  
    // Map total non-pawn material into [PHASE_ENDGAME, PHASE_MIDGAME]
 -  e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
 -
 -  // Let's look if we have a specialized evaluation function for this particular
 -  // material configuration. Firstly we look for a fixed configuration one, then
 -  // for a generic one if the previous search failed.
 -  if ((e->evaluationFunction = pos.this_thread()->endgames.probe<Value>(key)) != nullptr)
 -      return e;
 -
 -  for (Color c = WHITE; c <= BLACK; ++c)
 -      if (is_KXK(pos, c))
 -      {
 -          e->evaluationFunction = &EvaluateKXK[c];
 -          return e;
 -      }
 -
 -  // OK, we didn't find any special evaluation function for the current material
 -  // configuration. Is there a suitable specialized scaling function?
 -  const EndgameBase<ScaleFactor>* sf;
 -
 -  if ((sf = pos.this_thread()->endgames.probe<ScaleFactor>(key)) != nullptr)
 +  if (pos.captures_to_hand())
    {
 -      e->scalingFunction[sf->strongSide] = sf; // Only strong color assigned
 -      return e;
 +      npm = VALUE_ZERO;
 +      for (PieceType pt : pos.piece_types())
 +          npm += (pos.count_in_hand(WHITE, pt) + pos.count_in_hand(BLACK, pt)) * PieceValue[MG][make_piece(WHITE, pt)];
 +      e->gamePhase = Phase(PHASE_MIDGAME * (MidgameLimit - std::min(npm, MidgameLimit)) / MidgameLimit);
    }
 -
 -  // We didn't find any specialized scaling function, so fall back on generic
 -  // ones that refer to more than one material distribution. Note that in this
 -  // case we don't return after setting the function.
 -  for (Color c = WHITE; c <= BLACK; ++c)
 +  else
 +      e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
 +
 +#ifdef LARGEBOARDS
 +  // Disable endgame evaluation until it works independent of board size
 +  if (false)
 +#else
 +  if (pos.endgame_eval())
 +#endif
    {
 -    if (is_KBPsK(pos, c))
 -        e->scalingFunction[c] = &ScaleKBPsK[c];
 -
 -    else if (is_KQKRPs(pos, c))
 -        e->scalingFunction[c] = &ScaleKQKRPs[c];
 -  }
 +      // Let's look if we have a specialized evaluation function for this particular
 +      // material configuration. Firstly we look for a fixed configuration one, then
 +      // for a generic one if the previous search failed.
 +      if ((e->evaluationFunction = pos.this_thread()->endgames.probe<Value>(key)) != nullptr)
 +          return e;
  
 -  if (npm_w + npm_b == VALUE_ZERO && pos.pieces(PAWN)) // Only pawns on the board
 -  {
 -      if (!pos.count<PAWN>(BLACK))
 +      for (Color c = WHITE; c <= BLACK; ++c)
 +          if (is_KFsPsK(pos, c))
 +          {
 +              e->evaluationFunction = &EvaluateKFsPsK[c];
 +              return e;
 +          }
 +
 +      for (Color c = WHITE; c <= BLACK; ++c)
 +          if (is_KXK(pos, c))
 +          {
 +              e->evaluationFunction = &EvaluateKXK[c];
 +              return e;
 +          }
 +
 +      // OK, we didn't find any special evaluation function for the current material
 +      // configuration. Is there a suitable specialized scaling function?
-       EndgameBase<ScaleFactor>* sf;
++      const EndgameBase<ScaleFactor>* sf;
 +
 +      if ((sf = pos.this_thread()->endgames.probe<ScaleFactor>(key)) != nullptr)
        {
 -          assert(pos.count<PAWN>(WHITE) >= 2);
 -
 -          e->scalingFunction[WHITE] = &ScaleKPsK[WHITE];
 +          e->scalingFunction[sf->strongSide] = sf; // Only strong color assigned
 +          return e;
        }
 -      else if (!pos.count<PAWN>(WHITE))
 +
 +      // We didn't find any specialized scaling function, so fall back on generic
 +      // ones that refer to more than one material distribution. Note that in this
 +      // case we don't return after setting the function.
 +      for (Color c = WHITE; c <= BLACK; ++c)
        {
 -          assert(pos.count<PAWN>(BLACK) >= 2);
 +        if (is_KBPsK(pos, c))
 +            e->scalingFunction[c] = &ScaleKBPsK[c];
  
 -          e->scalingFunction[BLACK] = &ScaleKPsK[BLACK];
 +        else if (is_KQKRPs(pos, c))
 +            e->scalingFunction[c] = &ScaleKQKRPs[c];
        }
 -      else if (pos.count<PAWN>(WHITE) == 1 && pos.count<PAWN>(BLACK) == 1)
 +
 +      if (npm_w + npm_b == VALUE_ZERO && pos.pieces(PAWN)) // Only pawns on the board
        {
 -          // This is a special case because we set scaling functions
 -          // for both colors instead of only one.
 -          e->scalingFunction[WHITE] = &ScaleKPKP[WHITE];
 -          e->scalingFunction[BLACK] = &ScaleKPKP[BLACK];
 +          if (!pos.count<PAWN>(BLACK))
 +          {
 +              assert(pos.count<PAWN>(WHITE) >= 2);
 +
 +              e->scalingFunction[WHITE] = &ScaleKPsK[WHITE];
 +          }
 +          else if (!pos.count<PAWN>(WHITE))
 +          {
 +              assert(pos.count<PAWN>(BLACK) >= 2);
 +
 +              e->scalingFunction[BLACK] = &ScaleKPsK[BLACK];
 +          }
 +          else if (pos.count<PAWN>(WHITE) == 1 && pos.count<PAWN>(BLACK) == 1)
 +          {
 +              // This is a special case because we set scaling functions
 +              // for both colors instead of only one.
 +              e->scalingFunction[WHITE] = &ScaleKPKP[WHITE];
 +              e->scalingFunction[BLACK] = &ScaleKPKP[BLACK];
 +          }
        }
 -  }
  
 -  // Zero or just one pawn makes it difficult to win, even with a small material
 -  // advantage. This catches some trivial draws like KK, KBK and KNK and gives a
 -  // drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN).
 -  if (!pos.count<PAWN>(WHITE) && npm_w - npm_b <= BishopValueMg)
 -      e->factor[WHITE] = uint8_t(npm_w <  RookValueMg   ? SCALE_FACTOR_DRAW :
 -                                 npm_b <= BishopValueMg ? 4 : 14);
 +      // Zero or just one pawn makes it difficult to win, even with a small material
 +      // advantage. This catches some trivial draws like KK, KBK and KNK and gives a
 +      // drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN).
 +      if (!pos.count<PAWN>(WHITE) && npm_w - npm_b <= BishopValueMg)
 +          e->factor[WHITE] = uint8_t(npm_w <  RookValueMg   ? SCALE_FACTOR_DRAW :
 +                                    npm_b <= BishopValueMg ? 4 : 14);
  
 -  if (!pos.count<PAWN>(BLACK) && npm_b - npm_w <= BishopValueMg)
 -      e->factor[BLACK] = uint8_t(npm_b <  RookValueMg   ? SCALE_FACTOR_DRAW :
 -                                 npm_w <= BishopValueMg ? 4 : 14);
 +      if (!pos.count<PAWN>(BLACK) && npm_b - npm_w <= BishopValueMg)
 +          e->factor[BLACK] = uint8_t(npm_b <  RookValueMg   ? SCALE_FACTOR_DRAW :
 +                                    npm_w <= BishopValueMg ? 4 : 14);
 +  }
  
    // Evaluate the material imbalance. We use PIECE_TYPE_NONE as a place holder
    // for the bishop pair "extended piece", which allows us to be more flexible