Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 28 Jun 2020 13:13:34 +0000 (15:13 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 28 Jun 2020 13:13:34 +0000 (15:13 +0200)
No functional change.

1  2 
src/Makefile
src/bitboard.h
src/endgame.cpp
src/evaluate.cpp
src/evaluate.h
src/psqt.cpp
src/search.cpp
src/types.h

diff --cc src/Makefile
@@@ -422,13 -407,9 +422,13 @@@ help
        @echo "make build ARCH=x86-64 COMP=clang"
        @echo "make profile-build ARCH=x86-64-bmi2 COMP=gcc COMPCXX=g++-4.8"
        @echo ""
 +      @echo "Version for large boards (only GCC and mingw, 64-bit required): "
 +      @echo ""
 +      @echo "make build ARCH=x86-64 COMP=gcc largeboards=yes"
 +      @echo ""
  
  
- .PHONY: help build profile-build strip install clean objclean profileclean help \
+ .PHONY: help build profile-build strip install clean objclean profileclean \
          config-sanity icc-profile-use icc-profile-make gcc-profile-use gcc-profile-make \
          clang-profile-use clang-profile-make
  
diff --cc src/bitboard.h
@@@ -140,17 -102,11 +140,24 @@@ struct Magic 
    }
  };
  
 -extern Magic RookMagics[SQUARE_NB];
 +extern Magic RookMagicsH[SQUARE_NB];
 +extern Magic RookMagicsV[SQUARE_NB];
  extern Magic BishopMagics[SQUARE_NB];
 +extern Magic CannonMagicsH[SQUARE_NB];
 +extern Magic CannonMagicsV[SQUARE_NB];
 +extern Magic HorseMagics[SQUARE_NB];
 +extern Magic ElephantMagics[SQUARE_NB];
 +extern Magic JanggiElephantMagics[SQUARE_NB];
 +
++constexpr Bitboard make_bitboard() { return 0; }
++
++template<typename ...Squares>
++constexpr Bitboard make_bitboard(Square s, Squares... squares) {
++  return (Bitboard(1) << s) | make_bitboard(squares...);
++}
  inline Bitboard square_bb(Square s) {
 -  assert(s >= SQ_A1 && s <= SQ_H8);
 +  assert(s >= SQ_A1 && s <= SQ_MAX);
    return SquareBB[s];
  }
  
diff --cc src/endgame.cpp
Simple merge
@@@ -134,30 -126,27 +134,31 @@@ namespace 
      S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
    };
  
 +  // KingProximity contains a penalty according to distance from king
 +  constexpr Score KingProximity = S(1, 3);
 +  constexpr Score EndgameKingProximity = S(0, 10);
 +
    // Assorted bonuses and penalties
