- #include "chess.h" 
- #include "evaluate.h" 
- #include "data.h" 
- /* last modified 08/03/16 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   Evaluate() is used to evaluate the chess board.  Broadly, it addresses    * 
-  *   four (4) distinct areas:  (1) material score which is simply a summing of * 
-  *   piece types multiplied by piece values;  (2) pawn scoring which considers * 
-  *   placement of pawns and also evaluates passed pawns, particularly in end-  * 
-  *   game situations;  (3) piece scoring which evaluates the placement of each * 
-  *   piece as well as things like piece mobility;  (4) king safety which       * 
-  *   considers the pawn shelter around the king and enemy pieces and how close * 
-  *   they are to assist in a king-side attack.                                 * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- int Evaluate(TREE * RESTRICT tree, int ply, int wtm, int alpha, int beta) { 
-   PAWN_HASH_ENTRY *ptable; 
-   PXOR *pxtable; 
-   int score, side, can_win = 3, phase, lscore, cutoff; 
-   
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  First thing we do is if -DSKILL was passed in to the     * 
-  *  compiler, we burn some time to slow the search down,     * 
-  *  then we fall into the normal evaluation code.            * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
- #if defined(SKILL) 
-   if (skill < 100) { 
-     int i, j; 
-     for (i = 0; i < burnc[skill / 10] && !abort_search; i++) 
-       for (j = 1; j < 10 && !abort_search; j++) 
-         burner[j - 1] = burner[j - 1] * burner[j]; 
-     if (TimeCheck(tree, 1)) 
-       abort_search = 1; 
-   } 
- #endif 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  First lazy cutoff attempt.  If the material score is way * 
-  *  below alpha or way above beta (way above means so far    * 
-  *  above it is very unlikely the positional score can bring * 
-  *  the total score back into the alpha / beta window) then  * 
-  *  we take what is known as a "lazy evaluation exit" and    * 
-  *  avoid the computational cost of a full evaluation in a   * 
-  *  position where one side is way ahead or behind.          * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   cutoff = (TotalPieces(white, occupied) && TotalPieces(black, occupied)) 
-       ? KNIGHT_VALUE : ROOK_VALUE; 
-   lscore = MaterialSTM(wtm); 
-   if (lscore + cutoff < alpha) 
-     return alpha; 
-   if (lscore - cutoff > beta) 
-     return beta; 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  Check for draws where one side seems to be ahead, but    * 
-  *  has no actual winning chances.  One simple example is a  * 
-  *  king, bishop and rook pawn, with the wrong colored       * 
-  *  bishop and the enemy king too close to the promotion     * 
-  *  square.                                                  * 
-  *                                                           * 
-  *  The variable "can_win" uses 2 bits.  If White can        * 
-  *  actually win in this position, bit 1 is set.  If Black   * 
-  *  can actually win in this position, bit 0 is set.  If     * 
-  *  both sides can win, both bits are set.  This is used     * 
-  *  later to drag the score closer to a draw score if the    * 
-  *  side with the better score can't actually win.           * 
-  *                                                           * 
-  *  Note that we only set these bits in minimal material     * 
-  *  positions (both sides have < 13 points of material       * 
-  *  total).  Otherwise we assume normal scoring should       * 
-  *  apply.                                                   * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   tree->evaluations++; 
-   tree->score_mg = 0; 
-   tree->score_eg = 0; 
-   EvaluateMaterial(tree, wtm); 
-   if (TotalPieces(white, occupied) < 13 && TotalPieces(black, occupied) < 13) 
-     for (side = black; side <= white; side++) 
-       if (!EvaluateWinningChances(tree, side, wtm)) 
-         can_win ^= (1 << side); 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  Determine if this position should be evaluated to force  * 
-  *  mate (neither side has pawns) or if it should be         * 
-  *  evaluated normally.                                      * 
-  *                                                           * 
-  *  Note the special case of no pawns, one side is ahead in  * 
-  *  total material, but the game is a hopeless draw.  KRN vs * 
-  *  KR is one example.  If EvaluateWinningChances()          * 
-  *  determines that the side with extra material can not     * 
-  *  win, the score is pulled closer to a draw although it    * 
-  *  can not collapse completely to the drawscore as it is    * 
-  *  possible to lose KRB vs KR if the KR side lets the king  * 
-  *  get trapped on the edge of the board.                    * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   tree->all_pawns = Pawns(black) | Pawns(white); 
-   if (!tree->all_pawns) { 
-     if (TotalPieces(white, occupied) > 3 || TotalPieces(black, occupied) > 3) { 
-       if (Material > 0) 
-         EvaluateMate(tree, white); 
-       else if (Material < 0) 
-         EvaluateMate(tree, black); 
-       if (tree->score_eg > DrawScore(1) && !(can_win & 2)) 
-         tree->score_eg = tree->score_eg / 16; 
-       if (tree->score_eg < DrawScore(1) && !(can_win & 1)) 
-         tree->score_eg = tree->score_eg / 16; 
- #if defined(SKILL) 
-       if (skill < 100) 
-         tree->score_eg = (int) // Pierre-Marie Baty -- added type cast 
-             (skill * tree->score_eg / 100 + ((100 - 
-                 skill) * PAWN_VALUE * (uint64_t) Random32() / 
-             0x100000000ull) / 100); 
- #endif 
-       return (wtm) ? tree->score_eg : -tree->score_eg; 
-     } 
-   } 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  Now evaluate pawns.  If the pawn hash signature has not  * 
-  *  changed from the last entry to Evaluate() then we        * 
-  *  already have everything we need in the pawn hash entry.  * 
-  *  In this case, we do not need to call EvaluatePawns() at  * 
-  *  all.  EvaluatePawns() does all of the analysis for       * 
-  *  information specifically regarding only pawns.  In many  * 
-  *  cases, it merely records the presence/absence of         * 
-  *  positional pawn features because those features also     * 
-  *  depends on pieces.                                       * 
-  *                                                           * 
-  *  Note that anything put into EvaluatePawns() can only     * 
-  *  consider the placement of pawns.  Kings or other pieces  * 
-  *  can not influence the score because those pieces are not * 
-  *  hashed into the pawn hash signature.  Violating this     * 
-  *  principle leads to lots of very difficult and            * 
-  *  challenging debugging problems.                          * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   else { 
-     if (PawnHashKey == tree->pawn_score.key) { 
-       tree->score_mg += tree->pawn_score.score_mg; 
-       tree->score_eg += tree->pawn_score.score_eg; 
-     } 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  First check to see if this position has been handled     * 
-  *  before.  If so, we can skip the work saved in the pawn   * 
-  *  hash table.                                              * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-     else { 
-       ptable = pawn_hash_table + (PawnHashKey & pawn_hash_mask); 
-       pxtable = (PXOR *) & (tree->pawn_score); 
-       tree->pawn_score = *ptable; 
-       tree->pawn_score.key ^= pxtable->entry[1] ^ pxtable->entry[2]; 
-       if (tree->pawn_score.key != PawnHashKey) { 
-         tree->pawn_score.key = PawnHashKey; 
-         tree->pawn_score.score_mg = 0; 
-         tree->pawn_score.score_eg = 0; 
-         for (side = black; side <= white; side++) 
-           EvaluatePawns(tree, side); 
-         ptable->key = 
-             pxtable->entry[0] ^ pxtable->entry[1] ^ pxtable->entry[2]; 
-         memcpy((char *)-  ptable  + 8, (char *) &(- tree ->- pawn_score ) + 8,
 
-             sizeof(PAWN_HASH_ENTRY) - 8); 
-       } 
-       tree->score_mg += tree->pawn_score.score_mg; 
-       tree->score_eg += tree->pawn_score.score_eg; 
-     } 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  If there are any passed pawns, first call                * 
-  *  EvaluatePassedPawns() to evaluate them.  Then, if one    * 
-  *  side has a passed pawn and the other side has no pieces, * 
-  *  call EvaluatePassedPawnRaces() to see if the passed pawn * 
-  *  can be stopped from promoting.                           * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-     if (tree->pawn_score.passed[black] || tree->pawn_score.passed[white]) { 
-       for (side = black; side <= white; side++) 
-         if (tree->pawn_score.passed[side]) 
-           EvaluatePassedPawns(tree, side, wtm); 
-       if ((TotalPieces(white, occupied) == 0 && 
-               tree->pawn_score.passed[black]) 
-           || (TotalPieces(black, occupied) == 0 && 
-               tree->pawn_score.passed[white])) 
-         EvaluatePassedPawnRaces(tree, wtm); 
-     } 
-   } 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  Call EvaluateCastling() to evaluate castling potential.  * 
-  *   Note we  only do this when that side has not castled at * 
-  *  the root.                                                * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   for (side = black; side <= white; side++) 
-     if (Castle(1, side) > 0) 
-       EvaluateCastling(tree, ply, side); 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  The "dangerous" flag simply indicates whether that side  * 
-  *  has enough material to whip up a mating attack if the    * 
-  *  other side is careless (Q + minor or better, or RR + two * 
-  *  minors or better).                                       * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   tree->dangerous[white] = (Queens(white) && TotalPieces(white, occupied) > 9) 
-       || (TotalPieces(white, rook) > 1 && TotalPieces(white, occupied) > 15); 
-   tree->dangerous[black] = (Queens(black) && TotalPieces(black, occupied) > 9) 
-       || (TotalPieces(black, rook) > 1 && TotalPieces(black, occupied) > 15); 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  Second lazy evaluation test.  We have computed the large * 
-  *  positional scores (except for king safety).  If the      * 
-  *  score is too far outside the alpha/beta window, we skip  * 
-  *  the piece scoring which is the most expensive of all the * 
-  *  evaluation terms, and simply use what we have at this    * 
-  *  point.                                                   * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   phase = 
-       Min(62, TotalPieces(white, occupied) + TotalPieces(black, occupied)); 
-   score = ((tree->score_mg * phase) + (tree->score_eg * (62 - phase))) / 62; 
-   lscore = (wtm) ? score : -score; 
-   int w_mat = (2 * TotalPieces(white, rook)) + TotalPieces(white, 
-       knight) + TotalPieces(white, bishop); 
-   int b_mat = (2 * TotalPieces(black, rook)) + TotalPieces(black, 
-       knight) + TotalPieces(black, bishop); 
-   cutoff  = 72 + (- w_mat  +-  b_mat ) * 8 + abs(- w_mat  --  b_mat ) * 16;
-   if (tree->dangerous[white] || tree->dangerous[black]) 
-     cutoff += 35; 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  Then evaluate pieces if the lazy eval test fails.        * 
-  *                                                           * 
-  *  Note:  We MUST evaluate kings last, since their scoring  * 
-  *  depends on the tropism scores computed by the other      * 
-  *  piece evaluators.  Do NOT try to collapse the following  * 
-  *  loops into one loop.  That will break things since it    * 
-  *  would violate the kings last rule.  More importantly     * 
-  *  there is no benefit as the loops below are unrolled by   * 
-  *  the compiler anyway.                                     * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   if (lscore + cutoff > alpha && lscore - cutoff < beta) { 
-     tree->tropism[white] = 0; 
-     tree->tropism[black] = 0; 
-     for (side = black; side <= white; side++) 
-       if (Knights(side)) 
-         EvaluateKnights(tree, side); 
-     for (side = black; side <= white; side++) 
-       if (Bishops(side)) 
-         EvaluateBishops(tree, side); 
-     for (side = black; side <= white; side++) 
-       if (Rooks(side)) 
-         EvaluateRooks(tree, side); 
-     for (side = black; side <= white; side++) 
-       if (Queens(side)) 
-         EvaluateQueens(tree, side); 
-     for (side = black; side <= white; side++) 
-       EvaluateKing(tree, ply, side); 
-   } 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  Caclulate the final score, which is interpolated between * 
-  *  the middlegame score and endgame score based on the      * 
-  *  material left on the board.                              * 
-  *                                                           * 
-  *  Adjust the score if one side can't win, but the score    * 
-  *  actually favors that side significantly.                 * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   score = ((tree->score_mg * phase) + (tree->score_eg * (62 - phase))) / 62; 
-   score = EvaluateDraws(tree, ply, can_win, score); 
- #if defined(SKILL) 
-   if (skill < 100) 
-     score = (int) // Pierre-Marie Baty -- added type cast 
-         (skill * score / 100 + ((100 - 
-             skill) * PAWN_VALUE * (uint64_t) Random32() / 0x100000000ull) / 
-         100); 
- #endif 
-   return (wtm) ? score : -score; 
- } 
-   
- /* last modified 10/19/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *  EvaluateBishops() is used to evaluate bishops.                             * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateBishops(TREE * RESTRICT tree, int side) { 
-   uint64_t temp, moves; 
-   int square, special, i, mobility; 
-   int score_eg = 0, score_mg = 0, enemy = Flip(side), tpawns; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  First, locate each bishop and add in its piece/square   * 
-  *  table score.                                            * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   for (temp = Bishops(side); temp; temp &= temp - 1) { 
-     square = LSB(temp); 
-     score_mg += bval[mg][side][square]; 
-     score_eg += bval[eg][side][square]; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Evaluate for "outposts" which is a bishop that can't be * 
-  *  driven off by an enemy pawn, and which is supported by  * 
-  *  a friendly pawn.                                        * 
-  *                                                          * 
-  *  If the enemy has NO minor to take this bishop, then     * 
-  *  increase the bonus.                                     * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     special = bishop_outpost[side][square]; 
-     if (special) { 
-       if (!(mask_pattacks[enemy][square] & Pawns(enemy))) { 
-         if (pawn_attacks[enemy][square] & Pawns(side)) { 
-           special += special / 2; 
-           if (!Knights(enemy) && !(Color(square) & Bishops(enemy))) 
-             special += bishop_outpost[side][square]; 
-         } 
-         score_eg += special; 
-         score_mg += special; 
-       } 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Next we count the number of friendly pawns on the same  * 
-  *  color squares as the bishop.  This is a bad thing since * 
-  *  it restricts the bishop's ability to move.  We only do  * 
-  *  this if there is only one bishop for this side.         * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (TotalPieces(side, bishop) == 1) { 
-       if (dark_squares & SetMask(square)) 
-         tpawns = PopCnt(dark_squares & Pawns(side)); 
-       else 
-         tpawns = PopCnt(~dark_squares & Pawns(side)); 
-       score_mg -= tpawns * bishop_pawns_on_color[mg]; 
-       score_eg -= tpawns * bishop_pawns_on_color[eg]; 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Mobility counts the number of squares the bishop        * 
-  *  attacks, excluding squares with friendly pieces, and    * 
-  *  weighs each square according to centralization.         * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     mobility = BishopMobility(square, OccupiedSquares); 
-     if (mobility < 0 && (pawn_attacks[enemy][square] & Pawns(side)) 
-         && (File(square) == FILEA || File(square) == FILEH)) 
-       mobility -= 8; 
-     score_mg += mobility; 
-     score_eg += mobility; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Adjust the tropism count for this piece.                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (tree->dangerous[side]) { 
-       moves = king_attacks[KingSQ(enemy)]; 
-       i = ((bishop_attacks[square] & moves) && 
-           ((BishopAttacks(square, OccupiedSquares & ~Queens(side))) & moves)) 
-           ? 1 : Distance(square, KingSQ(enemy)); 
-       tree->tropism[side] += king_tropism_b[i]; 
-     } 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Add a bonus if this side has a pair of bishops, which   * 
-  *  can become very strong in open positions.               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (TotalPieces(side, bishop) > 1) { 
-     score_mg += bishop_pair[mg]; 
-     score_eg += bishop_pair[eg]; 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Check for pawns on both wings, which makes a bishop     * 
-  *  even more valuable against an enemy knight              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   else { 
-     if (tree->all_pawns & mask_fgh && tree->all_pawns & mask_abc) { 
-       score_mg += bishop_wing_pawns[mg]; 
-       score_eg += bishop_wing_pawns[eg]; 
-     } 
-   } 
-   tree->score_mg += sign[side] * score_mg; 
-   tree->score_eg += sign[side] * score_eg; 
- } 
-   
- /* last modified 01/03/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateCastling() is called when "side" has not castled at the root.     * 
-  *   Its main purpose is to determine if it has either castled somewhere in    * 
-  *   the tree, or else has lost all (or some) castling rights, which reduces   * 
-  *   options significantly.                                                    * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateCastling(TREE * RESTRICT tree, int ply, int side) { 
-   int enemy = Flip(side), oq, score_mg = 0;; 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If the king castled during the search, we are done and  * 
-  *  we leave it to EvaluateKing() to figure out how safe it * 
-  *  is.  If it has not castled, we give a significant       * 
-  *  penalty if the king moves since that loses all castling * 
-  *  rights, otherwise we give a smaller penalty for moving  * 
-  *  a rook and giving up castling rights to that side of    * 
-  *  the board.  The penalty is always increased if the      * 
-  *  opponent has a queen since the position is much more    * 
-  *  dangerous.                                              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   oq = (Queens(enemy)) ? 3 : 1; 
-   if (Castle(ply, side) != Castle(1, side)) { 
-     if (Castle(ply, side) == 0) 
-       score_mg -= oq * development_losing_castle; 
-     else if (Castle(ply, side) > 0) 
-       score_mg -= (oq * development_losing_castle) / 2; 
-   } else 
-     score_mg -= oq * development_not_castled; 
-   tree->score_mg += sign[side] * score_mg; 
- } 
-   
- /* last modified 01/03/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateDraws() is used to adjust the score based on whether the side     * 
-  *   that appears to be better according the computed score can actually win   * 
-  *   the game or not.  If the answer is "no" then the score is reduced         * 
-  *   significantly to reflect the lack of winning chances.                     * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- int EvaluateDraws(TREE * RESTRICT tree, int ply, int can_win, int score) { 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If the ending has only bishops of opposite colors, the  * 
-  *  score is pulled closer to a draw.                       * 
-  *                                                          * 
-  *  If this is a pure BOC ending, it is very drawish unless * 
-  *  one side has at least 4 pawns.  More pawns makes it     * 
-  *  harder for a bishop and king to stop them all from      * 
-  *  advancing.                                              * 
-  *                                                          * 
-  *  If the following are both true:                         * 
-  *                                                          * 
-  *    black and white have less than a queen left (pieces   * 
-  *    only).                                                * 
-  *                                                          * 
-  *    both have one bishop and they are opposite colored.   * 
-  *                                                          * 
-  *  then either                                             * 
-  *                                                          * 
-  *    (a) both have just one bishop, both have less than 4  * 
-  *    pawns or one side has only one more pawn than the     * 
-  *    other side then score is divided by 2 with draw score * 
-  *    added in; or                                          * 
-  *                                                          * 
-  *    (b) pieces are equal, then score is reduced by 25%    * 
-  *    with draw score added in.                             * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (TotalPieces(white, occupied) <= 8 && TotalPieces(black, occupied) <= 8) { 
-     if (TotalPieces(white, bishop) == 1 && TotalPieces(black, bishop) == 1) 
-       if (square_color[LSB(Bishops(black))] != 
-           square_color[LSB(Bishops(white))]) { 
-         if (TotalPieces(white, occupied) == 3 && 
-             TotalPieces(black, occupied) == 3 && 
-             ((TotalPieces(white, pawn) < 4 && TotalPieces(black, pawn) < 4) 
-                 || Abs(TotalPieces(white, pawn) - TotalPieces(black, 
-                         pawn)) < 2)) 
-           score = score / 2 + DrawScore(1); 
-         else if (TotalPieces(white, occupied) == TotalPieces(black, occupied)) 
-           score = 3 * score / 4 + DrawScore(1); 
-       } 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Final score adjustment.  If the score says white is     * 
-  *  better, but can_win says white can not win, or if the   * 
-  *  score says black is better, but can_win says black can  * 
-  *  not win, then we divide the score by 16, and then add   * 
-  *  in the draw score.  If the can_win says neither side    * 
-  *  can win, we just set the score to draw score and exit.  * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (can_win != 3) { 
-     if (can_win & 1) { 
-       if (score > DrawScore(1)) 
-         score = score / 16 + DrawScore(1); 
-     } else if (can_win & 2) { 
-       if (score < DrawScore(1)) 
-         score = score / 16 + DrawScore(1); 
-     } else 
-       score = DrawScore(1); 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If we are running into the 50-move rule, then start     * 
-  *  dragging the score toward draw.  This is the idea of a  * 
-  *  "weariness factor" as mentioned by Dave Slate many      * 
-  *  times.  This avoids slamming into a draw at move 50 and * 
-  *  having to move something quickly, rather than slowly    * 
-  *  discovering that the score is dropping and that pushing * 
-  *  a pawn or capturing something will cause it to go back  * 
-  *  to its correct value a bit more smoothly.               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (Reversible(ply) > 80) { 
-     int closeness = 101 - Reversible(ply); 
-   
-     score = DrawScore(1) + score * closeness / 20; 
-   } 
-   return score; 
- } 
-   
- /* last modified 01/03/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateHasOpposition() is used to determine if one king stands in        * 
-  *   "opposition" to the other.  If the kings are opposed on the same file or  * 
-  *   else are opposed on the same diagonal, then the side not-to-move has the  * 
-  *   opposition and the side-to-move must give way.                            * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- int EvaluateHasOpposition(int on_move, int king, int enemy_king) { 
-   int file_distance, rank_distance; 
-   
-   file_distance = FileDistance(king, enemy_king); 
-   rank_distance = RankDistance(king, enemy_king); 
-   if (rank_distance < 2) 
-     return 1; 
-   if (on_move) { 
-     if (rank_distance & 1) 
-       rank_distance--; 
-     if (file_distance & 1) 
-       file_distance--; 
-   } 
-   if (!(file_distance & 1) && !(rank_distance & 1)) 
-     return 1; 
-   return 0; 
- } 
-   
- /* last modified 01/03/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateKing() is used to evaluate a king.                                * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateKing(TREE * RESTRICT tree, int ply, int side) { 
-   int score_eg = 0, score_mg = 0, defects; 
-   int ksq = KingSQ(side), enemy = Flip(side); 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  First, check for where the king should be if this is an * 
-  *  endgame.  The basic idea is to centralize unless the    * 
-  *  king is needed to deal with a passed enemy pawn.        * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   score_eg += kval[side][ksq]; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Do castle scoring, if the king has castled, the pawns   * 
-  *  in front are important.  If not castled yet, the pawns  * 
-  *  on the kingside should be preserved for this.           * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (tree->dangerous[enemy]) { 
-     defects = 0; 
-     if (Castle(ply, side) <= 0) { 
-       if (File(ksq) > FILEE) 
-         defects = tree->pawn_score.defects_k[side]; 
-       else if (File(ksq) < FILED) 
-         defects = tree->pawn_score.defects_q[side]; 
-       else 
-         defects = tree->pawn_score.defects_m[side]; 
-     } else { 
-       if (Castle(ply, side) == 3) 
-         defects = 
-             Min(Min(tree->pawn_score.defects_k[side], 
-                 tree->pawn_score.defects_m[side]), 
-             tree->pawn_score.defects_q[side]); 
-       else if (Castle(ply, side) == 1) 
-         defects = 
-             Min(tree->pawn_score.defects_k[side], 
-             tree->pawn_score.defects_m[side]); 
-       else 
-         defects = 
-             Min(tree->pawn_score.defects_q[side], 
-             tree->pawn_score.defects_m[side]); 
-       if (defects < 3) 
-         defects = 3; 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Fold in the king tropism and king pawn shelter scores   * 
-  *  together.                                               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (tree->tropism[enemy] < 0) 
-       tree->tropism[enemy] = 0; 
-     else if (tree->tropism[enemy] > 15) 
-       tree->tropism[enemy] = 15; 
-     if (defects > 15) 
-       defects = 15; 
-     score_mg -= king_safety[defects][tree->tropism[enemy]]; 
-   } 
-   tree->score_mg += sign[side] * score_mg; 
-   tree->score_eg += sign[side] * score_eg; 
- } 
-   
- /* last modified 01/03/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateKingsFile computes defects for a file, based on whether the file  * 
-  *   is open or half-open.  If there are friendly pawns still on the file,     * 
-  *   they are penalized for advancing in front of the king.                    * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- int EvaluateKingsFile(TREE * RESTRICT tree, int side, int first, int last) { 
-   int defects = 0, file, enemy = Flip(side); 
-   
-   for (file = first; file <= last; file++) 
-     if (!(file_mask[file] & tree->all_pawns)) 
-       defects += open_file[file]; 
-     else { 
-       if (!(file_mask[file] & Pawns(enemy))) 
-         defects += half_open_file[file] / 2; 
-       else 
-         defects += 
-             pawn_defects[side][Rank(MostAdvanced(enemy, 
-                     file_mask[file] & Pawns(enemy)))]; 
-       if (!(file_mask[file] & Pawns(side))) 
-         defects += half_open_file[file]; 
-       else if (!(Pawns(side) & SetMask(sqflip[side][A2] + file))) { 
-         defects++; 
-         if (!(Pawns(side) & SetMask(sqflip[side][A3] + file))) 
-           defects++; 
-       } 
-     } 
-   return defects; 
- } 
-   
- /* last modified 10/19/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateKnights() is used to evaluate knights.                            * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateKnights(TREE * RESTRICT tree, int side) { 
-   uint64_t temp; 
-   int square, special, i, score_eg = 0, score_mg = 0, enemy = Flip(side); 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  First fold in centralization score from the piece/      * 
-  *  square table "nval".                                    * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   for (temp = Knights(side); temp; temp &= temp - 1) { 
-     square = LSB(temp); 
-     score_mg += nval[mg][side][square]; 
-     score_eg += nval[eg][side][square]; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Evaluate for "outposts" which is a knight that can't    * 
-  *  be driven off by an enemy pawn, and which is supported  * 
-  *  by a friendly pawn.                                     * 
-  *                                                          * 
-  *  If the enemy has NO minor to take this knight, then     * 
-  *  increase the bonus.                                     * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     special = knight_outpost[side][square]; 
-     if (special && !(mask_pattacks[enemy][square] & Pawns(enemy))) { 
-       if (pawn_attacks[enemy][square] & Pawns(side)) { 
-         special += special / 2; 
-         if (!Knights(enemy) && !(Color(square) & Bishops(enemy))) 
-           special += knight_outpost[side][square]; 
-       } 
-       score_eg += special; 
-       score_mg += special; 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Adjust the tropism count for this piece.                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (tree->dangerous[side]) { 
-       i = Distance(square, KingSQ(enemy)); 
-       tree->tropism[side] += king_tropism_n[i]; 
-     } 
-   } 
-   tree->score_mg += sign[side] * score_mg; 
-   tree->score_eg += sign[side] * score_eg; 
- } 
-   
- /* last modified 03/30/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateMate() is used to evaluate positions where neither side has pawns * 
-  *   and one side has enough material to force checkmate.  It simply trys to   * 
-  *   force the losing king to the edge of the board, and then to the corner    * 
-  *   where mates are easier to find.                                           * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateMate(TREE * RESTRICT tree, int side) { 
-   int mate_score = 0, enemy = Flip(side); 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If the winning side has a bishop + knight and the other * 
-  *  side has no pieces or pawns, then use the special       * 
-  *  bishop_knight scoring board for the losing king to      * 
-  *  force it to the right corner for mate.                  * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (!TotalPieces(enemy, occupied) && TotalPieces(side, bishop) == 1 && 
-       TotalPieces(side, knight) == 1) { 
-     if (dark_squares & Bishops(side)) 
-       mate_score = b_n_mate_dark_squares[KingSQ(enemy)]; 
-     else 
-       mate_score = b_n_mate_light_squares[KingSQ(enemy)]; 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  The winning side has to force the losing king to the    * 
-  *  edge of the board.                                      * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   else 
-     mate_score = mate[KingSQ(enemy)]; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  And for either, it is important to bring the winning    * 
-  *  king to help force mate.                                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   mate_score -= Distance(KingSQ(side), KingSQ(enemy)) * king_king_tropism; 
-   tree->score_eg += sign[side] * mate_score; 
- } 
-   
- /* last modified 10/19/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *  EvaluateMaterial() is used to evaluate material on the board.  It really   * 
-  *  accomplishes detecting cases where one side has made a 'bad trade' as the  * 
-  *  comments below show.                                                       * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateMaterial(TREE * RESTRICT tree, int wtm) { 
-   int score_mg, score_eg, majors, minors; 
-   
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  We start with the raw Material balance for the current   * 
-  *  position, then adjust this with a small bonus for the    * 
-  *  side on move.                                            * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   score_mg = Material + ((wtm) ? wtm_bonus[mg] : -wtm_bonus[mg]); 
-   score_eg = Material + ((wtm) ? wtm_bonus[eg] : -wtm_bonus[eg]); 
- /* 
-  ************************************************************* 
-  *                                                           * 
-  *  test 1.  if Majors or Minors are not balanced, then if   * 
-  *  one side is only an exchange up or down, we give a       * 
-  *  penalty to the side that is an exchange down, but not as * 
-  *  big a penalty as the bad trade case below.               * 
-  *                                                           * 
-  *  test 2.  if Majors or Minors are not balanced, then if   * 
-  *  one side has more piece material points than the other   * 
-  *  (using normal piece values of 3, 3, 5, 9 for N, B, R     * 
-  *  and Q) then the side that is behind in piece material    * 
-  *  gets a penalty.                                          * 
-  *                                                           * 
-  ************************************************************* 
-  */ 
-   majors = 
-       TotalPieces(white, rook) + 2 * TotalPieces(white, 
-       queen) - TotalPieces(black, rook) - 2 * TotalPieces(black, queen); 
-   minors = 
-       TotalPieces(white, knight) + TotalPieces(white, 
-       bishop) - TotalPieces(black, knight) - TotalPieces(black, bishop); 
-   if (majors || minors) { 
-     if (Abs(TotalPieces(white, occupied) - TotalPieces(black, occupied)) != 2 
-         && TotalPieces(white, occupied) - TotalPieces(black, occupied) != 0) { 
-       score_mg += 
-           Sign(TotalPieces(white, occupied) - TotalPieces(black, 
-               occupied)) * bad_trade; 
-       score_eg += 
-           Sign(TotalPieces(white, occupied) - TotalPieces(black, 
-               occupied)) * bad_trade; 
-     } 
-   } 
-   tree->score_mg += score_mg; 
-   tree->score_eg += score_eg; 
- } 
-   
- /* last modified 11/27/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluatePassedPawns() is used to evaluate passed pawns and the danger     * 
-  *   they produce.  This code considers pieces as well, so it MUST NOT be done * 
-  *   in the normal EvaluatePawns() code since that hashes information based    * 
-  *   only on the position of pawns.                                            * 
-  *                                                                             * 
-  *   This is a significant rewrite of passed pawn evaluation, with the primary * 
-  *   change being to collect the passed pawn scoring into one place, rather    * 
-  *   than have it scattered around all over the place.  One example is the old * 
-  *   rook_behind_passed_pawn scoring term that was done in rook scoring.  It   * 
-  *   is now done here along with other passed pawn terms such as blockaded and * 
-  *   the ability to advance or not.                                            * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluatePassedPawns(TREE * RESTRICT tree, int side, int wtm) { 
-   uint64_t behind, forward, backward, attacked, defended, thispawn; 
-   int file, square, score, score_mg = 0, score_eg = 0, next_sq; 
-   int pawns, rank, mg_base, eg_base, bonus, enemy = Flip(side); 
-   uint64_t fsliders = Queens(side) | Rooks(side); 
-   uint64_t esliders = Queens(enemy) | Rooks(enemy); 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Initialize.  The base value "passed_pawn[rank]" is      * 
-  *  almost the "square" of the rank.  That got a bit too    * 
-  *  big, so a hand-tuned set of values, one per rank,       * 
-  *  proved to be a better value.                            * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   for (pawns = tree->pawn_score.passed[side]; pawns; pawns &= pawns - 1) { 
-     file = LSB8Bit(pawns); 
-     thispawn = Pawns(side) & file_mask[file]; 
-     if (thispawn) { 
-       square = MostAdvanced(side, thispawn); 
-       rank = rankflip[side][Rank(square)]; 
-       score = passed_pawn[rank]; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  For endgame only, we add in a bonus based on how close  * 
-  *  our king is to this pawn and a penalty based on how     * 
-  *  close the enemy king is.  We also try to keep our king  * 
-  *  ahead of the pawn so it can escort it to promotion.  We * 
-  *  only do this for passed pawns whose base score value is * 
-  *  greater than zero (ie pawns on ranks 4-7 since those    * 
-  *  are the ones threatening to become a major problem.)    * 
-  *  Also, if you happen to think that a small bonus for a   * 
-  *  passed pawn on the 3rd rank might be useful, consider   * 
-  *  speed.  If the 3rd rank score is non-zero, that will    * 
-  *  trigger a significant amount of work below.  In testing * 
-  *  the additional cost more than offset the gain and so it * 
-  *  is basically ignored unless rank > 3.                   * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-       if (score) { 
-         mg_base = score * passed_pawn_base[mg]; 
-         eg_base = score * passed_pawn_base[eg]; 
-         next_sq = square + direction[side]; 
-         eg_base += 
-             Distance(KingSQ(enemy), 
-             next_sq) * 2 * score - Distance(KingSQ(side), next_sq) * score; 
-         if (rank < RANK7) 
-           eg_base -= 
-               Distance(KingSQ(side), next_sq + direction[side]) * score / 2; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If the pawn is not blockaded, we need to see whether it * 
-  *  can actually advance or not.  Note that this directly   * 
-  *  gives a bonus for blockading a passed pawn since the    * 
-  *  mobility evaluation below will not be applied when the  * 
-  *  pawn is blockaded by any piece.                         * 
-  *                                                          * 
-  *  Step one is to determine if the squares in front of the * 
-  *  pawn are attacked by the enemy.  If not, we add in a    * 
-  *  significant score bonus.  If some are attacked, we look * 
-  *  to see if at least the square directly in front of the  * 
-  *  pawn is not attacked so that we can advance one square, * 
-  *  anyway.  This gets a smaller score bonus.               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (!(OccupiedSquares & SetMask(next_sq))) { 
-           bonus = 0; 
-           if (Pawns(side) & pawn_attacks[enemy][next_sq]) 
-             bonus = passed_pawn_free_advance; 
-           else { 
-             attacked = 0; 
-             forward = (side) ? plus8dir[square] : minus8dir[square]; 
-             backward = (side) ? minus8dir[square] : plus8dir[square]; 
-             if ((behind = backward & esliders) && 
-                 (FileAttacks(square) & behind)) 
-               attacked = forward; 
-             else 
-               attacked = Attacked(tree, enemy, forward); 
-             if (!attacked) 
-               bonus = passed_pawn_free_advance; 
-             else if (!(attacked & SetMask(next_sq))) 
-               bonus = passed_pawn_free_advance_1; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Step two is to determine if the squares in front of the * 
-  *  pawn are are defended by the friendly side.  If all are * 
-  *  defended (such as with a rook or queen behind the pawn  * 
-  *  or the king in front and to one side of the pawn, then  * 
-  *  we give a bonus (but smaller than the previous cases).  * 
-  *  As a last resort, if we at least defend the square in   * 
-  *  front of the pawn, we give a small bonus.               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-             if ((behind = backward & fsliders) && 
-                 (FileAttacks(square) & behind)) 
-               defended = forward; 
-             else 
-               defended = Attacked(tree, side, forward); 
-             if (defended == forward) 
-               bonus += passed_pawn_defended; 
-             else if (defended & SetMask(next_sq)) 
-               bonus += passed_pawn_defended_1; 
-           } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Fold in the bonus for this pawn and move on to the next * 
-  *  (if there is one).  Note that the bonus computed above  * 
-  *  is multiplied by the base passed pawn score for this    * 
-  *  particular rank.                                        * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-           mg_base += bonus * score; 
-           eg_base += bonus * score; 
-         } 
-         score_mg += mg_base; 
-         score_eg += eg_base; 
-       } else 
-         score_eg += 4; 
-     } 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  All pawns done, add score to the two evaluation values  * 
-  *  and return.                                             * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   tree->score_mg += sign[side] * score_mg; 
-   tree->score_eg += sign[side] * score_eg; 
- } 
-   
- /* last modified 11/27/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluatePassedPawnRaces() is used to evaluate passed pawns when one       * 
-  *   side has passed pawns and the other side (or neither) has pieces.  In     * 
-  *   such a case, the critical question is can the defending king stop the     * 
-  *   pawn from queening or is it too far away?  If only one side has pawns     * 
-  *   that can "run" then the situation is simple.  When both sides have pawns  * 
-  *   that can "run" it becomes more complex as it then becomes necessary to    * 
-  *   see if one side can use a forced king move to stop the other side, while  * 
-  *   the other side doesn't have the same ability to stop ours.                * 
-  *                                                                             * 
-  *   In the case of king and pawn endings with exactly one pawn, the simple    * 
-  *   evaluation rules are used:  if the king is two squares in front of the    * 
-  *   pawn then it is a win, if the king is one one square in front with the    * 
-  *   opposition, then it is a win,  if the king is on the 6th rank with the    * 
-  *   pawn close by, it is a win.  Rook pawns are handled separately and are    * 
-  *   more difficult to queen because the king can get trapped in front of the  * 
-  *   pawn blocking promotion.                                                  * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluatePassedPawnRaces(TREE * RESTRICT tree, int wtm) { 
-   uint64_t pawns, thispawn; 
-   int file, square, queen_distance, pawnsq, passed, side, enemy; 
-   int queener[2] = { 8, 8 }; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Check to see if side has one pawn and neither side has  * 
-  *  any pieces.  If so, use the simple pawn evaluation      * 
-  *  logic.                                                  * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   for (side = black; side <= white; side++) { 
-     enemy = Flip(side); 
-     if (Pawns(side) && !Pawns(enemy) && TotalPieces(white, occupied) == 0 && 
-         TotalPieces(black, occupied) == 0) { 
-       for (pawns = Pawns(side); pawns; pawns &= pawns - 1) { 
-         pawnsq = LSB(pawns); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  King must be in front of the pawn or we go no further.  * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (sign[side] * Rank(KingSQ(side)) <= sign[side] * Rank(pawnsq)) 
-           continue; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  First a special case.  If this is a rook pawn, then the * 
-  *  king must be on the adjacent file, and be closer to the * 
-  *  queening square than the opposing king.                 * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (File(pawnsq) == FILEA) { 
-           if (File(KingSQ(side)) == FILEB && 
-               Distance(KingSQ(side), 
-                   sqflip[side][A8]) < Distance(KingSQ(enemy), 
-                   sqflip[side][A8])) { 
-             tree->score_eg += sign[side] * pawn_can_promote; 
-             return; 
-           } 
-           continue; 
-         } else if (File(pawnsq) == FILEH) { 
-           if (File(KingSQ(side)) == FILEG && 
-               Distance(KingSQ(side), 
-                   sqflip[side][H8]) < Distance(KingSQ(enemy), 
-                   sqflip[side][H8])) { 
-             tree->score_eg += sign[side] * pawn_can_promote; 
-             return; 
-           } 
-           continue; 
-         } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If king is two squares in front of the pawn then it's a * 
-  *  win immediately.  If the king is on the 6th rank and    * 
-  *  closer to the pawn than the opposing king, it's also a  * 
-  *  win.                                                    * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (Distance(KingSQ(side), pawnsq) < Distance(KingSQ(enemy), pawnsq)) { 
-           if (sign[side] * Rank(KingSQ(side)) > 
-               sign[side] * (Rank(pawnsq) - 1 + 2 * side)) { 
-             tree->score_eg += sign[side] * pawn_can_promote; 
-             return; 
-           } 
-           if (Rank(KingSQ(side)) == rank6[side]) { 
-             tree->score_eg += sign[side] * pawn_can_promote; 
-             return; 
-           } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Last chance:  if the king is one square in front of the * 
-  *  pawn and has the opposition, then it's still a win.     * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-           if (Rank(KingSQ(side)) == Rank(pawnsq) - 1 + 2 * side && 
-               EvaluateHasOpposition(wtm == side, KingSQ(side), 
-                   KingSQ(enemy))) { 
-             tree->score_eg += sign[side] * pawn_can_promote; 
-             return; 
-           } 
-         } 
-       } 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Check to see if enemy is out of pieces and stm has      * 
-  *  passed pawns.  If so, see if any of these passed pawns  * 
-  *  can outrun the defending king and promote.              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (TotalPieces(enemy, occupied) == 0 && tree->pawn_score.passed[side]) { 
-       passed = tree->pawn_score.passed[side]; 
-       for (; passed; passed &= passed - 1) { 
-         file = LSB8Bit(passed); 
-         thispawn = Pawns(side) & file_mask[file]; 
-         if (thispawn) { 
-           square = MostAdvanced(side, thispawn); 
-           if (!(pawn_race[side][wtm][square] & Kings(enemy))) { 
-             queen_distance = Abs(rank8[side] - Rank(square)); 
-             if (Kings(side) & ((side) ? plus8dir[square] : minus8dir[square])) { 
-               if (file == FILEA || file == FILEH) 
-                 queen_distance = 99; 
-               queen_distance++; 
-             } 
-             if (Rank(square) == rank2[side]) 
-               queen_distance--; 
-             if (queen_distance < queener[side]) 
-               queener[side] = queen_distance; 
-           } 
-         } 
-       } 
-     } 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Now that we know which pawns can outrun the kings for   * 
-  *  each side, we need to do determine if one side queens   * 
-  *  before the other.  If so, that side wins.  If they      * 
-  *  queen at the same time, then we will have to rely on    * 
-  *  the search to handle queening with check or queening    * 
-  *  and attacking the opponent's queening square.           * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (queener[white] < queener[black]) 
-     tree->score_eg += pawn_can_promote + (5 - queener[white]) * 10; 
-   else if (queener[black] < queener[white]) 
-     tree->score_eg -= pawn_can_promote + (5 - queener[black]) * 10; 
- } 
-   
- /* last modified 11/27/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluatePawns() is used to evaluate pawns.  It evaluates pawns for only   * 
-  *   one side, and fills in the pawn hash entry information.  It requires two  * 
-  *   calls to evaluate all pawns on the board.  Comments below indicate the    * 
-  *   particular pawn structure features that are evaluated.                    * 
-  *                                                                             * 
-  *   This procedure also flags which pawns are passed, since this is scored in * 
-  *   another part of the evaluation because that includes piece information    * 
-  *   which can not be used here since the pawn hash signature does not include * 
-  *   piece information of any kind.                                            * 
-  *                                                                             * 
-  *   Note that a pawn is not penalized for two different reasons.  If it is    * 
-  *   isolated, it is not backward.  Etc.  This simplifies evaluation tuning    * 
-  *   not to mention eliminating the overlap and interaction that was happening * 
-  *   previously when multiple penalties could be applied.                      * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluatePawns(TREE * RESTRICT tree, int side) { 
-   uint64_t pawns, attackers, defenders; 
-   uint64_t doubled, supported, connected, passed, backward; 
-   int square, file, rank, score_eg = 0, score_mg = 0, enemy = Flip(side); 
-   unsigned int isolated, pawn_files = 0; 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Loop through all pawns for this side.                   * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   tree->pawn_score.passed[side] = 0; 
-   for (pawns = Pawns(side); pawns; pawns &= pawns - 1) { 
-     square = LSB(pawns); 
-     file = File(square); 
-     rank = rankflip[side][Rank(square)]; 
-     pawn_files |= 1 << file; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Evaluate pawn advances.  Center pawns are encouraged to * 
-  *  occupy central squares, edge pawns are penalized on all * 
-  *  edge squares to encourage capture toward the center,    * 
-  *  the rest are neutral.                                   * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     score_mg += pval[side][square]; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Evaluate isolated pawns, which are penalized based on   * 
-  *  which file they occupy.                                 * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     isolated = !(Pawns(side) & mask_pawn_isolated[square]); 
-     if (isolated) { 
-       score_mg -= pawn_isolated[mg][file]; 
-       score_eg -= pawn_isolated[eg][file]; 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Evaluate unsupported pawns, which provide a target      * 
-  *  since they are undefended by a pawn.  We exclude pawns  * 
-  *  that are isolated since they have already been given a  * 
-  *  penalty.                                                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     supported = Pawns(side) & pawn_attacks[enemy][square]; 
-     if (!isolated && !supported) { 
-       score_mg += pawn_unsupported[mg]; 
-       score_eg += pawn_unsupported[eg]; 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Evaluate doubled pawns.  If there are other pawns on    * 
-  *  this file in front of this pawn, penalize this pawn.    * 
-  *  Note that this will NOT penalize both pawns, just the   * 
-  *  most rearward one that is really almost worthless.      * 
-  *                                                          * 
-  *  The farther apart two doubled pawns (same file) are,    * 
-  *  the less weak they are, so the penalty is reduced as    * 
-  *  this distance increases.                                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     doubled = Pawns(side) & ((side) ? plus8dir[square] : minus8dir[square]); 
-     if (doubled) { 
-       score_mg -= 
-           pawn_doubled[mg][file] / RankDistance(square, MostAdvanced(side, 
-               doubled)); 
-       score_eg -= 
-           pawn_doubled[eg][file] / RankDistance(square, MostAdvanced(side, 
-               doubled)); 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Test the pawn to see if it is connected to a neighbor   * 
-  *  which makes it easier to defend.                        * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     connected = Pawns(side) & mask_pawn_connected[side][square]; 
-     if (connected) { 
-       score_mg += pawn_connected[mg][rank][file]; 
-       score_eg += pawn_connected[eg][rank][file]; 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Flag passed pawns for use later when we finally call    * 
-  *  EvaluatePassedPawns.                                    * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     passed = !(Pawns(enemy) & mask_passed[side][square]); 
-     if (passed) 
-       tree->pawn_score.passed[side] |= 1 << file; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Test the pawn to see if it is backward which makes it a * 
-  *  target that ties down pieces to defend it.              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     backward = 0; 
-     if (!(passed | isolated | connected | (Pawns(side) & 
-                 mask_pattacks[side][square]) | (Pawns(enemy) & 
-                 PawnAttacks(side, square)))) 
-       backward = Pawns(enemy) & PawnAttacks(side, square + direction[side]); 
-     if (backward) { 
-       score_mg -= pawn_backward[mg][file]; 
-       score_eg -= pawn_backward[eg][file]; 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Determine if this pawn is a candidate passed pawn,      * 
-  *  which is a pawn on a file with no enemy pawns in front  * 
-  *  of it, and if it advances until it contacts an enemy    * 
-  *  pawn, and it is defended at least as many times as it   * 
-  *  is attacked when it reaches that pawn, then it will end * 
-  *  up passed.                                              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (!(passed | backward | isolated) && 
-         !(Pawns(enemy) & ((side) ? plus8dir[square] : minus8dir[square]))) { 
-       defenders = mask_pattacks[side][square + direction[side]] & Pawns(side); 
-       attackers = mask_pattacks[enemy][square] & Pawns(enemy); 
-       if (PopCnt(defenders) >= PopCnt(attackers)) { 
-         score_mg += passed_pawn_candidate[mg][rank]; 
-         score_eg += passed_pawn_candidate[eg][rank]; 
-       } 
-     } 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Give a bonus for distance between left-most pawn and    * 
-  *  right-most pawn.  The idea is that the wider the gap    * 
-  *  between the pawns, the harder they are for a lone king  * 
-  *  to control in the endgame.  Botvinnik referred to this  * 
-  *  concept as "trousers" (pants with two legs, the farther * 
-  *  the legs are apart, the better for the side with those  * 
-  *  pawns).                                                 * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   score_eg += pawn_file_width * (MSB8Bit(pawn_files) - LSB8Bit(pawn_files)); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Evaluate king safety.                                   * 
-  *                                                          * 
-  *  This uses the function EvaluateKingsFile() and looks at * 
-  *  three possible positions for the king, either castled   * 
-  *  kingside, queenside or else standing on the d or e file * 
-  *  stuck in the middle.  This essentially is about the     * 
-  *  pawns in front of the king and what kind of "shelter"   * 
-  *  they provide for the king during the middlegame.        * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   tree->pawn_score.defects_q[side] = 
-       EvaluateKingsFile(tree, side, FILEA, FILEC); 
-   tree->pawn_score.defects_m[side] = 
-       EvaluateKingsFile(tree, side, FILEC, FILEF); 
-   tree->pawn_score.defects_k[side] = 
-       EvaluateKingsFile(tree, side, FILEF, FILEH); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Done.  Add mg/eg scores to final result (sign-corrected * 
-  *  so that black = -, white = +) and return.               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   tree->pawn_score.score_mg += sign[side] * score_mg; 
-   tree->pawn_score.score_eg += sign[side] * score_eg; 
- } 
-   
- /* last modified 10/19/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateQueens() is used to evaluate queens.                              * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateQueens(TREE * RESTRICT tree, int side) { 
-   uint64_t temp; 
-   int square, i, score_mg = 0, score_eg = 0, enemy = Flip(side); 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  First locate each queen and obtain it's centralization  * 
-  *  score from the static piece/square table for queens.    * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   for (temp = Queens(side); temp; temp &= temp - 1) { 
-     square = LSB(temp); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Then, add in the piece/square table value for the       * 
-  *  queen.                                                  * 
-  *                                                          * 
-  ************************************************************ 
- */ 
-     score_mg += qval[mg][side][square]; 
-     score_eg += qval[eg][side][square]; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Adjust the tropism count for this piece.                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (tree->dangerous[side]) { 
-       i = KingSQ(enemy); 
-       tree->tropism[side] += king_tropism_q[Distance(square, i)]; 
-       i = 8 - (RankDistance(square, i) + FileDistance(square, i)); 
-       score_mg += i; 
-       score_eg += i; 
-     } 
-   } 
-   tree->score_mg += sign[side] * score_mg; 
-   tree->score_eg += sign[side] * score_eg; 
- } 
-   
- /* last modified 10/19/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateRooks() is used to evaluate rooks.                                * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void EvaluateRooks(TREE * RESTRICT tree, int side) { 
-   uint64_t temp, moves; 
-   int square, rank, file, i, mobility, score_mg = 0, score_eg = 0; 
-   int enemy = Flip(side); 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Initialize.                                             * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   for (temp = Rooks(side); temp; temp &= temp - 1) { 
-     square = LSB(temp); 
-     file = File(square); 
-     rank = Rank(square); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Determine if the rook is on an open file or on a half-  * 
-  *  open file, either of which increases its ability to     * 
-  *  attack important squares.                               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (!(file_mask[file] & Pawns(side))) { 
-       if (!(file_mask[file] & Pawns(enemy))) { 
-         score_mg += rook_open_file[mg]; 
-         score_eg += rook_open_file[eg]; 
-       } else { 
-         score_mg += rook_half_open_file[mg]; 
-         score_eg += rook_half_open_file[eg]; 
-       } 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Mobility counts the number of squares the rook attacks, * 
-  *  excluding squares with friendly pieces, and weighs each * 
-  *  square according to a complex formula that includes     * 
-  *  files as well as total number of squares attacked.      * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     mobility = RookMobility(square, OccupiedSquares); 
-     score_mg += mobility; 
-     score_eg += mobility; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Check to see if the king has been forced to move and    * 
-  *  has trapped a rook at a1/b1/g1/h1, if so, then penalize * 
-  *  the trapped rook to help extricate it.  We only need to * 
-  *  check this if the rooks mobility is very low.           * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (mobility < 0 && rank == rank1[side] && rank == Rank(KingSQ(side))) { 
-       i = File(KingSQ(side)); 
-       if (i > FILEE) { 
-         if (file > i) { 
-           score_mg += mobility * 3; 
-           score_eg += mobility * 3; 
-         } 
-       } else if (i < FILED && file < i) { 
-         score_mg += mobility * 3; 
-         score_eg += mobility * 3; 
-       } 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *   finally check to see if any rooks are on the 7th rank, * 
-  *   with the opponent having pawns on that rank or the     * 
-  *   opponent's king being hemmed in on the 7th/8th rank.   * 
-  *   If so, we give a bonus for the strong rook.  If there  * 
-  *   is another rook or queen on the 7th that is connected  * 
-  *   with this one, then the positional advantage is even   * 
-  *   stronger.                                              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     else if (rank == rank7[side] && (Rank(KingSQ(enemy)) == rank8[side] 
-             || Pawns(enemy) & rank_mask[rank])) { 
-       score_mg += rook_on_7th[mg]; 
-       score_eg += rook_on_7th[eg]; 
-       if (RankAttacks(square) & (Queens(side) | Rooks(side))) { 
-         score_mg += rook_connected_7th[mg]; 
-         score_eg += rook_connected_7th[eg]; 
-       } 
-     } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Adjust the tropism count for this piece.                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (tree->dangerous[side]) { 
-       moves = king_attacks[KingSQ(enemy)]; 
-       i = (rook_attacks[square] & moves && 
-           RookAttacks(square, 
-               OccupiedSquares & ~(Queens(side) | Rooks(side))) & moves) ? 1 : 
-           Distance(square, KingSQ(enemy)); 
-       tree->tropism[side] += king_tropism_r[i]; 
-     } 
-   } 
-   tree->score_mg += sign[side] * score_mg; 
-   tree->score_eg += sign[side] * score_eg; 
- } 
-   
- /* last modified 01/03/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   EvaluateWinningChances() is used to determine if one side has reached a   * 
-  *   position which can not be won, period, even though side may be ahead in   * 
-  *   material in some way.                                                     * 
-  *                                                                             * 
-  *   Return values:                                                            * 
-  *          0    ->     side on move can not win.                              * 
-  *          1    ->     side on move can win.                                  * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- int EvaluateWinningChances(TREE * RESTRICT tree, int side, int wtm) { 
-   int square, ekd, promote, majors, minors, enemy = Flip(side); 
-   
-   if (!Pawns(side)) { 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If side has a piece and no pawn, it can not possibly    * 
-  *  win.  If side is a piece ahead, the only way it can win * 
-  *  is if the enemy is already trapped on the edge of the   * 
-  *  board (special case to handle KRB vs KR which can be    * 
-  *  won if the king gets trapped).                          * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (TotalPieces(side, occupied) <= 3) 
-       return 0; 
-     if (TotalPieces(side, occupied) - TotalPieces(enemy, occupied) <= 3 && 
-         mask_not_edge & Kings(enemy)) 
-       return 0; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If one side is an exchange up, but has no pawns, then   * 
-  *  that side can not possibly win.                         * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     majors = 
-         TotalPieces(white, rook) + 2 * TotalPieces(white, 
-         queen) - TotalPieces(black, rook) - 2 * TotalPieces(black, queen); 
-     if (Abs(majors) == 1) { 
-       minors = 
-           TotalPieces(black, knight) + TotalPieces(black, 
-           bishop) - TotalPieces(white, knight) - TotalPieces(white, bishop); 
-       if (majors == minors) 
-         return 0; 
-     } 
-   } else { 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If neither side has any pieces, and both sides have     * 
-  *  non-rookpawns, then either side can win.                * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-     if (TotalPieces(white, occupied) == 0 && TotalPieces(black, occupied) == 0 
-         && Pawns(white) & not_rook_pawns && Pawns(black) & not_rook_pawns) 
-       return 1; 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If "side" has a pawn, then either the pawn had better   * 
-  *  not be a rook pawn, or else side had better have the    * 
-  *  right color bishop or any other piece, otherwise it is  * 
-  *  not winnable if the enemy king can get to the queening  * 
-  *  square first.                                           * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (!(Pawns(side) & not_rook_pawns)) 
-     do { 
-       if (TotalPieces(side, occupied) > 3 || (TotalPieces(side, occupied) == 3 
-               && Knights(side))) 
-         continue; 
-       if (file_mask[FILEA] & Pawns(side) && file_mask[FILEH] & Pawns(side)) 
-         continue; 
-       if (Bishops(side)) { 
-         if (Bishops(side) & dark_squares) { 
-           if (file_mask[dark_corner[side]] & Pawns(side)) 
-             continue; 
-         } else if (file_mask[light_corner[side]] & Pawns(side)) 
-           continue; 
-       } 
-       if (Pawns(side) & file_mask[FILEA]) 
-         promote = A8; 
-       else 
-         promote = H8; 
-       ekd = Distance(KingSQ(enemy), sqflip[side][promote]) - (wtm != side); 
-       if (ekd <= 1) 
-         return 0; 
-     } while (0); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Check to see if this is a KRP vs KR ending.  If so, and * 
-  *  the losing king is in front of the passer, then this is * 
-  *  a drawish ending.                                       * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (TotalPieces(side, pawn) == 1 && TotalPieces(enemy, pawn) == 0 && 
-       TotalPieces(side, occupied) == 5 && TotalPieces(enemy, occupied) == 5) { 
-     square = LSB(Pawns(side)); 
-     if (FileDistance(KingSQ(enemy), square) <= 1 && 
-         InFront(side, Rank(KingSQ(enemy)), Rank(square))) 
-       return 0; 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If this side has pawns, and we have made it through the * 
-  *  previous tests, then this side has winning chances.     * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (TotalPieces(side, pawn)) 
-     return 1; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If this side has two bishops, and the enemy has only a  * 
-  *  single kinght, the two bishops win.                     * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (TotalPieces(side, occupied) == 6) 
-     if (TotalPieces(enemy, occupied) == 3 && (Knights(side) 
-             || !Knights(enemy))) 
-       return 0; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If one side is two knights ahead and the opponent has   * 
-  *  no remaining material, it is a draw.                    * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (TotalPieces(side, occupied) == 6 && !Bishops(side) 
-       && TotalPieces(enemy, occupied) + TotalPieces(enemy, pawn) == 0) 
-     return 0; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If we make it through all the above tests, then "side"  * 
-  *  can win so we return 1.                                 * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   return 1; 
- } 
-   
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   InitializeKingSafety() is used to initialize the king safety matrix.      * 
-  *   This is set so that the matrix, indexed by king safety pawn structure     * 
-  *   index and by king safety piece tropism, combines the two indices to       * 
-  *   produce a single score.  As either index rises, the king safety score     * 
-  *   tracks along, but as both rise, the king safety score rises much more     * 
-  *   quickly.                                                                  * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- void InitializeKingSafety() { 
-   int safety, tropism; 
-   
-   for (safety = 0; safety < 16; safety++) { 
-     for (tropism = 0; tropism < 16; tropism++) { 
-       king_safety[safety][tropism] = 
-           180 * ((safety_vector[safety] + 100) * (tropism_vector[tropism] + 
-               100) / 100 - 100) / 100; 
-     } 
-   } 
- } 
-