From: Fabian Fichter Date: Sun, 28 Jun 2020 13:13:34 +0000 (+0200) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=3b15ec0b5542290da2639f1265d35a6ca0297564;p=fairystockfish.git Merge official-stockfish/master No functional change. --- 3b15ec0b5542290da2639f1265d35a6ca0297564 diff --cc src/Makefile index 98ee074,15ad635..041fff6 --- a/src/Makefile +++ b/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 index 307dac7,ca16148..f841214 --- a/src/bitboard.h +++ b/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 ++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/evaluate.cpp index 8ddc7c4,31272f2..319d68e --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@@ -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 @@@ -1163,8 -831,7 +1164,7 @@@ 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 index 44f0a05,7c8a2a6..c289736 --- a/src/evaluate.h +++ b/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 index f7ebd45,8bad7ed..9c44cd1 --- a/src/psqt.cpp +++ b/src/psqt.cpp @@@ -21,26 -21,7 +21,9 @@@ #include #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 index 274c385,7f6abf1..09d01a9 --- a/src/search.cpp +++ b/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(pos, ss, alpha, beta); diff --cc src/types.h index 2a02c91,58d05d2..3d8dd05 --- a/src/types.h +++ b/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 {