-   constexpr Score BishopPawns        = S(  3,  7);
-   constexpr Score CorneredBishop     = S( 50, 50);
-   constexpr Score FlankAttacks       = S(  8,  0);
-   constexpr Score Hanging            = S( 69, 36);
-   constexpr Score KingProtector      = S(  7,  8);
-   constexpr Score KnightOnQueen      = S( 16, 12);
-   constexpr Score LongDiagonalBishop = S( 45,  0);
-   constexpr Score MinorBehindPawn    = S( 18,  3);
-   constexpr Score Outpost            = S( 30, 21);
-   constexpr Score PassedFile         = S( 11,  8);
-   constexpr Score PawnlessFlank      = S( 17, 95);
-   constexpr Score RestrictedPiece    = S(  7,  7);
-   constexpr Score RookOnQueenFile    = S(  7,  6);
-   constexpr Score SliderOnQueen      = S( 59, 18);
-   constexpr Score ThreatByKing       = S( 24, 89);
-   constexpr Score ThreatByPawnPush   = S( 48, 39);
-   constexpr Score ThreatBySafePawn   = S(173, 94);
-   constexpr Score TrappedRook        = S( 52, 10);
-   constexpr Score WeakQueen          = S( 49, 15);
+   constexpr Score BishopPawns         = S(  3,  7);
+   constexpr Score CorneredBishop      = S( 50, 50);
+   constexpr Score FlankAttacks        = S(  8,  0);
+   constexpr Score Hanging             = S( 69, 36);
+   constexpr Score KingProtector       = S(  7,  8);
+   constexpr Score KnightOnQueen       = S( 16, 12);
+   constexpr Score LongDiagonalBishop  = S( 45,  0);
+   constexpr Score MinorBehindPawn     = S( 18,  3);
+   constexpr Score Outpost             = S( 30, 21);
+   constexpr Score PassedFile          = S( 11,  8);
+   constexpr Score PawnlessFlank       = S( 17, 95);
+   constexpr Score RestrictedPiece     = S(  7,  7);
+   constexpr Score RookOnQueenFile     = S(  7,  6);
+   constexpr Score SliderOnQueen       = S( 59, 18);
+   constexpr Score ThreatByKing        = S( 24, 89);
+   constexpr Score ThreatByPawnPush    = S( 48, 39);
+   constexpr Score ThreatBySafePawn    = S(173, 94);
+   constexpr Score TrappedRook         = S( 52, 10);
+   constexpr Score WeakQueen           = S( 49, 15);
+   constexpr Score WeakQueenProtection = S( 14,  0);
  
  #undef S
  
          Trace::add(TOTAL, score);
      }
  
-     return  (pos.side_to_move() == WHITE ? v : -v) // Side to move point of view
-            + Eval::tempo_value(pos);
 -    return  (pos.side_to_move() == WHITE ? v : -v) + Tempo; // Side to move point of view
++    return  (pos.side_to_move() == WHITE ? v : -v) + Eval::tempo_value(pos); // Side to move point of view
    }
  
  } // namespace
diff --cc src/evaluate.h
@@@ -29,11 -29,8 +29,9 @@@ class Position
  
  namespace Eval {
  
- constexpr Value Tempo = Value(28); // Must be visible to search
  std::string trace(const Position& pos);
  
 +Value tempo_value(const Position& pos);
  Value evaluate(const Position& pos);
  }
  
diff --cc src/psqt.cpp
  #include <algorithm>
  
  #include "types.h"
 +#include "piece.h"
 +#include "variant.h"
  
