- /* 
-     Texel - A UCI chess engine. 
-     Copyright (C) 2012-2014  Peter Ă–sterlund, peterosterlund2@gmail.com 
-   
-     This program is free software: you can redistribute it and/or modify 
-     it under the terms of the GNU General Public License as published by 
-     the Free Software Foundation, either version 3 of the License, or 
-     (at your option) any later version. 
-   
-     This program is distributed in the hope that it will be useful, 
-     but WITHOUT ANY WARRANTY; without even the implied warranty of 
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
-     GNU General Public License for more details. 
-   
-     You should have received a copy of the GNU General Public License 
-     along with this program.  If not, see <http://www.gnu.org/licenses/>. 
- */ 
-   
- /* 
-  * evaluate.cpp 
-  * 
-  *  Created on: Feb 25, 2012 
-  *      Author: petero 
-  */ 
-   
- #include "evaluate.hpp" 
- #include "endGameEval.hpp" 
- #include <vector> 
-   
- int Evaluate::pieceValueOrder[Piece::nPieceTypes] = { 
-     0, 
-     5, 4, 3, 2, 2, 1, 
-     5, 4, 3, 2, 2, 1 
- }; 
-   
-   
- static const int empty[64] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 
-                                0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 
-                                0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 
-                                0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}; 
-   
- int Evaluate::castleMaskFactor[256]; 
-   
- static StaticInitializer<Evaluate> evInit; 
-   
-   
- /** Get bitboard mask for a square translated (dx,dy). Return 0 if square outside board. */ 
- static inline U64 getMask(int sq, int dx, int dy) { 
-     int x = Position::getX(sq) + dx; 
-     int y = Position::getY(sq) + dy; 
-     if (x >= 0 && x < 8 && y >= 0 && y < 8) 
-         return 1ULL << Position::getSquare(x, y); 
-     else 
-         return 0; 
- } 
-   
- void 
- Evaluate::staticInitialize() { 
-     psTab1[Piece::EMPTY]   = empty; 
-     psTab1[Piece::WKING]   = kt1w.getTable(); 
-     psTab1[Piece::WQUEEN]  = qt1w.getTable(); 
-     psTab1[Piece::WROOK]   = rt1w.getTable(); 
-     psTab1[Piece::WBISHOP] = bt1w.getTable(); 
-     psTab1[Piece::WKNIGHT] = nt1w.getTable(); 
-     psTab1[Piece::WPAWN]   = pt1w.getTable(); 
-     psTab1[Piece::BKING]   = kt1b.getTable(); 
-     psTab1[Piece::BQUEEN]  = qt1b.getTable(); 
-     psTab1[Piece::BROOK]   = rt1b.getTable(); 
-     psTab1[Piece::BBISHOP] = bt1b.getTable(); 
-     psTab1[Piece::BKNIGHT] = nt1b.getTable(); 
-     psTab1[Piece::BPAWN]   = pt1b.getTable(); 
-   
-     psTab2[Piece::EMPTY]   = empty; 
-     psTab2[Piece::WKING]   = kt2w.getTable(); 
-     psTab2[Piece::WQUEEN]  = qt2w.getTable(); 
-     psTab2[Piece::WROOK]   = rt1w.getTable(); 
-     psTab2[Piece::WBISHOP] = bt2w.getTable(); 
-     psTab2[Piece::WKNIGHT] = nt2w.getTable(); 
-     psTab2[Piece::WPAWN]   = pt2w.getTable(); 
-     psTab2[Piece::BKING]   = kt2b.getTable(); 
-     psTab2[Piece::BQUEEN]  = qt2b.getTable(); 
-     psTab2[Piece::BROOK]   = rt1b.getTable(); 
-     psTab2[Piece::BBISHOP] = bt2b.getTable(); 
-     psTab2[Piece::BKNIGHT] = nt2b.getTable(); 
-     psTab2[Piece::BPAWN]   = pt2b.getTable(); 
-   
-     // Initialize knight/bishop king safety patterns 
-     for (int sq = 0; sq < 64; sq++) { 
-         const int x = Position::getX(sq); 
-         const int y = Position::getY(sq); 
-         int dx = (x < 4) ? -1 : 1; 
-         int dy = (y < 4) ? 1 : -1; 
-         U64 n = getMask(sq, -dx, 0) | getMask(sq, dx, 0) | getMask(sq, 0, dy) | getMask(sq, 0, 2*dy) | getMask(sq, dx, 2*dy); 
-         U64 b = getMask(sq, -dx, 0) | getMask(sq, 0, dy) | getMask(sq, dx, 2*dy); 
-         knightKingProtectPattern[sq] = n; 
-         bishopKingProtectPattern[sq] = b; 
-     } 
- } 
-   
- void 
- Evaluate::updateEvalParams() { 
-     // Castle bonus 
-     for (int i = 0; i < 256; i++) { 
-         int h1Dist = 100; 
-         bool h1Castle = (i & (1<<7)) != 0; 
-         if (h1Castle) 
-             h1Dist = BitBoard::bitCount(i & BitBoard::sqMask(F1,G1)); 
-         int a1Dist = 100; 
-         bool a1Castle = (i & 1) != 0; 
-         if (a1Castle) 
-             a1Dist = BitBoard::bitCount(i & BitBoard::sqMask(B1,C1,D1)); 
-         int dist = std::min(a1Dist, h1Dist); 
-         castleMaskFactor[i] = dist < 4 ? castleFactor[dist] : 0; 
-     } 
-   
-     // Knight mobility scores 
-     for (int sq = 0; sq < 64; sq++) { 
-         int x = Position::getX(sq); 
-         int y = Position::getY(sq); 
-         if (x >= 4) x = 7 - x; 
-         if (y >= 4) y = 7 - y; 
-         if (x < y) std::swap(x, y); 
-         int maxMob = 0; 
-         switch (y*8+x) { 
-         case A1: maxMob = 2; break; 
-         case B1: maxMob = 3; break; 
-         case C1: maxMob = 4; break; 
-         case D1: maxMob = 4; break; 
-         case B2: maxMob = 4; break; 
-         case C2: maxMob = 6; break; 
-         case D2: maxMob = 6; break; 
-         case C3: maxMob = 8; break; 
-         case D3: maxMob = 8; break; 
-         case D4: maxMob = 8; break; 
-         default: 
-             assert(false); 
-         } 
-         for (int m = 0; m <= 8; m++) { 
-             int offs = 0; 
-             switch (maxMob) { 
-             case 2: offs = 0; break; 
-             case 3: offs = 3; break; 
-             case 4: offs = 7; break; 
-             case 6: offs = 12; break; 
-             case 8: offs = 19; break; 
-             } 
-             knightMobScoreA[sq][m] = knightMobScore[offs + std::min(m, maxMob)]; 
-         } 
-     } 
- } 
-   
- const int* Evaluate::psTab1[Piece::nPieceTypes]; 
- const int* Evaluate::psTab2[Piece::nPieceTypes]; 
-   
- int Evaluate::knightMobScoreA[64][9]; 
- U64 Evaluate::knightKingProtectPattern[64]; 
- U64 Evaluate::bishopKingProtectPattern[64]; 
-   
- Evaluate::Evaluate(EvalHashTables& et) 
-     : pawnHash(et.pawnHash), 
-       materialHash(et.materialHash), 
-       kingSafetyHash(et.kingSafetyHash), 
-       wKingZone(0), bKingZone(0), 
-       wKingAttacks(0), bKingAttacks(0), 
-       wAttacksBB(0), bAttacksBB(0), 
-       wPawnAttacks(0), bPawnAttacks(0) { 
- } 
-   
- int 
- Evaluate::evalPos(const Position& pos) { 
-     return evalPos<false>(pos); 
- } 
-   
- int 
- Evaluate::evalPosPrint(const Position& pos) { 
-     return evalPos<true>(pos); 
- } 
-   
- template <bool print> 
- inline int 
- Evaluate::evalPos(const Position& pos) { 
-     int score = materialScore(pos, print); 
-   
-     wKingAttacks = bKingAttacks = 0; 
-     wKingZone = BitBoard::kingAttacks[pos.getKingSq(true)]; wKingZone |= wKingZone << 8; 
-     bKingZone = BitBoard::kingAttacks[pos.getKingSq(false)]; bKingZone |= bKingZone >> 8; 
-     wAttacksBB = bAttacksBB = 0L; 
-   
-     U64 pawns = pos.pieceTypeBB(Piece::WPAWN); 
-     wPawnAttacks = ((pawns & BitBoard::maskBToHFiles) << 7) | 
-                    ((pawns & BitBoard::maskAToGFiles) << 9); 
-     pawns = pos.pieceTypeBB(Piece::BPAWN); 
-     bPawnAttacks = ((pawns & BitBoard::maskBToHFiles) >> 9) | 
-                    ((pawns & BitBoard::maskAToGFiles) >> 7); 
-   
-     score += pieceSquareEval(pos); 
-     if (print) std::cout << "eval pst    :" << score << std::endl; 
-     score += pawnBonus(pos); 
-     if (print) std::cout << "eval pawn   :" << score << std::endl; 
-     score += castleBonus(pos); 
-     if (print) std::cout << "eval castle :" << score << std::endl; 
-   
-     score += rookBonus(pos); 
-     if (print) std::cout << "eval rook   :" << score << std::endl; 
-     score += bishopEval(pos, score); 
-     if (print) std::cout << "eval bishop :" << score << std::endl; 
-     score += knightEval(pos); 
-     if (print) std::cout << "eval knight :" << score << std::endl; 
-     score += threatBonus(pos); 
-     if (print) std::cout << "eval threat :" << score << std::endl; 
-     score += protectBonus(pos); 
-     if (print) std::cout << "eval protect:" << score << std::endl; 
-     score += kingSafety(pos); 
-     if (print) std::cout << "eval king   :" << score << std::endl; 
-     if (mhd->endGame) 
-         score = EndGameEval::endGameEval<true>(pos, phd->passedPawns, score); 
-     if (print) std::cout << "eval endgame:" << score << std::endl; 
-     if (pos.pieceTypeBB(Piece::WPAWN, Piece::BPAWN)) { 
-         int hmc = clamp(pos.getHalfMoveClock() / 10, 0, 9); 
-         score = score * halfMoveFactor[hmc] / 128; 
-     } 
-     if (print) std::cout << "eval halfmove:" << score << std::endl; 
-     if (score > 0) { 
-         int nStale = BitBoard::bitCount(BitBoard::southFill(phd->stalePawns & pos.pieceTypeBB(Piece::WPAWN)) & 0xff); 
-         score = score * stalePawnFactor[nStale] / 128; 
-     } else if (score < 0) { 
-         int nStale = BitBoard::bitCount(BitBoard::southFill(phd->stalePawns & pos.pieceTypeBB(Piece::BPAWN)) & 0xff); 
-         score = score * stalePawnFactor[nStale] / 128; 
-     } 
-     if (print) std::cout << "eval staleP :" << score << std::endl; 
-   
-     if (!pos.isWhiteMove()) 
-         score = -score; 
-     return score; 
- } 
-   
- /** Compensate for the fact that many knights are stronger compared to queens 
-  * than what the default material scores would predict. */ 
- static inline int correctionNvsQ(int n, int q) { 
-     if (n <= q+1) 
-         return 0; 
-     int knightBonus = 0; 
-     if (q == 1) 
-         knightBonus = knightVsQueenBonus1; 
-     else if (q == 2) 
-         knightBonus = knightVsQueenBonus2; 
-     else if (q >= 3) 
-         knightBonus = knightVsQueenBonus3; 
-     int corr = knightBonus * (n - q - 1); 
-     return corr; 
- } 
-   
- void 
- Evaluate::computeMaterialScore(const Position& pos, MaterialHashData& mhd, bool print) const { 
-     // Compute material part of score 
-     int score = pos.wMtrl() - pos.bMtrl(); 
-     if (print) std::cout << "eval mtrlraw:" << score << std::endl; 
-     const int nWQ = BitBoard::bitCount(pos.pieceTypeBB(Piece::WQUEEN)); 
-     const int nBQ = BitBoard::bitCount(pos.pieceTypeBB(Piece::BQUEEN)); 
-     const int nWN = BitBoard::bitCount(pos.pieceTypeBB(Piece::WKNIGHT)); 
-     const int nBN = BitBoard::bitCount(pos.pieceTypeBB(Piece::BKNIGHT)); 
-     int wCorr = correctionNvsQ(nWN, nBQ); 
-     int bCorr = correctionNvsQ(nBN, nWQ); 
-     score += wCorr - bCorr; 
-     if (print) std::cout << "eval qncorr :" << score << std::endl; 
-     score += tradeBonus(pos, wCorr, bCorr); 
-     if (print) std::cout << "eval trade  :" << score << std::endl; 
-   
-     const int nWR = BitBoard::bitCount(pos.pieceTypeBB(Piece::WROOK)); 
-     const int nBR = BitBoard::bitCount(pos.pieceTypeBB(Piece::BROOK)); 
-     { // Redundancy of major pieces 
-         int wMajor = nWQ + nWR; 
-         int bMajor = nBQ + nBR; 
-         int w = std::min(wMajor, 3); 
-         int b = std::min(bMajor, 3); 
-         score += majorPieceRedundancy[w*4+b]; 
-     } 
-     if (print) std::cout << "eval majred :" << score << std::endl; 
-   
-     const int wMtrl = pos.wMtrl(); 
-     const int bMtrl = pos.bMtrl(); 
-     const int wMtrlPawns = pos.wMtrlPawns(); 
-     const int bMtrlPawns = pos.bMtrlPawns(); 
-     const int wMtrlNoPawns = wMtrl - wMtrlPawns; 
-     const int bMtrlNoPawns = bMtrl - bMtrlPawns; 
-   
-     // Handle imbalances 
-     const int nWB = BitBoard::bitCount(pos.pieceTypeBB(Piece::WBISHOP)); 
-     const int nBB = BitBoard::bitCount(pos.pieceTypeBB(Piece::BBISHOP)); 
-     const int nWP = BitBoard::bitCount(pos.pieceTypeBB(Piece::WPAWN)); 
-     const int nBP = BitBoard::bitCount(pos.pieceTypeBB(Piece::BPAWN)); 
-     { 
-         const int dQ = nWQ - nBQ; 
-         const int dR = nWR - nBR; 
-         const int dB = nWB - nBB; 
-         const int dN = nWN - nBN; 
-         int nMinor = nWB + nWN + nBB + nBN; 
-         if ((dQ == 1) && (dR == -2)) { 
-             score += QvsRRBonus[std::min(4, nMinor)]; 
-         } else if ((dQ == -1) && (dR == 2)) { 
-             score -= QvsRRBonus[std::min(4, nMinor)]; 
-         } 
-   
-         const int dP = nWP - nBP; 
-         if ((dR == 1) && (dB + dN == -1)) { 
-             score += RvsMBonus[clamp(dP, -3, 3)+3]; 
-             if (wMtrlNoPawns == rV && dB == -1 && dP == -1) 
-                 score += RvsBPBonus; 
-         } else if ((dR == -1) && (dB + dN == 1)) { 
-             score -= RvsMBonus[clamp(-dP, -3, 3)+3]; 
-             if (bMtrlNoPawns == rV && dB == 1 && dP == 1) 
-                 score -= RvsBPBonus; 
-         } 
-   
-         if ((dR == 1) && (dB + dN == -2)) { 
-             score += RvsMMBonus[clamp(dP, -3, 3)+3]; 
-         } else if ((dR == -1) && (dB + dN == 2)) { 
-             score -= RvsMMBonus[clamp(-dP, -3, 3)+3]; 
-         } 
-   
-         if ((dQ == 1) && (dR == -1) && (dB + dN == -1)) { 
-             score += (nWR == 0) ? (int)QvsRMBonus1 : (int)QvsRMBonus2; // Pierre-Marie Baty -- added type cast 
-         } else if ((dQ == -1) && (dR == 1) && (dB + dN == 1)) { 
-             score -= (nBR == 0) ? (int)QvsRMBonus1 : (int)QvsRMBonus2; // Pierre-Marie Baty -- added type cast 
-         } 
-     } 
-     if (print) std::cout << "eval imbala :" << score << std::endl; 
-     mhd.id = pos.materialId(); 
-     mhd.score = score; 
-     mhd.endGame = EndGameEval::endGameEval<false>(pos, 0, 0); 
-   
-     // Compute interpolation factors 
-     { // Pawn 
-         const int loMtrl = pawnLoMtrl; 
-         const int hiMtrl = pawnHiMtrl; 
-         mhd.wPawnIPF = interpolate(bMtrlNoPawns, loMtrl, 0, hiMtrl, IPOLMAX); 
-         mhd.bPawnIPF = interpolate(wMtrlNoPawns, loMtrl, 0, hiMtrl, IPOLMAX); 
-         if (wCorr > 100) 
-             mhd.wPawnIPF = mhd.wPawnIPF * 100 / wCorr; 
-         if (bCorr > 100) 
-             mhd.bPawnIPF = mhd.bPawnIPF * 100 / bCorr; 
-     } 
-     { // Knight/bishop 
-         const int loMtrl = minorLoMtrl; 
-         const int hiMtrl = minorHiMtrl; 
-         mhd.wKnightIPF = interpolate(bMtrl, loMtrl, 0, hiMtrl, IPOLMAX); 
-         mhd.bKnightIPF = interpolate(wMtrl, loMtrl, 0, hiMtrl, IPOLMAX); 
-     } 
-     { // Castle 
-         const int loMtrl = castleLoMtrl; 
-         const int hiMtrl = castleHiMtrl; 
-         const int m = wMtrlNoPawns + bMtrlNoPawns; 
-         mhd.castleIPF = interpolate(m, loMtrl, 0, hiMtrl, IPOLMAX); 
-     } 
-     { 
-         const int loMtrl = queenLoMtrl; 
-         const int hiMtrl = queenHiMtrl; 
-         const int m = wMtrlNoPawns + bMtrlNoPawns; 
-         mhd.queenIPF = interpolate(m, loMtrl, 0, hiMtrl, IPOLMAX); 
-     } 
-     { // Passed pawn 
-         const int loMtrl = passedPawnLoMtrl; 
-         const int hiMtrl = passedPawnHiMtrl; 
-         mhd.wPassedPawnIPF = interpolate(bMtrlNoPawns-nBN*(nV/2), loMtrl, 0, hiMtrl, IPOLMAX); 
-         mhd.bPassedPawnIPF = interpolate(wMtrlNoPawns-nWN*(nV/2), loMtrl, 0, hiMtrl, IPOLMAX); 
-     } 
-     { // King safety 
-         const int loMtrl = kingSafetyLoMtrl; 
-         const int hiMtrl = kingSafetyHiMtrl; 
-         const int m = (wMtrlNoPawns + bMtrlNoPawns) / 2; 
-         mhd.kingSafetyIPF = interpolate(m, loMtrl, 0, hiMtrl, IPOLMAX); 
-         if (wCorr + bCorr > 200) 
-             mhd.kingSafetyIPF = mhd.kingSafetyIPF * 200 / (wCorr + bCorr); 
-     } 
-     { // Different color bishops 
-         const int loMtrl = oppoBishopLoMtrl; 
-         const int hiMtrl = oppoBishopHiMtrl; 
-         const int m = wMtrlNoPawns + bMtrlNoPawns; 
-         mhd.diffColorBishopIPF = interpolate(m, loMtrl, 0, hiMtrl, IPOLMAX); 
-     } 
-     { // Knight outpost 
-         const int loMtrl = knightOutpostLoMtrl; 
-         const int hiMtrl = knightOutpostHiMtrl; 
-         mhd.wKnightOutPostIPF = interpolate(bMtrlPawns, loMtrl, 0, hiMtrl, IPOLMAX); 
-         mhd.bKnightOutPostIPF = interpolate(wMtrlPawns, loMtrl, 0, hiMtrl, IPOLMAX); 
-     } 
- } 
-   
- int 
- Evaluate::tradeBonus(const Position& pos, int wCorr, int bCorr) const { 
-     const int wM = pos.wMtrl() + wCorr; 
-     const int bM = pos.bMtrl() + bCorr; 
-     const int wPawn = pos.wMtrlPawns(); 
-     const int bPawn = pos.bMtrlPawns(); 
-     const int deltaScore = wM - bM; 
-   
-     int pBonus = 0; 
-     pBonus += interpolate((deltaScore > 0) ? wPawn : bPawn, 0, -pawnTradePenalty * deltaScore / 100, pawnTradeThreshold, 0); 
-     pBonus += interpolate((deltaScore > 0) ? bM : wM, 0, pieceTradeBonus * deltaScore / 100, pieceTradeThreshold * 100, 0); 
-   
-     return pBonus; 
- } 
-   
- int 
- Evaluate::pieceSquareEval(const Position& pos) { 
-     int score = 0; 
-   
-     // Kings/pawns 
-     if (pos.wMtrlPawns() + pos.bMtrlPawns() > 0) { 
-         { 
-             const int k1 = pos.psScore1(Piece::WKING) + pos.psScore1(Piece::WPAWN); 
-             const int k2 = pos.psScore2(Piece::WKING) + pos.psScore2(Piece::WPAWN); 
-             score += interpolate(k2, k1, mhd->wPawnIPF); 
-         } 
-         { 
-             const int k1 = pos.psScore1(Piece::BKING) + pos.psScore1(Piece::BPAWN); 
-             const int k2 = pos.psScore2(Piece::BKING) + pos.psScore2(Piece::BPAWN); 
-             score -= interpolate(k2, k1, mhd->bPawnIPF); 
-         } 
-     } else { // Use symmetric tables if no pawns left 
-         if (pos.wMtrl() > pos.bMtrl()) 
-             score += EndGameEval::mateEval(pos.getKingSq(true), pos.getKingSq(false)); 
-         else if (pos.wMtrl() < pos.bMtrl()) 
-             score -= EndGameEval::mateEval(pos.getKingSq(false), pos.getKingSq(true)); 
-         else 
-             score += EndGameEval::winKingTable[pos.getKingSq(true)] - 
-                      EndGameEval::winKingTable[pos.getKingSq(false)]; 
-     } 
-   
-     // Knights/bishops 
-     { 
-         int n1 = pos.psScore1(Piece::WKNIGHT) + pos.psScore1(Piece::WBISHOP); 
-         int n2 = pos.psScore2(Piece::WKNIGHT) + pos.psScore2(Piece::WBISHOP); 
-         score += interpolate(n2, n1, mhd->wKnightIPF); 
-         n1 = pos.psScore1(Piece::BKNIGHT) + pos.psScore1(Piece::BBISHOP); 
-         n2 = pos.psScore2(Piece::BKNIGHT) + pos.psScore2(Piece::BBISHOP); 
-         score -= interpolate(n2, n1, mhd->bKnightIPF); 
-     } 
-   
-     // Queens 
-     { 
-         const U64 occupied = pos.occupiedBB(); 
-         int q1 = pos.psScore1(Piece::WQUEEN); 
-         int q2 = pos.psScore2(Piece::WQUEEN); 
-         score += interpolate(q2, q1, mhd->queenIPF); 
-         U64 m = pos.pieceTypeBB(Piece::WQUEEN); 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             U64 atk = BitBoard::rookAttacks(sq, occupied) | BitBoard::bishopAttacks(sq, occupied); 
-             wAttacksBB |= atk; 
-             score += queenMobScore[BitBoard::bitCount(atk & ~(pos.whiteBB() | bPawnAttacks))]; 
-             bKingAttacks += BitBoard::bitCount(atk & bKingZone) * 2; 
-         } 
-         q1 = pos.psScore1(Piece::BQUEEN); 
-         q2 = pos.psScore2(Piece::BQUEEN); 
-         score -= interpolate(q2, q1, mhd->queenIPF); 
-         m = pos.pieceTypeBB(Piece::BQUEEN); 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             U64 atk = BitBoard::rookAttacks(sq, occupied) | BitBoard::bishopAttacks(sq, occupied); 
-             bAttacksBB |= atk; 
-             score -= queenMobScore[BitBoard::bitCount(atk & ~(pos.blackBB() | wPawnAttacks))]; 
-             wKingAttacks += BitBoard::bitCount(atk & wKingZone) * 2; 
-         } 
-     } 
-   
-     // Rooks 
-     { 
-         int r1 = pos.psScore1(Piece::WROOK); 
-         if (r1 != 0) { 
-             const int nP = BitBoard::bitCount(pos.pieceTypeBB(Piece::BPAWN)); 
-             const int s = r1 * std::min(nP, 6) / 6; 
-             score += s; 
-         } 
-         r1 = pos.psScore1(Piece::BROOK); 
-         if (r1 != 0) { 
-             const int nP = BitBoard::bitCount(pos.pieceTypeBB(Piece::WPAWN)); 
-             const int s = r1 * std::min(nP, 6) / 6; 
-             score -= s; 
-         } 
-     } 
-   
-     return score; 
- } 
-   
- int 
- Evaluate::castleBonus(const Position& pos) { 
-     if (pos.getCastleMask() == 0) return 0; 
-   
-     const int k1 = kt1b[G8] - kt1b[E8]; 
-     const int k2 = kt2b[G8] - kt2b[E8]; 
-     const int ks = interpolate(k2, k1, mhd->castleIPF); 
-   
-     const int castleValue = ks + rt1b[F8] - rt1b[H8]; 
-     if (castleValue <= 0) 
-         return 0; 
-   
-     U64 occupied = pos.occupiedBB(); 
-     int tmp = (int) (occupied & BitBoard::sqMask(B1,C1,D1,F1,G1)); 
-     if (pos.a1Castle()) tmp |= 1; 
-     if (pos.h1Castle()) tmp |= (1 << 7); 
-     const int wBonus = (castleValue * castleMaskFactor[tmp]) >> 7; 
-   
-     tmp = (int) ((occupied >> 56) & BitBoard::sqMask(B1,C1,D1,F1,G1)); 
-     if (pos.a8Castle()) tmp |= 1; 
-     if (pos.h8Castle()) tmp |= (1 << 7); 
-     const int bBonus = (castleValue * castleMaskFactor[tmp]) >> 7; 
-   
-     return wBonus - bBonus; 
- } 
-   
- int 
- Evaluate::pawnBonus(const Position& pos) { 
-     U64 key = pos.pawnZobristHash(); 
-     PawnHashData& phd = getPawnHashEntry(pawnHash, key); 
-     if (phd.key != key) 
-         computePawnHashData(pos, phd); 
-     this->phd = &phd; 
-     int score = phd.score; 
-   
-     // Bonus for own king supporting passed pawns 
-     int passedScore = phd.passedBonusW; 
-     const U64 passedPawnsW = phd.passedPawns & pos.pieceTypeBB(Piece::WPAWN); 
-     U64 m = passedPawnsW; 
-     if (m != 0) { 
-         U64 kMask = pos.pieceTypeBB(Piece::WKING); 
-         int ky = Position::getY(pos.getKingSq(true)); 
-         if ((m << 8) & kMask) 
-             passedScore += kingPPSupportK[0] * kingPPSupportP[ky-1] / 32; 
-         else if ((m << 16) & kMask) 
-             passedScore += kingPPSupportK[1] * kingPPSupportP[ky-2] / 32; 
-         m = ((m & BitBoard::maskAToGFiles) << 1) | ((m & BitBoard::maskBToHFiles) >> 1); 
-         if (m & kMask) 
-             passedScore += kingPPSupportK[2] * kingPPSupportP[ky-0] / 32; 
-         if ((m << 8) & kMask) 
-             passedScore += kingPPSupportK[3] * kingPPSupportP[ky-1] / 32; 
-         if ((m << 16) & kMask) 
-             passedScore += kingPPSupportK[4] * kingPPSupportP[ky-2] / 32; 
-   
-         // Penalty for opponent pieces blocking passed pawns 
-         U64 ppBlockSquares = passedPawnsW << 8; 
-         if (ppBlockSquares & pos.blackBB()) { 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BKNIGHT)) * ppBlockerBonus[0]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BBISHOP)) * ppBlockerBonus[1]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BROOK))   * ppBlockerBonus[2]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BQUEEN))  * ppBlockerBonus[3]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BKING))   * ppBlockerBonus[4]; 
-         } 
-         ppBlockSquares = BitBoard::northFill(passedPawnsW << 16); 
-         if (ppBlockSquares & pos.blackBB()) { 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BKNIGHT)) * ppBlockerBonus[5]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BBISHOP)) * ppBlockerBonus[6]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BROOK))   * ppBlockerBonus[7]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BQUEEN))  * ppBlockerBonus[8]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::BKING))   * ppBlockerBonus[9]; 
-         } 
-   
-         // Bonus for rook behind passed pawn 
-         m = BitBoard::southFill(passedPawnsW); 
-         passedScore += RBehindPP1 * BitBoard::bitCount(m & pos.pieceTypeBB(Piece::WROOK)); 
-         passedScore -= RBehindPP2 * BitBoard::bitCount(m & pos.pieceTypeBB(Piece::BROOK)); 
-     } 
-     score += interpolate(passedScore * passedPawnEGFactor / 32, passedScore, mhd->wPassedPawnIPF); 
-   
-     passedScore = phd.passedBonusB; 
-     const U64 passedPawnsB = phd.passedPawns & pos.pieceTypeBB(Piece::BPAWN); 
-     m = passedPawnsB; 
-     if (m != 0) { 
-         U64 kMask = pos.pieceTypeBB(Piece::BKING); 
-         int ky = Position::getY(pos.getKingSq(false)); 
-         if ((m >> 8) & kMask) 
-             passedScore += kingPPSupportK[0] * kingPPSupportP[6-ky] / 32; 
-         else if ((m >> 16) & kMask) 
-             passedScore += kingPPSupportK[1] * kingPPSupportP[5-ky] / 32; 
-         m = ((m & BitBoard::maskAToGFiles) << 1) | ((m & BitBoard::maskBToHFiles) >> 1); 
-         if (m & kMask) 
-             passedScore += kingPPSupportK[2] * kingPPSupportP[7-ky] / 32; 
-         if ((m >> 8) & kMask) 
-             passedScore += kingPPSupportK[3] * kingPPSupportP[6-ky] / 32; 
-         if ((m >> 16) & kMask) 
-             passedScore += kingPPSupportK[4] * kingPPSupportP[5-ky] / 32; 
-   
-         // Penalty for opponent pieces blocking passed pawns 
-         U64 ppBlockSquares = passedPawnsB >> 8; 
-         if (ppBlockSquares & pos.whiteBB()) { 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WKNIGHT)) * ppBlockerBonus[0]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WBISHOP)) * ppBlockerBonus[1]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WROOK))   * ppBlockerBonus[2]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WQUEEN))  * ppBlockerBonus[3]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WKING))   * ppBlockerBonus[4]; 
-         } 
-         ppBlockSquares = BitBoard::southFill(passedPawnsB >> 16); 
-         if (ppBlockSquares && pos.whiteBB()) { 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WKNIGHT)) * ppBlockerBonus[5]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WBISHOP)) * ppBlockerBonus[6]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WROOK))   * ppBlockerBonus[7]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WQUEEN))  * ppBlockerBonus[8]; 
-             passedScore -= BitBoard::bitCount(ppBlockSquares & pos.pieceTypeBB(Piece::WKING))   * ppBlockerBonus[9]; 
-         } 
-   
-         // Bonus for rook behind passed pawn 
-         m = BitBoard::northFill(passedPawnsB); 
-         passedScore += RBehindPP1 * BitBoard::bitCount(m & pos.pieceTypeBB(Piece::BROOK)); 
-         passedScore -= RBehindPP2 * BitBoard::bitCount(m & pos.pieceTypeBB(Piece::WROOK)); 
-     } 
-     score -= interpolate(passedScore * passedPawnEGFactor / 32, passedScore, mhd->bPassedPawnIPF); 
-   
-     // Passed pawns are more dangerous if enemy king is far away 
-     const int hiMtrl = passedPawnHiMtrl; 
-     m = passedPawnsW; 
-     int bestWPawnDist = 8; 
-     int bestWPromSq = -1; 
-     if (m != 0) { 
-         int mtrlNoPawns = pos.bMtrl() - pos.bMtrlPawns(); 
-         if (mtrlNoPawns < hiMtrl) { 
-             int kingPos = pos.getKingSq(false); 
-             while (m != 0) { 
-                 int sq = BitBoard::extractSquare(m); 
-                 int x = Position::getX(sq); 
-                 int y = Position::getY(sq); 
-                 int pawnDist = std::min(5, 7 - y); 
-                 int kingDist = BitBoard::getKingDistance(kingPos, Position::getSquare(x, 7)); 
-                 int kScore = kingDist * 4; 
-                 if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist); 
-                 score += interpolate(kScore, 0, mhd->wPassedPawnIPF); 
-                 if (!pos.isWhiteMove()) 
-                     kingDist--; 
-                 if ((pawnDist < kingDist) && (mtrlNoPawns == 0)) { 
-                     if (BitBoard::northFill(1ULL<<sq) & (1LL << pos.getKingSq(true))) 
-                         pawnDist++; // Own king blocking pawn 
-                     if (pawnDist < bestWPawnDist) { 
-                         bestWPawnDist = pawnDist; 
-                         bestWPromSq = Position::getSquare(x, 7); 
-                     } 
-                 } 
-             } 
-         } 
-     } 
-     int bestBPawnDist = 8; 
-     int bestBPromSq = -1; 
-     m = passedPawnsB; 
-     if (m != 0) { 
-         int mtrlNoPawns = pos.wMtrl() - pos.wMtrlPawns(); 
-         if (mtrlNoPawns < hiMtrl) { 
-             int kingPos = pos.getKingSq(true); 
-             while (m != 0) { 
-                 int sq = BitBoard::extractSquare(m); 
-                 int x = Position::getX(sq); 
-                 int y = Position::getY(sq); 
-                 int pawnDist = std::min(5, y); 
-                 int kingDist = BitBoard::getKingDistance(kingPos, Position::getSquare(x, 0)); 
-                 int kScore = kingDist * 4; 
-                 if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist); 
-                 score -= interpolate(kScore, 0, mhd->bPassedPawnIPF); 
-                 if (pos.isWhiteMove()) 
-                     kingDist--; 
-                 if ((pawnDist < kingDist) && (mtrlNoPawns == 0)) { 
-                     if (BitBoard::southFill(1ULL<<sq) & (1LL << pos.getKingSq(false))) 
-                         pawnDist++; // Own king blocking pawn 
-                     if (pawnDist < bestBPawnDist) { 
-                         bestBPawnDist = pawnDist; 
-                         bestBPromSq = Position::getSquare(x, 0); 
-                     } 
-                 } 
-             } 
-         } 
-     } 
-   
-     // Evaluate pawn races in pawn end games 
-     const int prBonus = pawnRaceBonus; 
-     if (bestWPromSq >= 0) { 
-         if (bestBPromSq >= 0) { 
-             int wPly = bestWPawnDist * 2; if (pos.isWhiteMove()) wPly--; 
-             int bPly = bestBPawnDist * 2; if (!pos.isWhiteMove()) bPly--; 
-             if (wPly < bPly - 1) { 
-                 score += prBonus; 
-             } else if (wPly == bPly - 1) { 
-                 if (BitBoard::getDirection(bestWPromSq, pos.getKingSq(false))) 
-                     score += prBonus; 
-             } else if (wPly == bPly + 1) { 
-                 if (BitBoard::getDirection(bestBPromSq, pos.getKingSq(true))) 
-                     score -= prBonus; 
-             } else { 
-                 score -= prBonus; 
-             } 
-         } else 
-             score += prBonus; 
-     } else if (bestBPromSq >= 0) 
-         score -= prBonus; 
-   
-     return score; 
- } 
-   
- template <bool white> 
- static inline int 
- evalConnectedPP(int x, int y, U64 ppMask) { 
-     if ((x >= 7) || !(BitBoard::maskFile[x+1] & ppMask)) 
-         return 0; 
-   
-     int y2 = 0; 
-     if (white) { 
-         for (int i = 6; i >= 1; i--) { 
-             int sq = Position::getSquare(x+1, i); 
-             if (ppMask & (1ULL << sq)) { 
-                 y2 = i; 
-                 break; 
-             } 
-         } 
-     } else { 
-         for (int i = 1; i <= 6; i++) { 
-             int sq = Position::getSquare(x+1, i); 
-             if (ppMask & (1ULL << sq)) { 
-                 y2 = i; 
-                 break; 
-             } 
-         } 
-     } 
-     if (y2 == 0) 
-         return 0; 
-   
-     if (!white) { 
-         y = 7 - y; 
-         y2 = 7 - y2; 
-     } 
-     return connectedPPBonus[(y-1)*6 + (y2-1)]; 
- } 
-   
- /** Compute subset of squares given by mask that white is in control over, ie 
-  *  squares that have at least as many white pawn guards as black has pawn 
-  *  attacks on the square. */ 
- static inline U64 
- wPawnCtrlSquares(U64 mask, U64 wPawns, U64 bPawns) { 
-     U64 wLAtks = (wPawns & BitBoard::maskBToHFiles) << 7; 
-     U64 wRAtks = (wPawns & BitBoard::maskAToGFiles) << 9; 
-     U64 bLAtks = (bPawns & BitBoard::maskBToHFiles) >> 9; 
-     U64 bRAtks = (bPawns & BitBoard::maskAToGFiles) >> 7; 
-     return ((mask & ~bLAtks & ~bRAtks) | 
-             (mask & (bLAtks ^ bRAtks) & (wLAtks | wRAtks)) | 
-             (mask & wLAtks & wRAtks)); 
- } 
-   
- static inline U64 
- bPawnCtrlSquares(U64 mask, U64 wPawns, U64 bPawns) { 
-     U64 wLAtks = (wPawns & BitBoard::maskBToHFiles) << 7; 
-     U64 wRAtks = (wPawns & BitBoard::maskAToGFiles) << 9; 
-     U64 bLAtks = (bPawns & BitBoard::maskBToHFiles) >> 9; 
-     U64 bRAtks = (bPawns & BitBoard::maskAToGFiles) >> 7; 
-     return ((mask & ~wLAtks & ~wRAtks) | 
-             (mask & (wLAtks ^ wRAtks) & (bLAtks | bRAtks)) | 
-             (mask & bLAtks & bRAtks)); 
- } 
-   
- U64 
- Evaluate::computeStalePawns(const Position& pos) { 
-     const U64 wPawns = pos.pieceTypeBB(Piece::WPAWN); 
-     const U64 bPawns = pos.pieceTypeBB(Piece::BPAWN); 
-   
-     // Compute stale white pawns 
-     U64 wStale; 
-     { 
-         U64 wPawnCtrl = wPawnCtrlSquares(wPawns, wPawns, bPawns); 
-         for (int i = 0; i < 4; i++) 
-             wPawnCtrl |= wPawnCtrlSquares((wPawnCtrl << 8) & ~bPawns, wPawnCtrl, bPawns); 
-         wPawnCtrl &= ~BitBoard::maskRow8; 
-         U64 wPawnCtrlLAtk = (wPawnCtrl & BitBoard::maskBToHFiles) << 7; 
-         U64 wPawnCtrlRAtk = (wPawnCtrl & BitBoard::maskAToGFiles) << 9; 
-   
-         U64 bLAtks = (bPawns & BitBoard::maskBToHFiles) >> 9; 
-         U64 bRAtks = (bPawns & BitBoard::maskAToGFiles) >> 7; 
-         U64 wActive = ((bLAtks ^ bRAtks) | 
-                        (bLAtks & bRAtks & (wPawnCtrlLAtk | wPawnCtrlRAtk))); 
-         for (int i = 0; i < 4; i++) 
-             wActive |= (wActive & ~(wPawns | bPawns)) >> 8; 
-         wStale = wPawns & ~wActive; 
-     } 
-   
-     // Compute stale black pawns 
-     U64 bStale; 
-     { 
-         U64 bPawnCtrl = bPawnCtrlSquares(bPawns, wPawns, bPawns); 
-         for (int i = 0; i < 4; i++) 
-             bPawnCtrl |= bPawnCtrlSquares((bPawnCtrl >> 8) & ~wPawns, wPawns, bPawnCtrl); 
-         bPawnCtrl &= ~BitBoard::maskRow1; 
-         U64 bPawnCtrlLAtk = (bPawnCtrl & BitBoard::maskBToHFiles) >> 9; 
-         U64 bPawnCtrlRAtk = (bPawnCtrl & BitBoard::maskAToGFiles) >> 7; 
-   
-         U64 wLAtks = (wPawns & BitBoard::maskBToHFiles) << 7; 
-         U64 wRAtks = (wPawns & BitBoard::maskAToGFiles) << 9; 
-         U64 bActive = ((wLAtks ^ wRAtks) | 
-                        (wLAtks & wRAtks & (bPawnCtrlLAtk | bPawnCtrlRAtk))); 
-         for (int i = 0; i < 4; i++) 
-             bActive |= (bActive & ~(wPawns | bPawns)) << 8; 
-         bStale = bPawns & ~bActive; 
-     } 
-   
-     return wStale | bStale; 
- } 
-   
- void 
- Evaluate::computePawnHashData(const Position& pos, PawnHashData& ph) { 
-     int score = 0; 
-   
-     // Evaluate double pawns and pawn islands 
-     const U64 wPawns = pos.pieceTypeBB(Piece::WPAWN); 
-     const U64 wPawnFiles = BitBoard::southFill(wPawns) & 0xff; 
-     const int wIslands = BitBoard::bitCount(((~wPawnFiles) >> 1) & wPawnFiles); 
-   
-     const U64 bPawns = pos.pieceTypeBB(Piece::BPAWN); 
-     const U64 bPawnFiles = BitBoard::southFill(bPawns) & 0xff; 
-     const int bIslands = BitBoard::bitCount(((~bPawnFiles) >> 1) & bPawnFiles); 
-     score -= (wIslands - bIslands) * pawnIslandPenalty; 
-   
-     // Evaluate doubled pawns 
-     const U64 wDoubled = BitBoard::northFill(wPawns << 8) & wPawns; 
-     U64 m = wDoubled; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         score -= pawnDoubledPenalty[Position::getX(sq)]; 
-     } 
-     const U64 bDoubled = BitBoard::southFill(bPawns >> 8) & bPawns; 
-     m = bDoubled; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         score += pawnDoubledPenalty[Position::getX(sq)]; 
-     } 
-   
-     // Evaluate isolated pawns 
-     const U64 wIsolated = wPawns & ~BitBoard::northFill(BitBoard::southFill( 
-             ((wPawns & BitBoard::maskAToGFiles) << 1) | 
-             ((wPawns & BitBoard::maskBToHFiles) >> 1))); 
-     m = wIsolated; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         score -= pawnIsolatedPenalty[Position::getX(sq)]; 
-     } 
-     const U64 bIsolated = bPawns & ~BitBoard::northFill(BitBoard::southFill( 
-             ((bPawns & BitBoard::maskAToGFiles) << 1) | 
-             ((bPawns & BitBoard::maskBToHFiles) >> 1))); 
-     m = bIsolated; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         score += pawnIsolatedPenalty[Position::getX(sq)]; 
-     } 
-   
-     // Evaluate backward pawns, defined as a pawn that guards a friendly pawn, 
-     // can't be guarded by friendly pawns, can advance, but can't advance without 
-     // being captured by an enemy pawn. 
-     const U64 bPawnNoAtks = ~BitBoard::southFill(bPawnAttacks); 
-     const U64 wPawnNoAtks = ~BitBoard::northFill(wPawnAttacks); 
-     ph.outPostsW = bPawnNoAtks & wPawnAttacks; 
-     ph.outPostsB = wPawnNoAtks & bPawnAttacks; 
-   
-     U64 wBackward = wPawns & ~((wPawns | bPawns) >> 8) & (bPawnAttacks >> 8) & wPawnNoAtks; 
-     wBackward &= (((wPawns & BitBoard::maskBToHFiles) >> 9) | 
-                   ((wPawns & BitBoard::maskAToGFiles) >> 7)); 
-     wBackward &= ~BitBoard::northFill(bPawnFiles); 
-     U64 bBackward = bPawns & ~((wPawns | bPawns) << 8) & (wPawnAttacks << 8) & bPawnNoAtks; 
-     bBackward &= (((bPawns & BitBoard::maskBToHFiles) << 7) | 
-                   ((bPawns & BitBoard::maskAToGFiles) << 9)); 
-     bBackward &= ~BitBoard::northFill(wPawnFiles); 
-     score -= (BitBoard::bitCount(wBackward) - BitBoard::bitCount(bBackward)) * pawnBackwardPenalty; 
-   
-     // Evaluate "semi-backward pawns", defined as pawns on 2:nd or 3:rd rank that can advance, 
-     // but the advanced pawn is attacked by an enemy pawn. 
-     U64 wSemiBackward = wPawns & ~((wPawns | bPawns) >> 8) & (bPawnAttacks >> 8); 
-     score -= BitBoard::bitCount(wSemiBackward & BitBoard::maskRow2) * pawnSemiBackwardPenalty1; 
-     score -= BitBoard::bitCount(wSemiBackward & BitBoard::maskRow3) * pawnSemiBackwardPenalty2; 
-     U64 bSemiBackward = bPawns & ~((wPawns | bPawns) << 8) & (wPawnAttacks << 8); 
-     score += BitBoard::bitCount(bSemiBackward & BitBoard::maskRow7) * pawnSemiBackwardPenalty1; 
-     score += BitBoard::bitCount(bSemiBackward & BitBoard::maskRow6) * pawnSemiBackwardPenalty2; 
-   
-     // Evaluate passed pawn bonus, white 
-     U64 passedPawnsW = wPawns & ~BitBoard::southFill(bPawns | bPawnAttacks | (wPawns >> 8)); 
-     int passedBonusW = 0; 
-     if (passedPawnsW != 0) { 
-         U64 m = passedPawnsW; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             int x = Position::getX(sq); 
-             int y = Position::getY(sq); 
-             passedBonusW += passedPawnBonusX[x] + passedPawnBonusY[y]; 
-             passedBonusW += evalConnectedPP<true>(x, y, passedPawnsW); 
-         } 
-     } 
-   
-     // Evaluate passed pawn bonus, black 
-     U64 passedPawnsB = bPawns & ~BitBoard::northFill(wPawns | wPawnAttacks | (bPawns << 8)); 
-     int passedBonusB = 0; 
-     if (passedPawnsB != 0) { 
-         U64 m = passedPawnsB; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             int x = Position::getX(sq); 
-             int y = Position::getY(sq); 
-             passedBonusB += passedPawnBonusX[x] + passedPawnBonusY[7-y]; 
-             passedBonusB += evalConnectedPP<false>(x, y, passedPawnsB); 
-         } 
-     } 
-   
-     // Evaluate candidate passed pawn bonus 
-     const U64 wLeftAtks  = (wPawns & BitBoard::maskBToHFiles) << 7; 
-     const U64 wRightAtks = (wPawns & BitBoard::maskAToGFiles) << 9; 
-     const U64 bLeftAtks  = (bPawns & BitBoard::maskBToHFiles) >> 9; 
-     const U64 bRightAtks = (bPawns & BitBoard::maskAToGFiles) >> 7; 
-     const U64 bBlockSquares = ((bLeftAtks | bRightAtks) & ~(wLeftAtks | wRightAtks)) | 
-                               ((bLeftAtks & bRightAtks) & ~(wLeftAtks & wRightAtks)); 
-     const U64 wCandidates = wPawns & ~BitBoard::southFill(bPawns | (wPawns >> 8) | bBlockSquares) & ~passedPawnsW; 
-   
-     const U64 wBlockSquares = ((wLeftAtks | wRightAtks) & ~(bLeftAtks | bRightAtks)) | 
-                               ((wLeftAtks & wRightAtks) & ~(bLeftAtks & bRightAtks)); 
-     const U64 bCandidates = bPawns & ~BitBoard::northFill(wPawns | (bPawns << 8) | wBlockSquares) & ~passedPawnsB; 
-   
-     { 
-         U64 m = wCandidates; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             int y = Position::getY(sq); 
-             passedBonusW += candidatePassedBonus[y]; 
-         } 
-     } 
-     { 
-         U64 m = bCandidates; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             int y = Position::getY(sq); 
-             passedBonusB += candidatePassedBonus[7-y]; 
-         } 
-     } 
-   
-     { // Bonus for pawns protected by pawns 
-         U64 m = wPawnAttacks & wPawns; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             score += protectedPawnBonus[63-sq]; 
-         } 
-         m = bPawnAttacks & bPawns; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             score -= protectedPawnBonus[sq]; 
-         } 
-     } 
-     { // Bonus for pawns attacked by pawns 
-         U64 m = wPawnAttacks & bPawns; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             score += attackedPawnBonus[63-sq]; 
-         } 
-         m = bPawnAttacks & wPawns; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             score -= attackedPawnBonus[sq]; 
-         } 
-     } 
-   
-     ph.key = pos.pawnZobristHash(); 
-     ph.score = score; 
-     ph.passedBonusW = (S16)passedBonusW; 
-     ph.passedBonusB = (S16)passedBonusB; 
-     ph.passedPawns = passedPawnsW | passedPawnsB; 
-     ph.stalePawns = computeStalePawns(pos) & ~passedPawnsW & ~passedPawnsB; 
- } 
-   
- int 
- Evaluate::rookBonus(const Position& pos) { 
-     int score = 0; 
-     const U64 wPawns = pos.pieceTypeBB(Piece::WPAWN); 
-     const U64 bPawns = pos.pieceTypeBB(Piece::BPAWN); 
-     const U64 occupied = pos.occupiedBB(); 
-     U64 m = pos.pieceTypeBB(Piece::WROOK); 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         const int x = Position::getX(sq); 
-         if ((wPawns & BitBoard::maskFile[x]) == 0) { // At least half-open file 
-             score += (bPawns & BitBoard::maskFile[x]) == 0 ? (int)rookOpenBonus : (int)rookHalfOpenBonus; // Pierre-Marie Baty -- added type cast 
-         } // Pierre-Marie Baty -- braces fix 
-         U64 atk = BitBoard::rookAttacks(sq, occupied); 
-         wAttacksBB |= atk; 
-         score += rookMobScore[BitBoard::bitCount(atk & ~(pos.whiteBB() | bPawnAttacks))]; 
-         if ((atk & bKingZone) != 0) 
-             bKingAttacks += BitBoard::bitCount(atk & bKingZone); 
-     } 
-     U64 r7 = pos.pieceTypeBB(Piece::WROOK) & BitBoard::maskRow7; 
-     if (((r7 & (r7 - 1)) != 0) && 
-         ((pos.pieceTypeBB(Piece::BKING) & BitBoard::maskRow8) != 0)) 
-         score += rookDouble7thRowBonus; // Two rooks on 7:th row 
-     m = pos.pieceTypeBB(Piece::BROOK); 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         const int x = Position::getX(sq); 
-         if ((bPawns & BitBoard::maskFile[x]) == 0) { 
-             score -= (wPawns & BitBoard::maskFile[x]) == 0 ? (int)rookOpenBonus : (int)rookHalfOpenBonus; // Pierre-Marie Baty -- added type cast 
-         } // Pierre-Marie Baty -- braces fix 
-         U64 atk = BitBoard::rookAttacks(sq, occupied); 
-         bAttacksBB |= atk; 
-         score -= rookMobScore[BitBoard::bitCount(atk & ~(pos.blackBB() | wPawnAttacks))]; 
-         if ((atk & wKingZone) != 0) 
-             wKingAttacks += BitBoard::bitCount(atk & wKingZone); 
-     } 
-     r7 = pos.pieceTypeBB(Piece::BROOK) & BitBoard::maskRow2; 
-     if (((r7 & (r7 - 1)) != 0) && 
-         ((pos.pieceTypeBB(Piece::WKING) & BitBoard::maskRow1) != 0)) 
-       score -= rookDouble7thRowBonus; // Two rooks on 2:nd row 
-     return score; 
- } 
-   
- int 
- Evaluate::bishopEval(const Position& pos, int oldScore) { 
-     int score = 0; 
-     const U64 occupied = pos.occupiedBB(); 
-     const U64 wBishops = pos.pieceTypeBB(Piece::WBISHOP); 
-     const U64 bBishops = pos.pieceTypeBB(Piece::BBISHOP); 
-     if ((wBishops | bBishops) == 0) 
-         return 0; 
-     U64 m = wBishops; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         U64 atk = BitBoard::bishopAttacks(sq, occupied); 
-         wAttacksBB |= atk; 
-         score += bishMobScore[BitBoard::bitCount(atk & ~(pos.whiteBB() | bPawnAttacks))]; 
-         if ((atk & bKingZone) != 0) 
-             bKingAttacks += BitBoard::bitCount(atk & bKingZone); 
-     } 
-     m = bBishops; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         U64 atk = BitBoard::bishopAttacks(sq, occupied); 
-         bAttacksBB |= atk; 
-         score -= bishMobScore[BitBoard::bitCount(atk & ~(pos.blackBB() | wPawnAttacks))]; 
-         if ((atk & wKingZone) != 0) 
-             wKingAttacks += BitBoard::bitCount(atk & wKingZone); 
-     } 
-   
-     bool whiteDark  = (wBishops & BitBoard::maskDarkSq ) != 0; 
-     bool whiteLight = (wBishops & BitBoard::maskLightSq) != 0; 
-     bool blackDark  = (bBishops & BitBoard::maskDarkSq ) != 0; 
-     bool blackLight = (bBishops & BitBoard::maskLightSq) != 0; 
-     int numWhite = (whiteDark ? 1 : 0) + (whiteLight ? 1 : 0); 
-     int numBlack = (blackDark ? 1 : 0) + (blackLight ? 1 : 0); 
-   
-     // Bishop pair bonus 
-     if (numWhite == 2) { 
-         int numMinors = BitBoard::bitCount(pos.pieceTypeBB(Piece::BBISHOP, Piece::BKNIGHT)); 
-         const int numPawns = BitBoard::bitCount(pos.pieceTypeBB(Piece::WPAWN)); 
-         score += bishopPairValue[std::min(numMinors,3)] - numPawns * bishopPairPawnPenalty; 
-     } 
-     if (numBlack == 2) { 
-         int numMinors = BitBoard::bitCount(pos.pieceTypeBB(Piece::WBISHOP, Piece::WKNIGHT)); 
-         const int numPawns = BitBoard::bitCount(pos.pieceTypeBB(Piece::BPAWN)); 
-         score -= bishopPairValue[std::min(numMinors,3)] - numPawns * bishopPairPawnPenalty; 
-     } 
-   
-     if ((numWhite == 1) && (numBlack == 1) && (whiteDark != blackDark) && 
-         (pos.wMtrl() - pos.wMtrlPawns() == pos.bMtrl() - pos.bMtrlPawns())) { 
-         const int penalty = (oldScore + score) * oppoBishopPenalty / 128; 
-         score -= interpolate(penalty, 0, mhd->diffColorBishopIPF); 
-     } else { 
-         if (numWhite == 1) { 
-             U64 bishColorMask = whiteDark ? BitBoard::maskDarkSq : BitBoard::maskLightSq; 
-             U64 m = pos.pieceTypeBB(Piece::WPAWN) & bishColorMask; 
-             m |= (m << 8) & pos.pieceTypeBB(Piece::BPAWN); 
-             score -= 2 * BitBoard::bitCount(m); 
-         } 
-         if (numBlack == 1) { 
-             U64 bishColorMask = blackDark ? BitBoard::maskDarkSq : BitBoard::maskLightSq; 
-             U64 m = pos.pieceTypeBB(Piece::BPAWN) & bishColorMask; 
-             m |= (m >> 8) & pos.pieceTypeBB(Piece::WPAWN); 
-             score += 2 * BitBoard::bitCount(m); 
-         } 
-     } 
-   
-     // Penalty for bishop trapped behind pawn at a2/h2/a7/h7 
-     if (((wBishops | bBishops) & BitBoard::sqMask(A2,H2,A7,H7)) != 0) { 
-         const int bTrapped = trappedBishopPenalty; 
-         if ((pos.getPiece(A7) == Piece::WBISHOP) && 
-             (pos.getPiece(B6) == Piece::BPAWN) && 
-             (pos.getPiece(C7) == Piece::BPAWN)) 
-             score -= bTrapped; 
-         if ((pos.getPiece(H7) == Piece::WBISHOP) && 
-             (pos.getPiece(G6) == Piece::BPAWN) && 
-             (pos.getPiece(F7) == Piece::BPAWN)) 
-             score -= bTrapped; 
-         if ((pos.getPiece(A2)  == Piece::BBISHOP) && 
-             (pos.getPiece(B3) == Piece::WPAWN) && 
-             (pos.getPiece(C2) == Piece::WPAWN)) 
-             score += bTrapped; 
-         if ((pos.getPiece(H2) == Piece::BBISHOP) && 
-             (pos.getPiece(G3) == Piece::WPAWN) && 
-             (pos.getPiece(F2) == Piece::WPAWN)) 
-             score += bTrapped; 
-     } 
-   
-     return score; 
- } 
-   
- int 
- Evaluate::knightEval(const Position& pos) { 
-     int score = 0; 
-     U64 wKnights = pos.pieceTypeBB(Piece::WKNIGHT); 
-     U64 bKnights = pos.pieceTypeBB(Piece::BKNIGHT); 
-     if ((wKnights | bKnights) == 0) 
-         return 0; 
-   
-     // Knight mobility 
-     U64 m = wKnights; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         U64 atk = BitBoard::knightAttacks[sq]; 
-         wAttacksBB |= atk; 
-         score += knightMobScoreA[sq][BitBoard::bitCount(atk & ~pos.whiteBB() & ~bPawnAttacks)]; 
-     } 
-   
-     m = bKnights; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         U64 atk = BitBoard::knightAttacks[sq]; 
-         bAttacksBB |= atk; 
-         score -= knightMobScoreA[sq][BitBoard::bitCount(atk & ~pos.blackBB() & ~wPawnAttacks)]; 
-     } 
-   
-     m = wKnights & phd->outPostsW; 
-     if (m != 0) { 
-         int outPost = 0; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             outPost += knightOutpostBonus[63-sq]; 
-         } 
-         score += interpolate(0, outPost, mhd->wKnightOutPostIPF); 
-     } 
-   
-     m = bKnights & phd->outPostsB; 
-     if (m != 0) { 
-         int outPost = 0; 
-         while (m != 0) { 
-             int sq = BitBoard::extractSquare(m); 
-             outPost += knightOutpostBonus[sq]; 
-         } 
-         score -= interpolate(0, outPost, mhd->bKnightOutPostIPF); 
-     } 
-   
-     return score; 
- } 
-   
- int 
- Evaluate::threatBonus(const Position& pos) { 
-     int score = 0; 
-   
-     // Sum values for all black pieces under attack 
-     wAttacksBB &= pos.pieceTypeBB(Piece::BKNIGHT, Piece::BBISHOP, Piece::BROOK, Piece::BQUEEN); 
-     wAttacksBB |= wPawnAttacks; 
-     U64 m = wAttacksBB & pos.blackBB() & ~pos.pieceTypeBB(Piece::BKING); 
-     int tmp = 0; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         tmp += ::pieceValue[pos.getPiece(sq)]; 
-     } 
-     score += tmp + tmp * tmp / threatBonus2; 
-   
-     // Sum values for all white pieces under attack 
-     bAttacksBB &= pos.pieceTypeBB(Piece::WKNIGHT, Piece::WBISHOP, Piece::WROOK, Piece::WQUEEN); 
-     bAttacksBB |= bPawnAttacks; 
-     m = bAttacksBB & pos.whiteBB() & ~pos.pieceTypeBB(Piece::WKING); 
-     tmp = 0; 
-     while (m != 0) { 
-         int sq = BitBoard::extractSquare(m); 
-         tmp += ::pieceValue[pos.getPiece(sq)]; 
-     } 
-     score -= tmp + tmp * tmp / threatBonus2; 
-     return score / threatBonus1; 
- } 
-   
- int 
- Evaluate::protectBonus(const Position& pos) { 
-     int score = 0; 
-     score += BitBoard::bitCount(pos.pieceTypeBB(Piece::WKNIGHT) & wPawnAttacks) * ::protectBonus[0]; 
-     score += BitBoard::bitCount(pos.pieceTypeBB(Piece::WBISHOP) & wPawnAttacks) * ::protectBonus[1]; 
-     score += BitBoard::bitCount(pos.pieceTypeBB(Piece::WROOK  ) & wPawnAttacks) * ::protectBonus[2]; 
-     score += BitBoard::bitCount(pos.pieceTypeBB(Piece::WQUEEN ) & wPawnAttacks) * ::protectBonus[3]; 
-     score -= BitBoard::bitCount(pos.pieceTypeBB(Piece::BKNIGHT) & bPawnAttacks) * ::protectBonus[0]; 
-     score -= BitBoard::bitCount(pos.pieceTypeBB(Piece::BBISHOP) & bPawnAttacks) * ::protectBonus[1]; 
-     score -= BitBoard::bitCount(pos.pieceTypeBB(Piece::BROOK  ) & bPawnAttacks) * ::protectBonus[2]; 
-     score -= BitBoard::bitCount(pos.pieceTypeBB(Piece::BQUEEN ) & bPawnAttacks) * ::protectBonus[3]; 
-     return score; 
- } 
-   
- /** Compute king safety for both kings. */ 
- int 
- Evaluate::kingSafety(const Position& pos) { 
-     const int minM = (rV + bV) * 2; 
-     const int m = pos.wMtrl() - pos.wMtrlPawns() + pos.bMtrl() - pos.bMtrlPawns(); 
-     if (m <= minM) 
-         return 0; 
-   
-     const int wKing = pos.getKingSq(true); 
-     const int bKing = pos.getKingSq(false); 
-     int score = kingSafetyKPPart(pos); 
-     if (Position::getY(wKing) == 0) { 
-         if (((pos.pieceTypeBB(Piece::WKING) & BitBoard::sqMask(F1,G1)) != 0) && 
-             ((pos.pieceTypeBB(Piece::WROOK) & BitBoard::sqMask(G1,H1)) != 0) && 
-             ((pos.pieceTypeBB(Piece::WPAWN) & BitBoard::maskFile[6]) != 0)) { 
-             score -= ((pos.pieceTypeBB(Piece::WPAWN) & BitBoard::maskFile[7]) != 0) ? 
-                      (int)trappedRookPenalty1 : (int)trappedRookPenalty2; // Pierre-Marie Baty -- added type cast 
-         } else 
-         if (((pos.pieceTypeBB(Piece::WKING) & BitBoard::sqMask(B1,C1)) != 0) && 
-             ((pos.pieceTypeBB(Piece::WROOK) & BitBoard::sqMask(A1,B1)) != 0) && 
-             ((pos.pieceTypeBB(Piece::WPAWN) & BitBoard::maskFile[1]) != 0)) { 
-             score -= ((pos.pieceTypeBB(Piece::WPAWN) & BitBoard::maskFile[0]) != 0) ? 
-                      (int)trappedRookPenalty1 : (int)trappedRookPenalty2; // Pierre-Marie Baty -- added type cast 
-         } 
-     } 
-     if (Position::getY(bKing) == 7) { 
-         if (((pos.pieceTypeBB(Piece::BKING) & BitBoard::sqMask(F8,G8)) != 0) && 
-             ((pos.pieceTypeBB(Piece::BROOK) & BitBoard::sqMask(G8,H8)) != 0) && 
-             ((pos.pieceTypeBB(Piece::BPAWN) & BitBoard::maskFile[6]) != 0)) { 
-             score += ((pos.pieceTypeBB(Piece::BPAWN) & BitBoard::maskFile[7]) != 0) ? 
-                      (int)trappedRookPenalty1 : (int)trappedRookPenalty2; // Pierre-Marie Baty -- added type cast 
-         } else 
-         if (((pos.pieceTypeBB(Piece::BKING) & BitBoard::sqMask(B8,C8)) != 0) && 
-             ((pos.pieceTypeBB(Piece::BROOK) & BitBoard::sqMask(A8,B8)) != 0) && 
-             ((pos.pieceTypeBB(Piece::BPAWN) & BitBoard::maskFile[1]) != 0)) { 
-             score += ((pos.pieceTypeBB(Piece::BPAWN) & BitBoard::maskFile[0]) != 0) ? 
-                      (int)trappedRookPenalty1 : (int)trappedRookPenalty2; // Pierre-Marie Baty -- added type cast 
-         } 
-     } 
-   
-     // Bonus for minor pieces protecting king 
-     score += BitBoard::bitCount(Evaluate::knightKingProtectPattern[wKing] & pos.pieceTypeBB(Piece::WKNIGHT)) * knightKingProtectBonus; 
-     score += BitBoard::bitCount(Evaluate::bishopKingProtectPattern[wKing] & pos.pieceTypeBB(Piece::WBISHOP)) * bishopKingProtectBonus; 
-     score -= BitBoard::bitCount(Evaluate::knightKingProtectPattern[bKing] & pos.pieceTypeBB(Piece::BKNIGHT)) * knightKingProtectBonus; 
-     score -= BitBoard::bitCount(Evaluate::bishopKingProtectPattern[bKing] & pos.pieceTypeBB(Piece::BBISHOP)) * bishopKingProtectBonus; 
-   
-     score += kingAttackWeight[std::min(bKingAttacks, 13)] - kingAttackWeight[std::min(wKingAttacks, 13)]; 
-     const int kSafety = interpolate(0, score, mhd->kingSafetyIPF); 
-     return kSafety; 
- } 
-   
- template <bool white, bool right> 
- static inline int 
- evalKingPawnShelter(const Position& pos) { 
-     const int mPawn = white ? Piece::WPAWN : Piece::BPAWN; 
-     const int oPawn = white ? Piece::BPAWN : Piece::WPAWN; 
-   
-     const int yBeg = white ? 1 :  6; 
-     const int yInc = white ? 1 : -1; 
-     const int yEnd = white ? 4 :  3; 
-     const int xBeg = right ? 5 :  2; 
-     const int xInc = right ? 1 : -1; 
-     const int xEnd = right ? 8 : -1; 
-     int idx = 0; 
-     int score = 0; 
-     for (int y = yBeg; y != yEnd; y += yInc) { 
-         for (int x = xBeg; x != xEnd; x += xInc) { 
-             int p = pos.getPiece(Position::getSquare(x, y)); 
-             if (p == mPawn) 
-                 score += pawnShelterTable[idx]; 
-             else if (p == oPawn) 
-                 score -= pawnStormTable[idx]; 
-             idx++; 
-         } 
-     } 
-     return score; 
- } 
-   
- int 
- Evaluate::kingSafetyKPPart(const Position& pos) { 
-     const U64 key = pos.pawnZobristHash() ^ pos.kingZobristHash(); 
-     KingSafetyHashData& ksh = getKingSafetyHashEntry(kingSafetyHash, key); 
-     if (ksh.key != key) { 
-         int score = 0; 
-         const U64 wPawns = pos.pieceTypeBB(Piece::WPAWN); 
-         const U64 bPawns = pos.pieceTypeBB(Piece::BPAWN); 
-         { // White pawn shelter bonus 
-             int safety = 0; 
-             int halfOpenFiles = 0; 
-             if (Position::getY(pos.wKingSq()) < 2) { 
-                 U64 shelter = 1ULL << Position::getX(pos.wKingSq()); 
-                 shelter |= ((shelter & BitBoard::maskBToHFiles) >> 1) | 
-                            ((shelter & BitBoard::maskAToGFiles) << 1); 
-                 shelter <<= 8; 
-                 safety += kingSafetyWeight1 * BitBoard::bitCount(wPawns & shelter); 
-                 safety -= kingSafetyWeight2 * BitBoard::bitCount(bPawns & (shelter | (shelter << 8))); 
-                 shelter <<= 8; 
-                 safety += kingSafetyWeight3 * BitBoard::bitCount(wPawns & shelter); 
-                 shelter <<= 8; 
-                 safety -= kingSafetyWeight4 * BitBoard::bitCount(bPawns & shelter); 
-   
-                 U64 wOpen = BitBoard::southFill(shelter) & (~BitBoard::southFill(wPawns)) & 0xff; 
-                 if (wOpen != 0) { 
-                     halfOpenFiles += kingSafetyHalfOpenBCDEFG1 * BitBoard::bitCount(wOpen & 0xe7); 
-                     halfOpenFiles += kingSafetyHalfOpenAH1 * BitBoard::bitCount(wOpen & 0x18); 
-                 } 
-                 U64 bOpen = BitBoard::southFill(shelter) & (~BitBoard::southFill(bPawns)) & 0xff; 
-                 if (bOpen != 0) { 
-                     halfOpenFiles += kingSafetyHalfOpenBCDEFG2 * BitBoard::bitCount(bOpen & 0xe7); 
-                     halfOpenFiles += kingSafetyHalfOpenAH2 * BitBoard::bitCount(bOpen & 0x18); 
-                 } 
-                 const int th = kingSafetyThreshold; 
-                 safety = std::min(safety, th); 
-   
-                 const int xKing = Position::getX(pos.wKingSq()); 
-                 if (xKing >= 5) 
-                     score += evalKingPawnShelter<true, true>(pos); 
-                 else if (xKing <= 2) 
-                     score += evalKingPawnShelter<true, false>(pos); 
-             } 
-             const int kSafety = safety - halfOpenFiles; 
-             score += kSafety; 
-         } 
-         { // Black pawn shelter bonus 
-             int safety = 0; 
-             int halfOpenFiles = 0; 
-             if (Position::getY(pos.bKingSq()) >= 6) { 
-                 U64 shelter = 1ULL << (56 + Position::getX(pos.bKingSq())); 
-                 shelter |= ((shelter & BitBoard::maskBToHFiles) >> 1) | 
-                            ((shelter & BitBoard::maskAToGFiles) << 1); 
-                 shelter >>= 8; 
-                 safety += kingSafetyWeight1 * BitBoard::bitCount(bPawns & shelter); 
-                 safety -= kingSafetyWeight2 * BitBoard::bitCount(wPawns & (shelter | (shelter >> 8))); 
-                 shelter >>= 8; 
-                 safety += kingSafetyWeight3 * BitBoard::bitCount(bPawns & shelter); 
-                 shelter >>= 8; 
-                 safety -= kingSafetyWeight4 * BitBoard::bitCount(wPawns & shelter); 
-   
-                 U64 bOpen = BitBoard::southFill(shelter) & (~BitBoard::southFill(bPawns)) & 0xff; 
-                 if (bOpen != 0) { 
-                     halfOpenFiles += kingSafetyHalfOpenBCDEFG1 * BitBoard::bitCount(bOpen & 0xe7); 
-                     halfOpenFiles += kingSafetyHalfOpenAH1 * BitBoard::bitCount(bOpen & 0x18); 
-                 } 
-                 U64 wOpen = BitBoard::southFill(shelter) & (~BitBoard::southFill(wPawns)) & 0xff; 
-                 if (wOpen != 0) { 
-                     halfOpenFiles += kingSafetyHalfOpenBCDEFG2 * BitBoard::bitCount(wOpen & 0xe7); 
-                     halfOpenFiles += kingSafetyHalfOpenAH2 * BitBoard::bitCount(wOpen & 0x18); 
-                 } 
-                 const int th = kingSafetyThreshold; 
-                 safety = std::min(safety, th); 
-   
-                 const int xKing = Position::getX(pos.bKingSq()); 
-                 if (xKing >= 5) 
-                     score -= evalKingPawnShelter<false, true>(pos); 
-                 else if (xKing <= 2) 
-                     score -= evalKingPawnShelter<false, false>(pos); 
-             } 
-             const int kSafety = safety - halfOpenFiles; 
-             score -= kSafety; 
-         } 
-         // Pawn storm bonus 
-         static const int kingZone[8] = {0,0,0, 1,1, 2,2,2}; 
-         static const U64 pStormMask[3] = { 0x0707070707070707ULL, 0, 0xE0E0E0E0E0E0E0E0ULL }; 
-         const int wKingZone = kingZone[Position::getX(pos.wKingSq())]; 
-         const int bKingZone = kingZone[Position::getX(pos.bKingSq())]; 
-         const int kingDiff = std::abs(wKingZone - bKingZone); 
-         if (kingDiff > 1) { 
-             U64 m = wPawns & pStormMask[bKingZone]; 
-             while (m != 0) { 
-                 int sq = BitBoard::extractSquare(m); 
-                 score += pawnStormBonus * (Position::getY(sq)-5); 
-             } 
-             m = bPawns & pStormMask[wKingZone]; 
-             while (m != 0) { 
-                 int sq = BitBoard::extractSquare(m); 
-                 score += pawnStormBonus * (Position::getY(sq)-2); 
-             } 
-         } 
-   
-         ksh.key = key; 
-         ksh.score = score; 
-     } 
-     return ksh.score; 
- } 
-   
- std::shared_ptr<Evaluate::EvalHashTables> 
- Evaluate::getEvalHashTables() { 
-     return std::make_shared<EvalHashTables>(); 
- } 
-   
- int 
- Evaluate::swindleScore(int evalScore) { 
-     int sgn = evalScore >= 0 ? 1 : -1; 
-     int score = std::abs(evalScore) + 4; 
-     int lg = floorLog2(score); 
-     score = (lg - 3) * 4 + (score >> (lg - 2)); 
-     return sgn * score; 
- } 
-