- Value PieceValue[PHASE_NB][PIECE_NB] = {
-   { VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg,
-     FersValueMg, AlfilValueMg, FersAlfilValueMg, SilverValueMg, AiwokValueMg, BersValueMg,
-     ArchbishopValueMg, ChancellorValueMg, AmazonValueMg, KnibisValueMg, BiskniValueMg, KnirooValueMg, RookniValueMg,
-     ShogiPawnValueMg, LanceValueMg, ShogiKnightValueMg, EuroShogiKnightValueMg, GoldValueMg, DragonHorseValueMg,
-     ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg,
-     CannonPieceValueMg, JanggiCannonPieceValueMg, SoldierValueMg, HorseValueMg, ElephantValueMg, JanggiElephantValueMg, BannerValueMg,
-     WazirValueMg, CommonerValueMg, CentaurValueMg },
-   { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg,
-     FersValueEg, AlfilValueEg, FersAlfilValueEg, SilverValueEg, AiwokValueEg, BersValueEg,
-     ArchbishopValueMg, ChancellorValueEg, AmazonValueEg, KnibisValueMg, BiskniValueMg, KnirooValueEg, RookniValueEg,
-     ShogiPawnValueEg, LanceValueEg, ShogiKnightValueEg, EuroShogiKnightValueEg, GoldValueEg, DragonHorseValueEg,
-     ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg,
-     CannonPieceValueEg, JanggiCannonPieceValueEg, SoldierValueEg, HorseValueEg, ElephantValueEg, JanggiElephantValueEg, BannerValueEg,
-     WazirValueEg, CommonerValueEg, CentaurValueEg }
- };
  namespace PSQT {
  
  #define S(mg, eg) make_score(mg, eg)
@@@ -123,97 -103,19 +106,94 @@@ Score psq[PIECE_NB][SQUARE_NB + 1]
  // init() initializes piece-square tables: the white halves of the tables are
  // copied from Bonus[] adding the piece value, then the black halves of the
  // tables are initialized by flipping and changing the sign of the white scores.
 -void init() {
 +void init(const Variant* v) {
  
 -  for (Piece pc = W_PAWN; pc <= W_KING; ++pc)
 +  PieceType strongestPiece = NO_PIECE_TYPE;
 +  for (PieceType pt : v->pieceTypes)
 +      if (PieceValue[MG][pt] > PieceValue[MG][strongestPiece])
 +          strongestPiece = pt;
 +
 +  Value maxPromotion = VALUE_ZERO;
 +  for (PieceType pt : v->promotionPieceTypes)
 +      maxPromotion = std::max(maxPromotion, PieceValue[EG][pt]);
 +
 +  for (PieceType pt = PAWN; pt <= KING; ++pt)
    {
 +      Piece pc = make_piece(WHITE, pt);
 +
-       PieceValue[MG][~pc] = PieceValue[MG][pc];
-       PieceValue[EG][~pc] = PieceValue[EG][pc];
        Score score = make_score(PieceValue[MG][pc], PieceValue[EG][pc]);
  
 -      for (Square s = SQ_A1; s <= SQ_H8; ++s)
 +      // Consider promotion types in pawn score
 +      if (pt == PAWN)
 +          score -= make_score(0, (QueenValueEg - maxPromotion) / 100);
 +
 +      // Scale slider piece values with board size
 +      const PieceInfo* pi = pieceMap.find(pt)->second;
 +      bool isSlider = pi->sliderQuiet.size() || pi->sliderCapture.size() || pi->hopperQuiet.size() || pi->hopperCapture.size();
 +      bool isPawn = !isSlider && pi->stepsQuiet.size() && !std::any_of(pi->stepsQuiet.begin(), pi->stepsQuiet.end(), [](Direction d) { return d < SOUTH / 2; });
 +      bool isSlowLeaper = !isSlider && !std::any_of(pi->stepsQuiet.begin(), pi->stepsQuiet.end(), [](Direction d) { return dist(d) > 1; });
 +
 +      if (isSlider)
 +      {
 +          constexpr int lc = 5;
 +          constexpr int rm = 5;
 +          constexpr int r0 = rm + RANK_8;
 +          int r1 = rm + (v->maxRank + v->maxFile) / 2;
 +          int leaper = pi->stepsQuiet.size() + pi->stepsCapture.size();
 +          int slider = pi->sliderQuiet.size() + pi->sliderCapture.size() + pi->hopperQuiet.size() + pi->hopperCapture.size();
 +          score = make_score(mg_value(score) * (lc * leaper + r1 * slider) / (lc * leaper + r0 * slider),
 +                             eg_value(score) * (lc * leaper + r1 * slider) / (lc * leaper + r0 * slider));
 +      }
 +
 +      // Increase leapers' value in makpong
 +      if (v->makpongRule)
 +      {
 +          if (std::any_of(pi->stepsCapture.begin(), pi->stepsCapture.end(), [](Direction d) { return dist(d) > 1; })
 +                  && !pi->lameLeaper)
 +              score = make_score(mg_value(score) * 4200 / (3500 + mg_value(score)),
 +                                 eg_value(score) * 4700 / (3500 + mg_value(score)));
 +      }
 +
 +      // For drop variants, halve the piece values
 +      if (v->capturesToHand)
 +          score = make_score(mg_value(score) * 3500 / (7000 + mg_value(score)),
 +                             eg_value(score) * 3500 / (7000 + eg_value(score)));
 +      else if (!v->checking)
 +          score = make_score(mg_value(score) * 2000 / (3500 + mg_value(score)),
 +                             eg_value(score) * 2200 / (3500 + eg_value(score)));
 +      else if (v->twoBoards)
 +          score = make_score(mg_value(score) * 7000 / (7000 + mg_value(score)),
 +                             eg_value(score) * 7000 / (7000 + eg_value(score)));
 +      else if (v->checkCounting)
 +          score = make_score(mg_value(score) * (40000 + mg_value(score)) / 41000,
 +                             eg_value(score) * (30000 + eg_value(score)) / 31000);
 +      else if (pt == strongestPiece)
 +              score += make_score(std::max(QueenValueMg - PieceValue[MG][pt], VALUE_ZERO) / 20,
 +                                  std::max(QueenValueEg - PieceValue[EG][pt], VALUE_ZERO) / 20);
 +
 +      // For antichess variants, use negative piece values
 +      if (   v->extinctionValue == VALUE_MATE
 +          && v->extinctionPieceTypes.find(ALL_PIECES) != v->extinctionPieceTypes.end())
 +          score = -make_score(mg_value(score) / 8, eg_value(score) / 8 / (1 + !pi->sliderCapture.size()));
 +
 +      for (Square s = SQ_A1; s <= SQ_MAX; ++s)
        {
 -          File f = map_to_queenside(file_of(s));
 -          psq[ pc][ s] = score + (type_of(pc) == PAWN ? PBonus[rank_of(s)][file_of(s)]
 -                                                      : Bonus[pc][rank_of(s)][f]);
 -          psq[~pc][~s] = -psq[pc][s];
 +          File f = std::max(std::min(file_of(s), File(v->maxFile - file_of(s))), FILE_A);
 +          Rank r = rank_of(s);
 +          psq[ pc][ s] = score + (  pt == PAWN  ? PBonus[std::min(r, RANK_8)][std::min(file_of(s), FILE_H)]
 +                                  : pt == KING  ? KingBonus[std::min(r, RANK_8)][std::min(f, FILE_D)] * (1 + v->capturesToHand)
 +                                  : pt <= QUEEN ? Bonus[pc][std::min(r, RANK_8)][std::min(f, FILE_D)]
 +                                  : pt == HORSE ? Bonus[KNIGHT][std::min(r, RANK_8)][std::min(f, FILE_D)]
 +                                  : isSlider    ? make_score(5, 5) * (2 * f + std::max(std::min(r, Rank(v->maxRank - r)), RANK_1) - v->maxFile - 1)
 +                                  : isPawn      ? make_score(5, 5) * (2 * f - v->maxFile)
 +                                                : make_score(10, 10) * (1 + isSlowLeaper) * (f + std::max(std::min(r, Rank(v->maxRank - r)), RANK_1) - v->maxFile / 2));
 +          if (pt == SOLDIER && r < v->soldierPromotionRank)
 +              psq[pc][s] -= score * (v->soldierPromotionRank - r) / (4 + f);
 +          psq[~pc][rank_of(s) <= v->maxRank ? relative_square(BLACK, s, v->maxRank) : s] = -psq[pc][s];
        }
 +      // pieces in pocket
 +      psq[ pc][SQ_NONE] = score + make_score(45, 10);
 +      psq[~pc][SQ_NONE] = -psq[pc][SQ_NONE];
    }
  }
  
diff --cc src/search.cpp
@@@ -888,10 -826,7 +888,10 @@@ namespace 
  
      // Step 7. Razoring (~1 Elo)
      if (   !rootNode // The required rootNode PV handling is not available in qsearch
-         &&  depth < 2
+         &&  depth == 1
 +        && !pos.must_capture()
 +        && !pos.capture_the_flag_piece()
 +        && !pos.check_counting()
          &&  eval <= alpha - RazorMargin)
          return qsearch<NT>(pos, ss, alpha, beta);
  
diff --cc src/types.h
@@@ -321,38 -186,7 +321,39 @@@ enum Value : int 
    BishopValueMg = 825,   BishopValueEg = 915,
    RookValueMg   = 1276,  RookValueEg   = 1380,
    QueenValueMg  = 2538,  QueenValueEg  = 2682,
 +  FersValueMg              = 420,   FersValueEg              = 450,
 +  AlfilValueMg             = 350,   AlfilValueEg             = 330,
 +  FersAlfilValueMg         = 700,   FersAlfilValueEg         = 650,
 +  SilverValueMg            = 630,   SilverValueEg            = 630,
 +  AiwokValueMg             = 2300,  AiwokValueEg             = 2700,
 +  BersValueMg              = 2000,  BersValueEg              = 2000,
 +  ArchbishopValueMg        = 2200,  ArchbishopValueEg        = 2200,
 +  ChancellorValueMg        = 2300,  ChancellorValueEg        = 2600,
 +  AmazonValueMg            = 2700,  AmazonValueEg            = 2850,
 +  KnibisValueMg            = 1100,  KnibisValueEg            = 1200,
 +  BiskniValueMg            = 750,   BiskniValueEg            = 700,
 +  KnirooValueMg            = 1050,  KnirooValueEg            = 1250,
 +  RookniValueMg            = 800,   RookniValueEg            = 950,
 +  ShogiPawnValueMg         =  90,   ShogiPawnValueEg         = 100,
 +  LanceValueMg             = 350,   LanceValueEg             = 250,
 +  ShogiKnightValueMg       = 350,   ShogiKnightValueEg       = 300,
 +  EuroShogiKnightValueMg   = 400,   EuroShogiKnightValueEg   = 400,
 +  GoldValueMg              = 640,   GoldValueEg              = 640,
 +  DragonHorseValueMg       = 1500,  DragonHorseValueEg       = 1500,
 +  ClobberPieceValueMg      = 300,   ClobberPieceValueEg      = 300,
 +  BreakthroughPieceValueMg = 300,   BreakthroughPieceValueEg = 300,
 +  ImmobilePieceValueMg     = 100,   ImmobilePieceValueEg     = 100,
 +  CannonPieceValueMg       = 800,   CannonPieceValueEg       = 700,
 +  JanggiCannonPieceValueMg = 800,   JanggiCannonPieceValueEg = 600,
 +  SoldierValueMg           = 200,   SoldierValueEg           = 270,
 +  HorseValueMg             = 520,   HorseValueEg             = 800,
 +  ElephantValueMg          = 300,   ElephantValueEg          = 300,
 +  JanggiElephantValueMg    = 340,   JanggiElephantValueEg    = 350,
 +  BannerValueMg            = 3400,  BannerValueEg            = 3500,
 +  WazirValueMg             = 400,   WazirValueEg             = 350,
 +  CommonerValueMg          = 700,   CommonerValueEg          = 900,
 +  CentaurValueMg           = 1800,  CentaurValueEg           = 1900,
+   Tempo = 28,
  
    MidgameLimit  = 15258, EndgameLimit  = 3915
  };
@@@ -379,25 -199,18 +380,77 @@@ static_assert(2 * SQUARE_BITS + MOVE_TY
  
  enum Piece {
    NO_PIECE,
 -  W_PAWN = 1, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
 -  B_PAWN = 9, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
 -  PIECE_NB = 16
 +  PIECE_NB = 2 * PIECE_TYPE_NB
 +};
 +
 +enum RiderType {
 +  NO_RIDER = 0,
 +  RIDER_BISHOP = 1 << 0,
 +  RIDER_ROOK_H = 1 << 1,
 +  RIDER_ROOK_V = 1 << 2,
 +  RIDER_CANNON_H = 1 << 3,
 +  RIDER_CANNON_V = 1 << 4,
 +  RIDER_HORSE = 1 << 5,
 +  RIDER_ELEPHANT = 1 << 6,
 +  RIDER_JANGGI_ELEPHANT = 1 << 7,
 +  HOPPING_RIDERS = RIDER_CANNON_H | RIDER_CANNON_V,
 +  ASYMMETRICAL_RIDERS = RIDER_HORSE | RIDER_JANGGI_ELEPHANT,
  };
  
- extern Value PieceValue[PHASE_NB][PIECE_NB];
+ constexpr Value PieceValue[PHASE_NB][PIECE_NB] = {
 -  { VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg, VALUE_ZERO, VALUE_ZERO,
 -    VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg, VALUE_ZERO, VALUE_ZERO },
 -  { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg, VALUE_ZERO, VALUE_ZERO,
 -    VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg, VALUE_ZERO, VALUE_ZERO }
++  { VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg,
++    FersValueMg, AlfilValueMg, FersAlfilValueMg, SilverValueMg, AiwokValueMg, BersValueMg,
++    ArchbishopValueMg, ChancellorValueMg, AmazonValueMg, KnibisValueMg, BiskniValueMg, KnirooValueMg, RookniValueMg,
++    ShogiPawnValueMg, LanceValueMg, ShogiKnightValueMg, EuroShogiKnightValueMg, GoldValueMg, DragonHorseValueMg,
++    ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg,
++    CannonPieceValueMg, JanggiCannonPieceValueMg, SoldierValueMg, HorseValueMg, ElephantValueMg, JanggiElephantValueMg, BannerValueMg,
++    WazirValueMg, CommonerValueMg, CentaurValueMg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg,
++    FersValueMg, AlfilValueMg, FersAlfilValueMg, SilverValueMg, AiwokValueMg, BersValueMg,
++    ArchbishopValueMg, ChancellorValueMg, AmazonValueMg, KnibisValueMg, BiskniValueMg, KnirooValueMg, RookniValueMg,
++    ShogiPawnValueMg, LanceValueMg, ShogiKnightValueMg, EuroShogiKnightValueMg, GoldValueMg, DragonHorseValueMg,
++    ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg,
++    CannonPieceValueMg, JanggiCannonPieceValueMg, SoldierValueMg, HorseValueMg, ElephantValueMg, JanggiElephantValueMg, BannerValueMg,
++    WazirValueMg, CommonerValueMg, CentaurValueMg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO },
++  { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg,
++    FersValueEg, AlfilValueEg, FersAlfilValueEg, SilverValueEg, AiwokValueEg, BersValueEg,
++    ArchbishopValueMg, ChancellorValueEg, AmazonValueEg, KnibisValueMg, BiskniValueMg, KnirooValueEg, RookniValueEg,
++    ShogiPawnValueEg, LanceValueEg, ShogiKnightValueEg, EuroShogiKnightValueEg, GoldValueEg, DragonHorseValueEg,
++    ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg,
++    CannonPieceValueEg, JanggiCannonPieceValueEg, SoldierValueEg, HorseValueEg, ElephantValueEg, JanggiElephantValueEg, BannerValueEg,
++    WazirValueEg, CommonerValueEg, CentaurValueEg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg,
++    FersValueEg, AlfilValueEg, FersAlfilValueEg, SilverValueEg, AiwokValueEg, BersValueEg,
++    ArchbishopValueMg, ChancellorValueEg, AmazonValueEg, KnibisValueMg, BiskniValueMg, KnirooValueEg, RookniValueEg,
++    ShogiPawnValueEg, LanceValueEg, ShogiKnightValueEg, EuroShogiKnightValueEg, GoldValueEg, DragonHorseValueEg,
++    ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg,
++    CannonPieceValueEg, JanggiCannonPieceValueEg, SoldierValueEg, HorseValueEg, ElephantValueEg, JanggiElephantValueEg, BannerValueEg,
++    WazirValueEg, CommonerValueEg, CentaurValueEg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
++    VALUE_ZERO, VALUE_ZERO, VALUE_ZERO }
+ };
++static_assert(   PieceValue[MG][PIECE_TYPE_NB + 1] == PawnValueMg
++              && PieceValue[EG][PIECE_TYPE_NB + 1] == PawnValueEg, "PieceValue array broken");
 +
  typedef int Depth;
  
  enum : int {