Subversion Repositories Games.Chess Giants

Rev

Rev 108 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "chess.h"
  2. #include "data.h"
  3. /* last modified 02/23/14 */
  4. /*
  5.  *******************************************************************************
  6.  *                                                                             *
  7.  *   Evaluate() is used to evaluate the chess board.  Broadly, it addresses    *
  8.  *   four (4) distinct areas:  (1) material score which is simply a summing of *
  9.  *   piece types multiplied by piece values;  (2) pawn scoring which considers *
  10.  *   placement of pawns and also evaluates passed pawns, particularly in end-  *
  11.  *   game situations;  (3) piece scoring which evaluates the placement of each *
  12.  *   piece as well as things like piece mobility;  (4) king safety which       *
  13.  *   considers the pawn shelter around the king along with material present to *
  14.  *   facilitate an attack.                                                     *
  15.  *                                                                             *
  16.  *******************************************************************************
  17.  */
  18. int Evaluate(TREE * RESTRICT tree, int ply, int wtm, int alpha, int beta) {
  19.   PAWN_HASH_ENTRY *ptable;
  20.   PXOR *pxtable;
  21.   int score, side, majors, minors, can_win = 3;
  22.   int phase, lscore, cutoff;
  23.  
  24. /*
  25.  **********************************************************************
  26.  *                                                                    *
  27.  *  Initialize.                                                       *
  28.  *                                                                    *
  29.  **********************************************************************
  30.  */
  31.   cutoff = (TotalPieces(white, occupied) && TotalPieces(black, occupied))
  32.       ? KNIGHT_VALUE : ROOK_VALUE;
  33.   lscore = (wtm) ? Material : -Material;
  34.   if (lscore + cutoff < alpha || lscore - cutoff > beta)
  35.     return lscore;
  36.   tree->dangerous[white] = (Queens(white) && TotalPieces(white, occupied) > 9)
  37.       || (TotalPieces(white, rook) > 1 && TotalPieces(white, occupied) > 15);
  38.   tree->dangerous[black] = (Queens(black) && TotalPieces(black, occupied) > 9)
  39.       || (TotalPieces(black, rook) > 1 && TotalPieces(black, occupied) > 15);
  40.   tree->evaluations++;
  41.   tree->score_mg = 0;
  42.   tree->score_eg = 0;
  43.   EvaluateMaterial(tree, wtm);
  44. #if defined(SKILL)
  45.   if (skill < 100) {
  46.     int i, j;
  47.     for (i = 0; i < burnc[skill / 10]; i++)
  48.       for (j = 1; j < 10; j++)
  49.         burner[j - 1] = burner[j - 1] * burner[j];
  50.   }
  51. #endif
  52. /*
  53.  **********************************************************************
  54.  *                                                                    *
  55.  *  Check for draws due to insufficient material and adjust the score *
  56.  *  as necessary.  This code also handles a special endgame case      *
  57.  *  where one side has only a lone king, and the king has no legal    *
  58.  *  moves.  This has been shown to break a few evaluation terms such  *
  59.  *  as bishop + wrong color rook pawn.  If this case is detected, a   *
  60.  *  drawscore is returned.                                            *
  61.  *                                                                    *
  62.  **********************************************************************
  63.  */
  64.   if (TotalPieces(white, occupied) < 13 && TotalPieces(black, occupied) < 13)
  65.     do {
  66. /*
  67.  ************************************************************
  68.  *                                                          *
  69.  *  If neither side has any pieces, and both sides have     *
  70.  *  non-rookpawns, then either side can win.                *
  71.  *                                                          *
  72.  ************************************************************
  73.  */
  74.       if (TotalPieces(white, occupied) == 0 &&
  75.           TotalPieces(black, occupied) == 0 && (Pawns(white) & not_rook_pawns
  76.               && Pawns(black) & not_rook_pawns))
  77.         break;
  78. /*
  79.  ************************************************************
  80.  *                                                          *
  81.  *  If one side is an exchange up, but has no pawns, then   *
  82.  *  that side can not possibly win.                         *
  83.  *                                                          *
  84.  ************************************************************
  85.  */
  86.       majors = TotalMajors(white) - TotalMajors(black);
  87.       if (Abs(majors) == 1) {
  88.         minors = TotalMinors(white) - TotalMinors(black);
  89.         if (majors == -minors) {
  90.           if (TotalPieces(black, pawn) == 0)
  91.             can_win &= 1;
  92.           if (TotalPieces(white, pawn) == 0)
  93.             can_win &= 2;
  94.         }
  95.         if (can_win == 0)
  96.           break;
  97.       }
  98. /*
  99.  ************************************************************
  100.  *                                                          *
  101.  *  check several special cases, such as bishop + the wrong *
  102.  *  rook pawn and adjust can_win accordingly.               *
  103.  *                                                          *
  104.  ************************************************************
  105.  */
  106.       if (!EvaluateWinningChances(tree, white, wtm))
  107.         can_win &= 2;
  108.       if (!EvaluateWinningChances(tree, black, wtm))
  109.         can_win &= 1;
  110.     } while (0);
  111. /*
  112.  **********************************************************************
  113.  *                                                                    *
  114.  *  Determine if this position should be evaluated to force mate      *
  115.  *  (neither side has pawns) or if it should be evaluated normally.   *
  116.  *                                                                    *
  117.  *  Note the special case of no pawns, one side is ahead in total     *
  118.  *  material, but the game is a hopeless draw.  KRN vs KR is one      *
  119.  *  example.  If EvaluateWinningChances() determines that the side    *
  120.  *  with extra material can not win, the score is pulled closer to a  *
  121.  *  draw although it can not collapse completely to the drawscore as  *
  122.  *  it is possible to lose KRB vs KR if the KR side lets the king get *
  123.  *  trapped on the edge of the board.                                 *
  124.  *                                                                    *
  125.  **********************************************************************
  126.  */
  127.   tree->all_pawns = Pawns(black) | Pawns(white);
  128.   if (!tree->all_pawns) {
  129.     if (TotalPieces(white, occupied) > 3 || TotalPieces(black, occupied) > 3) {
  130.       if (Material > 0)
  131.         EvaluateMate(tree, white);
  132.       else if (Material < 0)
  133.         EvaluateMate(tree, black);
  134.       if (tree->score_eg > DrawScore(1) && !(can_win & 1))
  135.         tree->score_eg = tree->score_eg / 4;
  136.       if (tree->score_eg < DrawScore(1) && !(can_win & 2))
  137.         tree->score_eg = tree->score_eg / 4;
  138. #if defined(SKILL)
  139.       if (skill < 100)
  140.         tree->score_eg =
  141.             (int) (skill * tree->score_eg / 100 + ((100 -
  142.                 skill) * PAWN_VALUE * (uint64_t) Random32() /
  143.             0x100000000ull) / 100); // Pierre-Marie Baty -- added type cast
  144. #endif
  145.       return (wtm) ? tree->score_eg : -tree->score_eg;
  146.     }
  147.   }
  148. /*
  149.  **********************************************************************
  150.  *                                                                    *
  151.  *  Now evaluate pawns.  If the pawn hash signature has not changed   *
  152.  *  from the last entry to Evaluate() then we already have everything *
  153.  *  we need in the pawn hash entry.  In this case, we do not need to  *
  154.  *  call EvaluatePawns() at all.  EvaluatePawns() does all of the     *
  155.  *  analysis for information specifically regarding only pawns.  In   *
  156.  *  many cases, it merely records the presence/absence of positional  *
  157.  *  pawn features because those features also depends on pieces.      *
  158.  *  Note that anything put into EvaluatePawns() can only consider the *
  159.  *  placement of pawns.  Kings or other pieces can not influence the  *
  160.  *  score because those pieces are not hashed into the pawn hash      *
  161.  *  signature.  Violating this principle leads to lots of very        *
  162.  *  difficult and challenging debugging problems.                     *
  163.  *                                                                    *
  164.  **********************************************************************
  165.  */
  166.   else {
  167.     if (PawnHashKey == tree->pawn_score.key) {
  168.       tree->score_mg += tree->pawn_score.score_mg;
  169.       tree->score_eg += tree->pawn_score.score_eg;
  170.     }
  171. /*
  172.  ************************************************************
  173.  *                                                          *
  174.  *  First check to see if this position has been handled    *
  175.  *  before.  If so, we can skip the work saved in the pawn  *
  176.  *  hash table.                                             *
  177.  *                                                          *
  178.  ************************************************************
  179.  */
  180.     else {
  181.       ptable = pawn_hash_table + (PawnHashKey & pawn_hash_mask);
  182.       pxtable = (PXOR *) & (tree->pawn_score);
  183.       tree->pawn_score = *ptable;
  184.       tree->pawn_score.key ^=
  185.           pxtable->entry[1] ^ pxtable->entry[2] ^ pxtable->entry[3];
  186.       if (tree->pawn_score.key != PawnHashKey) {
  187.         tree->pawn_score.key = PawnHashKey;
  188.         tree->pawn_score.score_mg = 0;
  189.         tree->pawn_score.score_eg = 0;
  190.         for (side = black; side <= white; side++)
  191.           EvaluatePawns(tree, side);
  192.         ptable->key =
  193.             pxtable->entry[0] ^ pxtable->entry[1] ^ pxtable->
  194.             entry[2] ^ pxtable->entry[3];
  195.         memcpy((char *) ptable + 8, (char *) &(tree->pawn_score) + 8, 20);
  196.       }
  197.       tree->score_mg += tree->pawn_score.score_mg;
  198.       tree->score_eg += tree->pawn_score.score_eg;
  199.     }
  200. /*
  201.  **********************************************************************
  202.  *                                                                    *
  203.  *  If there are any passed pawns, first call EvaluatePassedPawns()   *
  204.  *  to evaluate them.  Then, if one side has a passed pawn and the    *
  205.  *  other side has no pieces, call EvaluatePassedPawnRaces() to see   *
  206.  *  if the passed pawn can be stopped from promoting.                 *
  207.  *                                                                    *
  208.  **********************************************************************
  209.  */
  210.     if (tree->pawn_score.passed[black] || tree->pawn_score.passed[white]) {
  211.       for (side = black; side <= white; side++)
  212.         if (tree->pawn_score.passed[side])
  213.           EvaluatePassedPawns(tree, side, wtm);
  214.       if ((TotalPieces(white, occupied) == 0 &&
  215.               tree->pawn_score.passed[black])
  216.           || (TotalPieces(black, occupied) == 0 &&
  217.               tree->pawn_score.passed[white]))
  218.         EvaluatePassedPawnRaces(tree, wtm);
  219.     }
  220.   }
  221. /*
  222.  **********************************************************************
  223.  *                                                                    *
  224.  *  Call EvaluateDevelopment() to evaluate development.  Note that we *
  225.  *  only do this when either side has not castled at the root.        *
  226.  *                                                                    *
  227.  **********************************************************************
  228.  */
  229.   for (side = black; side <= white; side++)
  230.     EvaluateDevelopment(tree, ply, side);
  231. /*
  232.  **********************************************************************
  233.  *                                                                    *
  234.  *  Then evaluate pieces.                                             *
  235.  *                                                                    *
  236.  **********************************************************************
  237.  */
  238.   phase =
  239.       Min(62, TotalPieces(white, occupied) + TotalPieces(black, occupied));
  240.   score = ((tree->score_mg * phase) + (tree->score_eg * (62 - phase))) / 62;
  241.   lscore = (wtm) ? score : -score;
  242.   cutoff = (tree->dangerous[white]
  243.       || tree->dangerous[black]) ? 114 + phase : 102;
  244.   if (lscore + cutoff > alpha && lscore - cutoff < beta) {
  245.     tree->tropism[white] = 0;
  246.     tree->tropism[black] = 0;
  247.     for (side = black; side <= white; side++)
  248.       EvaluateKnights(tree, side);
  249.     for (side = black; side <= white; side++)
  250.       EvaluateBishops(tree, side);
  251.     for (side = black; side <= white; side++)
  252.       EvaluateRooks(tree, side);
  253.     for (side = black; side <= white; side++)
  254.       EvaluateQueens(tree, side);
  255.     for (side = black; side <= white; side++)
  256.       EvaluateKings(tree, ply, side);
  257.   }
  258. /*
  259.  **********************************************************************
  260.  *                                                                    *
  261.  *  Adjust the score if the game is drawish but one side appears to   *
  262.  *  be significantly better according to the computed score.          *
  263.  *                                                                    *
  264.  **********************************************************************
  265.  */
  266.   score = ((tree->score_mg * phase) + (tree->score_eg * (62 - phase))) / 62;
  267.   score = EvaluateDraws(tree, ply, can_win, score);
  268. #if defined(SKILL)
  269.   if (skill < 100)
  270.     score =
  271.         (int) (skill * score / 100 + ((100 -
  272.             skill) * PAWN_VALUE * (uint64_t) Random32() / 0x100000000ull) /
  273.         100); // Pierre-Marie Baty -- added type cast
  274. #endif
  275.   return (wtm) ? score : -score;
  276. }
  277.  
  278. /* last modified 02/23/14 */
  279. /*
  280.  *******************************************************************************
  281.  *                                                                             *
  282.  *  EvaluateBishops() is used to evaluate bishops.                             *
  283.  *                                                                             *
  284.  *******************************************************************************
  285.  */
  286. void EvaluateBishops(TREE * RESTRICT tree, int side) {
  287.   uint64_t temp, moves;
  288.   int square, t, mobility;
  289.   int score_eg = 0, score_mg = 0, enemy = Flip(side);
  290. /*
  291.  ************************************************************
  292.  *                                                          *
  293.  *  First, locate each bishop and add in its piece/square   *
  294.  *  score.                                                  *
  295.  *                                                          *
  296.  ************************************************************
  297.  */
  298.   for (temp = Bishops(side); temp; temp &= temp - 1) {
  299.     square = LSB(temp);
  300.     score_mg += bval[mg][side][square];
  301.     score_eg += bval[eg][side][square];
  302. /*
  303.  ************************************************************
  304.  *                                                          *
  305.  *  Evaluate for "outposts" which is a bishop that can't be *
  306.  *  driven off by an enemy pawn, and which is supported by  *
  307.  *  a friendly pawn.                                        *
  308.  *                                                          *
  309.  *  If the enemy has NO minor to take this bishop, then     *
  310.  *  increase the bonus.                                     *
  311.  *                                                          *
  312.  *  Note that the bishop_outpost array is overloaded to     *
  313.  *  serve a dual prupose.  A negative value is used to flag *
  314.  *  squares A7 and H7 to test for a trapped bishop.  This   *
  315.  *  is done for speed.                                      *
  316.  *                                                          *
  317.  ************************************************************
  318.  */
  319.     t = bishop_outpost[side][square];
  320.     if (t) {
  321.       if (t > 0) {
  322.         if (!(mask_no_pattacks[enemy][square] & Pawns(enemy))) {
  323.           if (pawn_attacks[enemy][square] & Pawns(side)) {
  324.             t += t / 2;
  325.             if (!Knights(enemy) && !(Color(square) & Bishops(enemy)))
  326.               t += bishop_outpost[side][square];
  327.           }
  328.           score_eg += t;
  329.           score_mg += t;
  330.         }
  331.       }
  332. /*
  333.  ************************************************************
  334.  *                                                          *
  335.  *  Check to see if the bishop is trapped at a7 or h7 with  *
  336.  *  a pawn at b6 or g6 that has trapped the bishop.         *
  337.  *                                                          *
  338.  ************************************************************
  339.  */
  340.       else {
  341.         if (square == sqflip[side][A7]) {
  342.           if (SetMask(sqflip[side][B6]) & Pawns(enemy)) {
  343.             score_eg -= bishop_trapped;
  344.             score_mg -= bishop_trapped;
  345.           }
  346.         } else if (square == sqflip[side][H7]) {
  347.           if (SetMask(sqflip[side][G6]) & Pawns(enemy)) {
  348.             score_eg -= bishop_trapped;
  349.             score_mg -= bishop_trapped;
  350.           }
  351.         }
  352.       }
  353.     }
  354. /*
  355.  ************************************************************
  356.  *                                                          *
  357.  *  Mobility counts the number of squares the piece         *
  358.  *  attacks, and weighs each square according to            *
  359.  *  centralization.                                         *
  360.  *                                                          *
  361.  ************************************************************
  362.  */
  363.     mobility = BishopMobility(square, OccupiedSquares);
  364.     if (mobility < 0 && (pawn_attacks[enemy][square] & Pawns(side))
  365.         && (File(square) == FILEA || File(square) == FILEH))
  366.       mobility -= 8;
  367.     score_mg += mobility;
  368.     score_eg += mobility;
  369. /*
  370.  ************************************************************
  371.  *                                                          *
  372.  *  Check for pawns on both wings, which makes a bishop     *
  373.  *  even more valuable against an enemy knight              *
  374.  *                                                          *
  375.  ************************************************************
  376.  */
  377.     if (tree->all_pawns & mask_fgh && tree->all_pawns & mask_abc) {
  378.       score_mg += bishop_with_wing_pawns[mg];
  379.       score_eg += bishop_with_wing_pawns[eg];
  380.     }
  381. /*
  382.  ************************************************************
  383.  *                                                          *
  384.  *  Adjust the tropism count for this piece.                *
  385.  *                                                          *
  386.  ************************************************************
  387.  */
  388.     if (tree->dangerous[side]) {
  389.       moves = king_attacks[KingSQ(enemy)];
  390.       t = ((bishop_attacks[square] & moves)
  391.           && ((BishopAttacks(square,
  392.                       OccupiedSquares & ~(Queens(side)))) & moves)) ? 1 :
  393.           Distance(square, KingSQ(enemy));
  394.       tree->tropism[side] += king_tropism_b[t];
  395.     }
  396.   }
  397.   tree->score_mg += sign[side] * score_mg;
  398.   tree->score_eg += sign[side] * score_eg;
  399. }
  400.  
  401. /* last modified 02/23/14 */
  402. /*
  403.  *******************************************************************************
  404.  *                                                                             *
  405.  *   EvaluateDevelopment() is used to encourage the program to develop its     *
  406.  *   pieces before moving its queen.  Standard developmental principles are    *
  407.  *   applied.  They include:  (1) don't move the queen until minor pieces are  *
  408.  *   developed;  (2) advance the center pawns as soon as possible;  (3) don't  *
  409.  *   move the king unless its a castling move.                                 *
  410.  *                                                                             *
  411.  *******************************************************************************
  412.  */
  413. void EvaluateDevelopment(TREE * RESTRICT tree, int ply, int side) {
  414.   int score_mg = 0;
  415.   int enemy = Flip(side);
  416.  
  417. /*
  418.  ************************************************************
  419.  *                                                          *
  420.  *  First, some "thematic" things, which includes don't     *
  421.  *  block the c-pawn in queen-pawn openings.                *
  422.  *                                                          *
  423.  ************************************************************
  424.  */
  425.   if (!(SetMask(sqflip[side][E4]) & Pawns(side))
  426.       && SetMask(sqflip[side][D4]) & Pawns(side)
  427.       && SetMask(sqflip[side][C2]) & Pawns(side)
  428.       && SetMask(sqflip[side][C3]) & (Knights(side) | Bishops(side)))
  429.     score_mg -= development_thematic;
  430. /*
  431.  ************************************************************
  432.  *                                                          *
  433.  *  If the king hasn't moved at the beginning of the        *
  434.  *  search, but it has moved somewhere in the current       *
  435.  *  search path, make *sure* it's a castle move or else     *
  436.  *  penalize the loss of castling privilege.                *
  437.  *                                                          *
  438.  ************************************************************
  439.  */
  440.   if (Castle(1, side) > 0) {
  441.     int oq = (Queens(enemy)) ? 3 : 1;
  442.  
  443.     if (Castle(ply, side) != Castle(1, side)) {
  444.       if (Castle(ply, side) == 0)
  445.         score_mg -= oq * development_losing_castle;
  446.       else if (Castle(ply, side) > 0)
  447.         score_mg -= (oq * development_losing_castle) / 2;
  448.     } else
  449.       score_mg -= oq * development_not_castled;
  450.   }
  451. /*
  452.  ************************************************************
  453.  *                                                          *
  454.  *  Check for an undeveloped knight/rook combo              *
  455.  *                                                          *
  456.  ************************************************************
  457.  */
  458.   if (PcOnSq(sqflip[side][B1]) == pieces[side][knight]
  459.       && PcOnSq(sqflip[side][A1]) == pieces[side][rook])
  460.     score_mg -= undeveloped_piece;
  461.   if (PcOnSq(sqflip[side][G1]) == pieces[side][knight]
  462.       && PcOnSq(sqflip[side][H1]) == pieces[side][rook])
  463.     score_mg -= undeveloped_piece;
  464.   tree->score_mg += sign[side] * score_mg;
  465. }
  466.  
  467. /* last modified 02/23/14 */
  468. /*
  469.  *******************************************************************************
  470.  *                                                                             *
  471.  *   EvaluateDraws() is used to adjust the score based on whether the side     *
  472.  *   that appears to be better according the computed score can actually win   *
  473.  *   the game or not.  If the answer is "no" then the score is reduced         *
  474.  *   significantly to reflect the lack of winning chances.                     *
  475.  *                                                                             *
  476.  *******************************************************************************
  477.  */
  478. int EvaluateDraws(TREE * RESTRICT tree, int ply, int can_win, int score) {
  479. /*
  480.  ************************************************************
  481.  *                                                          *
  482.  *  If the ending has only bishops of opposite colors, the  *
  483.  *  score is pulled closer to a draw.  If the score says    *
  484.  *  one side is winning, but that side doesn't have enough  *
  485.  *  material to win, the score is also pulled closer to a   *
  486.  *  draw.                                                   *
  487.  *                                                          *
  488.  *  If this is a pure BOC ending, it is very drawish unless *
  489.  *  one side has at least 4 pawns.  More pawns makes it     *
  490.  *  harder for a bishop and king to stop them all from      *
  491.  *  advancing.                                              *
  492.  *                                                          *
  493.  ************************************************************
  494.  */
  495.   if (TotalPieces(white, occupied) <= 8 && TotalPieces(black, occupied) <= 8) {
  496.     if (TotalPieces(white, bishop) == 1 && TotalPieces(black, bishop) == 1)
  497.       if (square_color[LSB(Bishops(black))] !=
  498.           square_color[LSB(Bishops(white))]) {
  499.         if (TotalPieces(white, occupied) == 3 &&
  500.             TotalPieces(black, occupied) == 3 &&
  501.             ((TotalPieces(white, pawn) < 4 && TotalPieces(black, pawn) < 4)
  502.                 || Abs(TotalPieces(white, pawn) - TotalPieces(black,
  503.                         pawn)) < 2))
  504.           score = score / 2 + DrawScore(1);
  505.         else if (TotalPieces(white, occupied) == TotalPieces(black, occupied))
  506.           score = 3 * score / 4 + DrawScore(1);
  507.       }
  508.   }
  509.   if (can_win != 3) {
  510.     if (can_win != 1 && score > DrawScore(1))
  511.       score = score / 4 + DrawScore(1);
  512.     else if (can_win != 2 && score < DrawScore(1))
  513.       score = score / 4 + DrawScore(1);
  514.   }
  515. /*
  516.  ************************************************************
  517.  *                                                          *
  518.  *  If we are running into the 50-move rule, then start     *
  519.  *  dragging the score toward draw.  This is the idea of a  *
  520.  *  "weariness factor" as mentioned by Dave Slate many      *
  521.  *  times.  This avoids slamming into a draw at move 50 and *
  522.  *  having to move something quickly, rather than slowly    *
  523.  *  discovering that the score is dropping and that pushing *
  524.  *  a pawn or capturing something will cause it to go back  *
  525.  *  to its correct value a bit more smoothly.               *
  526.  *                                                          *
  527.  ************************************************************
  528.  */
  529.   if (Reversible(ply) > 80) {
  530.     int iscale = 101 - Reversible(ply);
  531.  
  532.     score = DrawScore(1) + score * iscale / 20;
  533.   }
  534.   return score;
  535. }
  536.  
  537. /* last modified 02/23/14 */
  538. /*
  539.  *******************************************************************************
  540.  *                                                                             *
  541.  *   EvaluateHasOpposition() is used to determine if one king stands in        *
  542.  *   "opposition" to the other.  If the kings are opposed on the same file or  *
  543.  *   else are opposed on the same diagonal, then the side not-to-move has the  *
  544.  *   opposition and the side-to-move must give way.                            *
  545.  *                                                                             *
  546.  *******************************************************************************
  547.  */
  548. int EvaluateHasOpposition(int on_move, int king, int enemy_king) {
  549.   int file_distance, rank_distance;
  550.  
  551.   file_distance = FileDistance(king, enemy_king);
  552.   rank_distance = RankDistance(king, enemy_king);
  553.   if (rank_distance < 2)
  554.     return 1;
  555.   if (on_move) {
  556.     if (rank_distance & 1)
  557.       rank_distance--;
  558.     if (file_distance & 1)
  559.       file_distance--;
  560.   }
  561.   if (!(file_distance & 1) && !(rank_distance & 1))
  562.     return 1;
  563.   return 0;
  564. }
  565.  
  566. /* last modified 02/23/14 */
  567. /*
  568.  *******************************************************************************
  569.  *                                                                             *
  570.  *   EvaluateKings() is used to evaluate kings.                                *
  571.  *                                                                             *
  572.  *******************************************************************************
  573.  */
  574. void EvaluateKings(TREE * RESTRICT tree, int ply, int side) {
  575.   int score_eg = 0, score_mg = 0, defects;
  576.   int ksq = KingSQ(side), enemy = Flip(side);
  577.  
  578. /*
  579.  ************************************************************
  580.  *                                                          *
  581.  *  First, check for where the king should be if this is an *
  582.  *  endgame.  Ie with pawns on one wing, the king needs to  *
  583.  *  be on that wing.  With pawns on both wings, the king    *
  584.  *  belongs in the center.                                  *
  585.  *                                                          *
  586.  ************************************************************
  587.  */
  588.   if (tree->all_pawns) {
  589.     if (tree->all_pawns & mask_efgh && tree->all_pawns & mask_abcd)
  590.       score_eg += kval_n[side][ksq];
  591.     else if (tree->all_pawns & mask_efgh)
  592.       score_eg += kval_k[side][ksq];
  593.     else
  594.       score_eg += kval_q[side][ksq];
  595.   }
  596. /*
  597.  ************************************************************
  598.  *                                                          *
  599.  *  Do castle scoring, if the king has castled, the pawns   *
  600.  *  in front are important.  If not castled yet, the pawns  *
  601.  *  on the kingside should be preserved for this.           *
  602.  *                                                          *
  603.  ************************************************************
  604.  */
  605.   if (tree->dangerous[enemy]) {
  606.     defects = 0;
  607.     if (Castle(ply, side) <= 0) {
  608.       if (File(ksq) >= FILEE) {
  609.         if (File(ksq) > FILEE)
  610.           defects = tree->pawn_score.defects_k[side];
  611.         else
  612.           defects = tree->pawn_score.defects_e[side];
  613.       } else {
  614.         if (File(ksq) < FILED)
  615.           defects = tree->pawn_score.defects_q[side];
  616.         else
  617.           defects = tree->pawn_score.defects_d[side];
  618.       }
  619.     } else {
  620.       if (Castle(ply, side) == 3)
  621.         defects =
  622.             Min(Min(tree->pawn_score.defects_k[side],
  623.                 tree->pawn_score.defects_e[side]),
  624.             tree->pawn_score.defects_q[side]);
  625.       else if (Castle(ply, side) == 1)
  626.         defects =
  627.             Min(tree->pawn_score.defects_k[side],
  628.             tree->pawn_score.defects_e[side]);
  629.       else
  630.         defects =
  631.             Min(tree->pawn_score.defects_q[side],
  632.             tree->pawn_score.defects_e[side]);
  633.       if (defects < 3)
  634.         defects = 3;
  635.     }
  636. /*
  637.  ************************************************************
  638.  *                                                          *
  639.  *  Fold in the king tropism and king pawn shelter scores   *
  640.  *  together.                                               *
  641.  *                                                          *
  642.  ************************************************************
  643.  */
  644.     if (tree->tropism[enemy] < 0)
  645.       tree->tropism[enemy] = 0;
  646.     else if (tree->tropism[enemy] > 15)
  647.       tree->tropism[enemy] = 15;
  648.     if (defects > 15)
  649.       defects = 15;
  650.     score_mg -= king_safety[defects][tree->tropism[enemy]];
  651.   }
  652.   tree->score_mg += sign[side] * score_mg;
  653.   tree->score_eg += sign[side] * score_eg;
  654. }
  655.  
  656. /* last modified 02/23/14 */
  657. /*
  658.  *******************************************************************************
  659.  *                                                                             *
  660.  *   EvaluateKingsFile computes defects for a file, based on whether the file  *
  661.  *   is open or half-open.  If there are friendly pawns still on the file,     *
  662.  *   they are penalized for advancing in front of the king.                    *
  663.  *                                                                             *
  664.  *******************************************************************************
  665.  */
  666. int EvaluateKingsFile(TREE * RESTRICT tree, int whichfile, int side) {
  667.   int defects = 0, file;
  668.   int enemy = Flip(side);
  669.  
  670.   for (file = whichfile - 1; file <= whichfile + 1; file++)
  671.     if (!(file_mask[file] & tree->all_pawns))
  672.       defects += open_file[file];
  673.     else {
  674.       if (!(file_mask[file] & Pawns(enemy)))
  675.         defects += half_open_file[file] / 2;
  676.       else
  677.         defects +=
  678.             pawn_defects[side][Rank(Advanced(enemy,
  679.                     file_mask[file] & Pawns(enemy)))];
  680.       if (!(file_mask[file] & Pawns(side)))
  681.         defects += half_open_file[file];
  682.       else if (!(Pawns(side) & SetMask(sqflip[side][A2] + file))) {
  683.         defects++;
  684.         if (!(Pawns(side) & SetMask(sqflip[side][A3] + file)))
  685.           defects++;
  686.       }
  687.     }
  688.   return defects;
  689. }
  690.  
  691. /* last modified 02/23/14 */
  692. /*
  693.  *******************************************************************************
  694.  *                                                                             *
  695.  *   EvaluateKnights() is used to evaluate knights.                            *
  696.  *                                                                             *
  697.  *******************************************************************************
  698.  */
  699. void EvaluateKnights(TREE * RESTRICT tree, int side) {
  700.   uint64_t temp;
  701.   int square, t, score_eg = 0, score_mg = 0;
  702.   int enemy = Flip(side);
  703.  
  704. /*
  705.  ************************************************************
  706.  *                                                          *
  707.  *  First fold in centralization score from the piece/      *
  708.  *  square table "nval".                                    *
  709.  *                                                          *
  710.  ************************************************************
  711.  */
  712.   for (temp = Knights(side); temp; temp &= temp - 1) {
  713.     square = LSB(temp);
  714.     score_mg += nval[mg][side][square];
  715.     score_eg += nval[eg][side][square];
  716. /*
  717.  ************************************************************
  718.  *                                                          *
  719.  *  Evaluate for "outposts" which is a knight that can't    *
  720.  *  be driven off by an enemy pawn, and which is supported  *
  721.  *  by a friendly pawn.                                     *
  722.  *                                                          *
  723.  *  If the enemy has NO minor to take this knight, then     *
  724.  *  increase the bonus.                                     *
  725.  *                                                          *
  726.  ************************************************************
  727.  */
  728.     t = knight_outpost[side][square];
  729.     if (t && !(mask_no_pattacks[enemy][square] & Pawns(enemy))) {
  730.       if (pawn_attacks[enemy][square] & Pawns(side)) {
  731.         t += t / 2;
  732.         if (!Knights(enemy) && !(Color(square) & Bishops(enemy)))
  733.           t += knight_outpost[side][square];
  734.       }
  735.       score_eg += t;
  736.       score_mg += t;
  737.     }
  738. /*
  739.  ************************************************************
  740.  *                                                          *
  741.  *  Mobility counts the number of squares the piece         *
  742.  *  attacks, including squares with friendly pieces, and    *
  743.  *  weighs each square according to centralization.         *
  744.  *                                                          *
  745.  ************************************************************
  746.  */
  747.     score_mg += knight_mobility_table[square];
  748.     score_eg += knight_mobility_table[square];
  749. /*
  750.  ************************************************************
  751.  *                                                          *
  752.  *  Adjust the tropism count for this piece.                *
  753.  *                                                          *
  754.  ************************************************************
  755.  */
  756.     if (tree->dangerous[side]) {
  757.       t = Distance(square, KingSQ(enemy));
  758.       tree->tropism[side] += king_tropism_n[t];
  759.     }
  760.   }
  761.   tree->score_mg += sign[side] * score_mg;
  762.   tree->score_eg += sign[side] * score_eg;
  763. }
  764.  
  765. /* last modified 02/23/14 */
  766. /*
  767.  *******************************************************************************
  768.  *                                                                             *
  769.  *   EvaluateMate() is used to evaluate positions where neither side has pawns *
  770.  *   and one side has enough material to force checkmate.  It simply trys to   *
  771.  *   force the losing king to the edge of the board, and then to the corner    *
  772.  *   where mates are easier to find.                                           *
  773.  *                                                                             *
  774.  *******************************************************************************
  775.  */
  776. void EvaluateMate(TREE * RESTRICT tree, int side) {
  777.   int mate_score = 0;
  778.   int enemy = Flip(side);
  779.  
  780. /*
  781.  ************************************************************
  782.  *                                                          *
  783.  *  If one side has a bishop+knight and the other side has  *
  784.  *  no pieces or pawns, then use the special bishop_knight  *
  785.  *  scoring board for the losing king to force it to the    *
  786.  *  right corner for mate.                                  *
  787.  *                                                          *
  788.  ************************************************************
  789.  */
  790.   if (!TotalPieces(enemy, occupied) && TotalMinors(side) == 2 &&
  791.       TotalPieces(side, bishop) == 1) {
  792.     if (dark_squares & Bishops(side))
  793.       mate_score = b_n_mate_dark_squares[KingSQ(enemy)];
  794.     else
  795.       mate_score = b_n_mate_light_squares[KingSQ(enemy)];
  796.   }
  797. /*
  798.  ************************************************************
  799.  *                                                          *
  800.  *  If one side is winning, force the enemy king to the     *
  801.  *  edge of the board.                                      *
  802.  *                                                          *
  803.  ************************************************************
  804.  */
  805.   else {
  806.     mate_score = mate[KingSQ(enemy)];
  807.     mate_score -=
  808.         (Distance(KingSQ(side), KingSQ(enemy)) - 3) * king_king_tropism;
  809.   }
  810.   tree->score_mg += sign[side] * mate_score;
  811.   tree->score_eg += sign[side] * mate_score;
  812. }
  813.  
  814. /* last modified 02/23/14 */
  815. /*
  816.  *******************************************************************************
  817.  *                                                                             *
  818.  *  EvaluateMaterial() is used to evaluate material on the board.  It really   *
  819.  *  accomplishes detecting cases where one side has made a 'bad trade' as the  *
  820.  *  comments below show.                                                       *
  821.  *                                                                             *
  822.  *******************************************************************************
  823.  */
  824. void EvaluateMaterial(TREE * RESTRICT tree, int wtm) {
  825.   int score_mg, score_eg, majors, minors, imbal;
  826.   static int bon[17] =
  827.       { 0, 40, 40, 35, 30, 24, 16, 12, 10, 8, 7, 6, 5, 4, 3, 2, 1 };
  828.  
  829. /*
  830.  **********************************************************************
  831.  *                                                                    *
  832.  *  We start with the raw Material balance for the current position,  *
  833.  *  then adjust this with a small bonus for the side on move.         *
  834.  *                                                                    *
  835.  **********************************************************************
  836.  */
  837.   score_mg = Material + ((wtm) ? wtm_bonus[mg] : -wtm_bonus[mg]);
  838.   score_eg = Material + ((wtm) ? wtm_bonus[eg] : -wtm_bonus[eg]);
  839. /*
  840.  **********************************************************************
  841.  *                                                                    *
  842.  *  If Majors or Minors are not balanced, then apply the appropriate  *
  843.  *  bonus/penatly from our imbalance table.                           *
  844.  *                                                                    *
  845.  **********************************************************************
  846.  */
  847.   majors = 4 + TotalMajors(white) - TotalMajors(black);
  848.   minors = 4 + TotalMinors(white) - TotalMinors(black);
  849.   majors = Max(Min(majors, 8), 0);
  850.   minors = Max(Min(minors, 8), 0);
  851.   imbal = imbalance[majors][minors];
  852.   score_mg += imbal;
  853.   score_eg += imbal;
  854. /*
  855.  ************************************************************
  856.  *                                                          *
  857.  *  Add a bonus per side if side has a pair of bishops,     *
  858.  *  which can become very strong in open positions.         *
  859.  *                                                          *
  860.  ************************************************************
  861.  */
  862.   if (TotalPieces(white, bishop) > 1) {
  863.     score_mg += bishop_pair[mg];
  864.     score_eg += bishop_pair[eg];
  865.   }
  866.   if (TotalPieces(black, bishop) > 1) {
  867.     score_mg -= bishop_pair[mg];
  868.     score_eg -= bishop_pair[eg];
  869.   }
  870. /*
  871.  ************************************************************
  872.  *                                                          *
  873.  *  Check for pawns on both wings, which makes a bishop     *
  874.  *  even more valuable against an enemy knight (knight vs.  *
  875.  *  bishop in endgame)                                      *
  876.  *                                                          *
  877.  ************************************************************
  878.  */
  879.   if (!imbal && !TotalMajors(white) && TotalMinors(white) == 1) {
  880.     imbal = bon[(TotalPieces(white, pawn) + TotalPieces(black, pawn))];
  881.     if (Bishops(white)) {
  882.       score_mg += imbal;
  883.       score_eg += imbal;
  884.     }
  885.     if (Bishops(black)) {
  886.       score_mg -= imbal;
  887.       score_eg -= imbal;
  888.     }
  889.   }
  890.   tree->score_mg += score_mg;
  891.   tree->score_eg += score_eg;
  892. }
  893.  
  894. /* last modified 02/23/14 */
  895. /*
  896.  *******************************************************************************
  897.  *                                                                             *
  898.  *   EvaluatePassedPawns() is used to evaluate passed pawns and the danger     *
  899.  *   they produce.  This code considers pieces as well, so it has been         *
  900.  *   separated from the normal EvaluatePawns() code that hashes information    *
  901.  *   based only on pawn positions.                                             *
  902.  *                                                                             *
  903.  *******************************************************************************
  904.  */
  905. void EvaluatePassedPawns(TREE * RESTRICT tree, int side, int wtm) {
  906.   uint64_t behind;
  907.   int file, square, score_mg = 0, score_eg = 0;
  908.   int pawns, rank;
  909.   int enemy = Flip(side);
  910.  
  911. /*
  912.  ************************************************************
  913.  *                                                          *
  914.  *  Initialize.                                             *
  915.  *                                                          *
  916.  ************************************************************
  917.  */
  918.   for (pawns = tree->pawn_score.passed[side]; pawns; pawns &= pawns - 1) {
  919.     file = LSB8Bit(pawns);
  920.     square = Advanced(side, Pawns(side) & file_mask[file]);
  921.     rank = rankflip[side][Rank(square)];
  922. /*
  923.  ************************************************************
  924.  *                                                          *
  925.  *  We have located the most advanced pawn on this file,    *
  926.  *  which is the only one that will get any sort of bonus.  *
  927.  *  Add in the MG/EG scores first.                          *
  928.  ************************************************************
  929.  */
  930.     score_mg += passed_pawn_value[mg][rank];
  931.     score_eg += passed_pawn_value[eg][rank];
  932. /*
  933.  ************************************************************
  934.  *                                                          *
  935.  *  Add in a bonus if the passed pawn is connected with     *
  936.  *  another pawn for support.                               *
  937.  *                                                          *
  938.  ************************************************************
  939.  */
  940.     if (mask_pawn_connected[square] & Pawns(side)) {
  941.       score_mg += passed_pawn_connected[mg][rank];
  942.       score_eg += passed_pawn_connected[eg][rank];
  943.     }
  944. /*
  945.  ************************************************************
  946.  *                                                          *
  947.  *  See if this pawn is either supported by a friendly rook *
  948.  *  from behind, or is attacked by an enemy rook from       *
  949.  *  behind.                                                 *
  950.  *                                                          *
  951.  ************************************************************
  952.  */
  953.     if (Rooks(white) | Rooks(black)) {
  954.       behind =
  955.           ((side) ? minus8dir[square] : plus8dir[square]) &
  956.           RookAttacks(square, OccupiedSquares);
  957.       if (behind) {
  958.         if (behind & Rooks(side)) {
  959.           score_mg += rook_behind_passed_pawn[mg][rank];
  960.           score_eg += rook_behind_passed_pawn[eg][rank];
  961.         } else if (behind & Rooks(enemy)) {
  962.           score_mg -= rook_behind_passed_pawn[mg][rank];
  963.           score_eg -= rook_behind_passed_pawn[eg][rank];
  964.         }
  965.       }
  966.     }
  967. /*
  968.  ************************************************************
  969.  *                                                          *
  970.  *  If the pawn is blockaded by an enemy piece, it cannot   *
  971.  *  move and is therefore not nearly as valuable as if it   *
  972.  *  were free to advance.  If it is blocked by a friendly   *
  973.  *  piece, it is penalized 1/2 the normal blockade amount   *
  974.  *  to encourage the blocking piece to move so the pawn can *
  975.  *  advance.                                                *
  976.  *                                                          *
  977.  ************************************************************
  978.  */
  979.     if (OccupiedSquares & ((side) ? plus8dir[square] : minus8dir[square])) {
  980.       score_eg -= passed_pawn_obstructed[rank];
  981.       if (SetMask(square + direction[side]) & Occupied(enemy)) {
  982.         score_mg -= passed_pawn_blockaded_by_enemy[mg][rank];
  983.         score_eg -= passed_pawn_blockaded_by_enemy[eg][rank];
  984.       } else if (SetMask(square + direction[side]) & Occupied(side)) {
  985.         score_mg -= passed_pawn_blockaded_by_friendly[mg][rank];
  986.         score_eg -= passed_pawn_blockaded_by_friendly[eg][rank];
  987.       }
  988. /*
  989.  ************************************************************
  990.  *                                                          *
  991.  *  If the pawn has nothing blocking its progress to the    *
  992.  *  promotion square, then we give a bonus.  If the pawn is *
  993.  *  outside the square of the enemy king, this bonus is     *
  994.  *  increased, because this makes it more difficult for the *
  995.  *  opponent to trade pieces which might let this pawn run. *
  996.  *                                                          *
  997.  ************************************************************
  998.  */
  999.     } else {
  1000.       if (!(pawn_race[side][wtm][square] & Kings(enemy)))
  1001.         score_eg += passed_pawn_far_away[rank];
  1002.       else
  1003.         score_eg += passed_pawn_not_far_away[rank];
  1004.     }
  1005. /*
  1006.  ************************************************************
  1007.  *                                                          *
  1008.  *  Add in a bonus based on how close the friendly king is, *
  1009.  *  and a penalty based on how close the enemy king is.     *
  1010.  *  The bonus/penalty is based on how advanced the pawn is  *
  1011.  *  to attract the kings toward the most advanced (and most *
  1012.  *  dangerous) passed pawn.                                 *
  1013.  *                                                          *
  1014.  ************************************************************
  1015.  */
  1016.     square += direction[side];
  1017.     score_eg -=
  1018.         (Distance(square, KingSQ(side)) - Distance(square,
  1019.             KingSQ(enemy))) * pp_dist_bonus[rank];
  1020.   }
  1021. /*
  1022.  ************************************************************
  1023.  *                                                          *
  1024.  *  Check to see if side has an outside passed pawn.        *
  1025.  *                                                          *
  1026.  ************************************************************
  1027.  */
  1028.   if (tree->pawn_score.passed[side]
  1029.       && is_outside[tree->pawn_score.passed[side]]
  1030.       [tree->pawn_score.all[enemy]]) {
  1031.     score_mg += outside_passed[mg];
  1032.     score_eg += outside_passed[eg];
  1033.   }
  1034.   tree->score_mg += sign[side] * score_mg;
  1035.   tree->score_eg += sign[side] * score_eg;
  1036. }
  1037.  
  1038. /* last modified 02/23/14 */
  1039. /*
  1040.  *******************************************************************************
  1041.  *                                                                             *
  1042.  *   EvaluatePassedPawnRaces() is used to evaluate passed pawns when one       *
  1043.  *   side has passed pawns and the other side (or neither) has pieces.  In     *
  1044.  *   such a case, the critical question is can the defending king stop the pawn*
  1045.  *   from queening or is it too far away?  If only one side has pawns that can *
  1046.  *   "run" then the situation is simple.  When both sides have pawns that can  *
  1047.  *   "run" it becomes more complex as it then becomes necessary to see if      *
  1048.  *   one side can use a forced king move to stop the other side, while the     *
  1049.  *   other side doesn't have the same ability to stop ours.                    *
  1050.  *                                                                             *
  1051.  *   In the case of king and pawn endings with exactly one pawn, the simple    *
  1052.  *   evaluation rules are used:  if the king is two squares in front of the    *
  1053.  *   pawn then it is a win, if the king is one one square in front with the    *
  1054.  *   opposition, then it is a win,  if the king is on the 6th rank with the    *
  1055.  *   pawn close by, it is a win.  Rook pawns are handled separately and are    *
  1056.  *   more difficult to queen because the king can get trapped in front of the  *
  1057.  *   pawn blocking promotion.                                                  *
  1058.  *                                                                             *
  1059.  *******************************************************************************
  1060.  */
  1061. void EvaluatePassedPawnRaces(TREE * RESTRICT tree, int wtm) {
  1062.   int file, square;
  1063.   int queen_distance;
  1064.   int pawnsq;
  1065.   uint64_t pawns;
  1066.   int passed;
  1067.   int side, enemy;
  1068.   int queener[2] = { 8, 8 };
  1069.   int forced_km[2] = { 0, 0 };
  1070. /*
  1071.  ************************************************************
  1072.  *                                                          *
  1073.  *  Check to see if side has one pawn and neither side has  *
  1074.  *  any pieces.  If so, use the simple pawn evaluation      *
  1075.  *  logic.                                                  *
  1076.  *                                                          *
  1077.  ************************************************************
  1078.  */
  1079.   for (side = black; side <= white; side++) {
  1080.     enemy = Flip(side);
  1081.     if (Pawns(side) && !Pawns(enemy) && TotalPieces(white, occupied) == 0 &&
  1082.         TotalPieces(black, occupied) == 0) {
  1083.       for (pawns = Pawns(side); pawns; pawns &= pawns - 1) {
  1084.         pawnsq = LSB(pawns);
  1085. /*
  1086.  ************************************************************
  1087.  *                                                          *
  1088.  *  King must be in front of the pawn or we go no further.  *
  1089.  *                                                          *
  1090.  ************************************************************
  1091.  */
  1092.         if (sign[side] * Rank(KingSQ(side)) <= sign[side] * Rank(pawnsq))
  1093.           continue;
  1094. /*
  1095.  ************************************************************
  1096.  *                                                          *
  1097.  *  First a special case.  If this is a rook pawn, then the *
  1098.  *  king must be on the adjacent file, and be closer to the *
  1099.  *  queening square than the opposing king.                 *
  1100.  *                                                          *
  1101.  ************************************************************
  1102.  */
  1103.         if (File(pawnsq) == FILEA) {
  1104.           if (File(KingSQ(side)) == FILEB &&
  1105.               Distance(KingSQ(side),
  1106.                   sqflip[side][A8]) < Distance(KingSQ(enemy),
  1107.                   sqflip[side][A8])) {
  1108.             tree->score_eg += sign[side] * pawn_can_promote;
  1109.             return;
  1110.           }
  1111.           continue;
  1112.         } else if (File(pawnsq) == FILEH) {
  1113.           if (File(KingSQ(side)) == FILEG &&
  1114.               Distance(KingSQ(side),
  1115.                   sqflip[side][H8]) < Distance(KingSQ(enemy),
  1116.                   sqflip[side][H8])) {
  1117.             tree->score_eg += sign[side] * pawn_can_promote;
  1118.             return;
  1119.           }
  1120.           continue;
  1121.         }
  1122. /*
  1123.  ************************************************************
  1124.  *                                                          *
  1125.  *  If king is two squares in front of the pawn then it's a *
  1126.  *  win immediately.  If the king is on the 6th rank and    *
  1127.  *  closer to the pawn than the opposing king, it's also a  *
  1128.  *  win.                                                    *
  1129.  *                                                          *
  1130.  ************************************************************
  1131.  */
  1132.         if (Distance(KingSQ(side), pawnsq) < Distance(KingSQ(enemy), pawnsq)) {
  1133.           if (sign[side] * Rank(KingSQ(side)) >
  1134.               sign[side] * (Rank(pawnsq) - 1 + 2 * side)) {
  1135.             tree->score_eg += sign[side] * pawn_can_promote;
  1136.             return;
  1137.           }
  1138.           if (Rank(KingSQ(side)) == rankflip[side][RANK6]) {
  1139.             tree->score_eg += sign[side] * pawn_can_promote;
  1140.             return;
  1141.           }
  1142. /*
  1143.  ************************************************************
  1144.  *                                                          *
  1145.  *  Last chance:  if the king is one square in front of the *
  1146.  *  pawn and has the opposition, then it's still a win.     *
  1147.  *                                                          *
  1148.  ************************************************************
  1149.  */
  1150.           if (Rank(KingSQ(side)) == Rank(pawnsq) - 1 + 2 * side &&
  1151.               EvaluateHasOpposition(wtm == side, KingSQ(side),
  1152.                   KingSQ(enemy))) {
  1153.             tree->score_eg += sign[side] * pawn_can_promote;
  1154.             return;
  1155.           }
  1156.         }
  1157.       }
  1158.     }
  1159. /*
  1160.  ************************************************************
  1161.  *                                                          *
  1162.  *  Check to see if enemy is out of pieces and stm has      *
  1163.  *  passed pawns.  If so, see if any of these passed pawns  *
  1164.  *  can outrun the defending king and promote.              *
  1165.  *                                                          *
  1166.  ************************************************************
  1167.  */
  1168.     if (TotalPieces(enemy, occupied) == 0 && tree->pawn_score.passed[side]) {
  1169.       passed = tree->pawn_score.passed[side];
  1170.       for (; passed; passed &= passed - 1) {
  1171.         file = LSB8Bit(passed);
  1172.         square = Advanced(side, Pawns(side) & file_mask[file]);
  1173.         forced_km[enemy] =
  1174.             (pawn_race[side][wtm][square] & Kings(enemy)) !=
  1175.             (pawn_race[side][Flip(wtm)][square] & Kings(enemy));
  1176.         if (!(pawn_race[side][wtm][square] & Kings(enemy))) {
  1177.           queen_distance = Abs(rankflip[side][RANK8] - Rank(square));
  1178.           if (Kings(side) & ((side) ? plus8dir[square] : minus8dir[square])) {
  1179.             if (file == FILEA || file == FILEH)
  1180.               queen_distance = 99;
  1181.             queen_distance++;
  1182.           }
  1183.           if (Rank(square) == rankflip[side][RANK2])
  1184.             queen_distance--;
  1185.           if (queen_distance < queener[side])
  1186.             queener[side] = queen_distance;
  1187.         }
  1188.       }
  1189.     }
  1190.   }
  1191.   if (queener[white] == 8 && queener[black] == 8)
  1192.     return;
  1193. /*
  1194.  ************************************************************
  1195.  *                                                          *
  1196.  *  Now that we know which pawns can outrun the kings for   *
  1197.  *  each side, we need to do the following:                 *
  1198.  *                                                          *
  1199.  *    (1) If both sides are forced to move their king to    *
  1200.  *        prevent the opponent from promoting, we let the   *
  1201.  *        search resolve this as the depth increases.       *
  1202.  *                                                          *
  1203.  *    (2) If white can run while black can not, then white  *
  1204.  *        wins, or vice-versa.                              *
  1205.  *                                                          *
  1206.  *    (3) If white queens and black's king can't stop it    *
  1207.  *        no matter who moves first, while black has a pawn *
  1208.  *        that white can stop if a king move is made        *
  1209.  *        immediately, then white wins, and vice-versa.     *
  1210.  *                                                          *
  1211.  *    (4) Other situations are left to the search to        *
  1212.  *        resolve.                                          *
  1213.  *                                                          *
  1214.  ************************************************************
  1215.  */
  1216.   if (forced_km[white] & forced_km[black])
  1217.     return;
  1218.   if (queener[white] < 8 && queener[black] == 8) {
  1219.     tree->score_eg += pawn_can_promote + (5 - queener[white]) * 10;
  1220.     return;
  1221.   } else if (queener[black] < 8 && queener[white] == 8) {
  1222.     tree->score_eg += -(pawn_can_promote + (5 - queener[black]) * 10);
  1223.     return;
  1224.   }
  1225.   if (queener[white] < queener[black] && forced_km[white]) {
  1226.     tree->score_eg += pawn_can_promote + (5 - queener[white]) * 10;
  1227.     return;
  1228.   } else if (queener[black] < queener[white] && forced_km[white]) {
  1229.     tree->score_eg += -(pawn_can_promote + (5 - queener[black]) * 10);
  1230.     return;
  1231.   }
  1232. }
  1233.  
  1234. /* last modified 02/23/14 */
  1235. /*
  1236.  *******************************************************************************
  1237.  *                                                                             *
  1238.  *   EvaluatePawns() is used to evaluate pawns.  It evaluates pawns for only   *
  1239.  *   one side, and fills in the pawn hash entry information.  It requires two  *
  1240.  *   calls to evaluate all pawns on the board.  Comments below indicate the    *
  1241.  *   particular pawn structure features that are evaluated.                    *
  1242.  *                                                                             *
  1243.  *   This procedure also fills in information (without scoring) that other     *
  1244.  *   evaluation procedures use, such as which pawns are passed or candidates,  *
  1245.  *   which pawns are weak, which files are open, and so forth.                 *
  1246.  *                                                                             *
  1247.  *******************************************************************************
  1248.  */
  1249. void EvaluatePawns(TREE * RESTRICT tree, int side) {
  1250.   uint64_t pawns;
  1251.   uint64_t temp;
  1252.   uint64_t p_moves[2];
  1253.   int square, file, rank, score_eg = 0, score_mg = 0;
  1254.   int defenders, attackers, sq;
  1255.   int enemy = Flip(side);
  1256.  
  1257. /*
  1258.  ************************************************************
  1259.  *                                                          *
  1260.  *  Initialize.                                             *
  1261.  *                                                          *
  1262.  ************************************************************
  1263.  */
  1264.   tree->pawn_score.all[side] = 0;
  1265.   tree->pawn_score.passed[side] = 0;
  1266. /*
  1267.  ************************************************************
  1268.  *                                                          *
  1269.  *  First, determine which squares pawns can reach.         *
  1270.  *                                                          *
  1271.  ************************************************************
  1272.  */
  1273.   p_moves[side] = 0;
  1274.   for (pawns = Pawns(side); pawns; pawns &= pawns - 1) {
  1275.     square = LSB(pawns);
  1276.     tree->pawn_score.all[side] |= 1 << File(square);
  1277.     for (sq = square; sq != File(square) + ((side) ? RANK7 << 3 : RANK2 << 3);
  1278.         sq += direction[side]) {
  1279.       p_moves[side] |= SetMask(sq);
  1280.       if (SetMask(sq + direction[side]) & tree->all_pawns)
  1281.         break;
  1282.       defenders =
  1283.           PopCnt(pawn_attacks[enemy][sq + direction[side]] & Pawns(side));
  1284.       attackers =
  1285.           PopCnt(pawn_attacks[side][sq + direction[side]] & Pawns(enemy));
  1286.       if (attackers - defenders > 0)
  1287.         break;
  1288.     }
  1289.   }
  1290. /*
  1291.  ************************************************************
  1292.  *                                                          *
  1293.  *  Loop through all pawns for this side.                   *
  1294.  *                                                          *
  1295.  ************************************************************
  1296.  */
  1297.   for (pawns = Pawns(side); pawns; pawns &= pawns - 1) {
  1298.     square = LSB(pawns);
  1299.     file = File(square);
  1300.     rank = rankflip[side][Rank(square)];
  1301. /*
  1302.  ************************************************************
  1303.  *                                                          *
  1304.  *  Evaluate pawn advances.  Center pawns are encouraged to *
  1305.  *  advance, while wing pawns are pretty much neutral.      *
  1306.  *  This is a simple piece/square value.                    *
  1307.  *                                                          *
  1308.  ************************************************************
  1309.  */
  1310.     score_mg += pval[mg][side][square];
  1311.     score_eg += pval[eg][side][square];
  1312. /*
  1313.  ************************************************************
  1314.  *                                                          *
  1315.  *  Evaluate isolated pawns, which  are penalized based on  *
  1316.  *  the file, with central isolani being worse than when on *
  1317.  *  the wings.                                              *
  1318.  *                                                          *
  1319.  ************************************************************
  1320.  */
  1321.     if (!(mask_pawn_isolated[square] & Pawns(side))) {
  1322.       score_mg -= pawn_isolated[mg];
  1323.       score_eg -= pawn_isolated[eg];
  1324.       if (!(Pawns(enemy) & file_mask[file])) {
  1325.         score_mg -= pawn_isolated[mg] / 2;
  1326.         score_eg -= pawn_isolated[eg] / 2;
  1327.       }
  1328.     }
  1329. /*
  1330.  ************************************************************
  1331.  *                                                          *
  1332.  *  Evaluate weak pawns.  Weak pawns are evaluated by the   *
  1333.  *  following rules:  (1) if a pawn is defended by a pawn,  *
  1334.  *  it isn't weak;  (2) if a pawn is undefended by a pawn   *
  1335.  *  and advances one (or two if it hasn't moved yet) ranks  *
  1336.  *  and is defended fewer times than it is attacked, it is  *
  1337.  *  weak.  Note that the penalty is greater if the pawn is  *
  1338.  *  on an open file.  Note that an isolated pawn is just    *
  1339.  *  another case of a weak pawn, since it can never be      *
  1340.  *  defended by a pawn.                                     *
  1341.  *                                                          *
  1342.  *  First, test the pawn where it sits to determine if it   *
  1343.  *  is defended more times than attacked.  If so, it is not *
  1344.  *  weak and we are done.  If it is weak where it sits, can *
  1345.  *  it advance one square and become not weak.  If so we    *
  1346.  *  are again finished with this pawn.  Otherwise we fall   *
  1347.  *  into the next test.                                     *
  1348.  *                                                          *
  1349.  ************************************************************
  1350.  */
  1351.     else {
  1352.       do {
  1353.         attackers = 0;
  1354.         defenders = 0;
  1355.         temp =
  1356.             p_moves[side] & ((side) ? plus8dir[square] : minus8dir[square]);
  1357.         for (; temp; temp &= temp - 1) {
  1358.           sq = LSB(temp);
  1359.           defenders = PopCnt(pawn_attacks[enemy][sq] & Pawns(side));
  1360.           attackers = PopCnt(pawn_attacks[side][sq] & Pawns(enemy));
  1361.           if (defenders && defenders >= attackers)
  1362.             break;
  1363.         }
  1364.         if (defenders && defenders >= attackers)
  1365.           break;
  1366. /*
  1367.  ************************************************************
  1368.  *                                                          *
  1369.  *  If the pawn can be defended by a pawn, and that pawn    *
  1370.  *  can safely advance to actually defend this pawn, then   *
  1371.  *  this pawn is not weak.                                  *
  1372.  *                                                          *
  1373.  ************************************************************
  1374.  */
  1375.         if (!(pawn_attacks[enemy][square] & p_moves[side])) {
  1376.           score_mg -= pawn_weak[mg];
  1377.           score_eg -= pawn_weak[eg];
  1378.           if (!(Pawns(enemy) & file_mask[file]))
  1379.             score_mg -= pawn_weak[mg] / 2;
  1380.         }
  1381.       } while (0);
  1382. /*
  1383.  ************************************************************
  1384.  *                                                          *
  1385.  *  Evaluate doubled pawns.  If there are other pawns on    *
  1386.  *  this file, penalize this pawn.                          *
  1387.  *                                                          *
  1388.  ************************************************************
  1389.  */
  1390.       if (PopCnt(file_mask[file] & Pawns(side)) > 1) {
  1391.         score_mg -= doubled_pawn_value[mg];
  1392.         score_eg -= doubled_pawn_value[eg];
  1393.       }
  1394. /*
  1395.  ************************************************************
  1396.  *                                                          *
  1397.  *  Test the pawn to see if it is connected with a neighbor *
  1398.  *  which makes it more mobile.                             *
  1399.  *                                                          *
  1400.  ************************************************************
  1401.  */
  1402.       if (mask_pawn_connected[square] & Pawns(side)) {
  1403.         score_mg += pawn_connected[mg];
  1404.         score_eg += pawn_connected[eg];
  1405.       }
  1406.     }
  1407. /*
  1408.  ************************************************************
  1409.  *                                                          *
  1410.  *  Discover and flag passed pawns for use later.           *
  1411.  *                                                          *
  1412.  ************************************************************
  1413.  */
  1414.     if (!(mask_passed[side][square] & Pawns(enemy)))
  1415.       tree->pawn_score.passed[side] |= 1 << file;
  1416. /*
  1417.  ************************************************************
  1418.  *                                                          *
  1419.  *  Determine if this pawn is a candidate passer, since we  *
  1420.  *  now know it isn't passed.  A candidate is a pawn on a   *
  1421.  *  file with no enemy pawns in front of it, and if it      *
  1422.  *  advances until it contacts an enemy pawn, and it is     *
  1423.  *  defended as many times as it is attacked when it        *
  1424.  *  reaches that pawn, then all that is left is to see if   *
  1425.  *  it is passed when the attacker(s) get removed.          *
  1426.  *                                                          *
  1427.  ************************************************************
  1428.  */
  1429.     else if (!(file_mask[File(square)] & Pawns(enemy))
  1430.         && mask_pawn_isolated[square] & Pawns(side)
  1431.         && !(pawn_attacks[side][square] & Pawns(enemy))) {
  1432.       attackers = 1;
  1433.       defenders = 0;
  1434.       for (sq = square;
  1435.           sq != File(square) + ((side) ? RANK7 << 3 : RANK2 << 3);
  1436.           sq += direction[side]) {
  1437.         if (SetMask(sq + direction[side]) & tree->all_pawns)
  1438.           break;
  1439.         defenders = PopCnt(pawn_attacks[enemy][sq] & p_moves[side]);
  1440.         attackers = PopCnt(pawn_attacks[side][sq] & Pawns(enemy));
  1441.         if (attackers)
  1442.           break;
  1443.       }
  1444.       if (attackers <= defenders) {
  1445.         if (!(mask_passed[side][sq + direction[side]] & Pawns(enemy))) {
  1446.           score_mg += passed_pawn_candidate[mg][rank];
  1447.           score_eg += passed_pawn_candidate[eg][rank];
  1448.         }
  1449.       }
  1450.     }
  1451. /*
  1452.  ************************************************************
  1453.  *                                                          *
  1454.  *  Evaluate "hidden" passed pawns.  Simple case is a pawn  *
  1455.  *  chain (white) at b5, a6, with a black pawn at a7.       *
  1456.  *  It appears the b-pawn is backward, with a ram at a6/a7  *
  1457.  *  but this is misleading, because the pawn at a6 is       *
  1458.  *  really passed when white plays b6.                      *
  1459.  *                                                          *
  1460.  ************************************************************
  1461.  */
  1462.     if (Rank(square) == ((side) ? RANK6 : RANK3)
  1463.         && SetMask(square + direction[side]) & Pawns(enemy)
  1464.         && ((File(square) < FILEH &&
  1465.                 SetMask(square + 9 - 16 * side) & Pawns(side)
  1466.                 && !(mask_hidden_right[side][File(square)] & Pawns(enemy)))
  1467.             || (File(square) > FILEA &&
  1468.                 SetMask(square + 7 - 16 * side) & Pawns(side)
  1469.                 && !(mask_hidden_left[side][File(square)] & Pawns(enemy))))) {
  1470.       score_mg += passed_pawn_hidden[mg];
  1471.       score_eg += passed_pawn_hidden[eg];
  1472.     }
  1473.   }
  1474. /*
  1475.  ************************************************************
  1476.  *                                                          *
  1477.  *  Evaluate king safety.                                   *
  1478.  *                                                          *
  1479.  *  This uses the function EvaluateKingsFile() which looks  *
  1480.  *  at four possible positions for the king, either castled *
  1481.  *  kingside, queenside or else standing on the d or e file *
  1482.  *  stuck in the middle.  This essentially is about the     *
  1483.  *  pawns in front of the king and what kind of "shelter"   *
  1484.  *  they provide for the king during the middlegame.        *
  1485.  *                                                          *
  1486.  ************************************************************
  1487.  */
  1488.   tree->pawn_score.defects_q[side] = EvaluateKingsFile(tree, FILEB, side);
  1489.   tree->pawn_score.defects_d[side] = EvaluateKingsFile(tree, FILED, side);
  1490.   tree->pawn_score.defects_e[side] = EvaluateKingsFile(tree, FILEE, side);
  1491.   tree->pawn_score.defects_k[side] = EvaluateKingsFile(tree, FILEG, side);
  1492.   tree->pawn_score.score_mg += sign[side] * score_mg;
  1493.   tree->pawn_score.score_eg += sign[side] * score_eg;
  1494. }
  1495.  
  1496. /* last modified 02/23/14 */
  1497. /*
  1498.  *******************************************************************************
  1499.  *                                                                             *
  1500.  *   EvaluateQueens() is used to evaluate queens.                              *
  1501.  *                                                                             *
  1502.  *******************************************************************************
  1503.  */
  1504. void EvaluateQueens(TREE * RESTRICT tree, int side) {
  1505.   uint64_t temp;
  1506.   int square, t, score_mg = 0, score_eg = 0;
  1507.   int enemy = Flip(side);
  1508.  
  1509. /*
  1510.  ************************************************************
  1511.  *                                                          *
  1512.  *  First locate each queen and obtain it's centralization  *
  1513.  *  score from the static piece/square table for queens.    *
  1514.  *                                                          *
  1515.  ************************************************************
  1516.  */
  1517.   for (temp = Queens(side); temp; temp &= temp - 1) {
  1518.     square = LSB(temp);
  1519. /*
  1520.  ************************************************************
  1521.  *                                                          *
  1522.  *  Then, add in the piece/square table value for the       *
  1523.  *  queen.                                                  *
  1524.  *                                                          *
  1525.  ************************************************************
  1526. */
  1527.     score_mg += qval[mg][side][square];
  1528.     score_eg += qval[eg][side][square];
  1529. /*
  1530.  ************************************************************
  1531.  *                                                          *
  1532.  *  Adjust the tropism count for this piece.                *
  1533.  *                                                          *
  1534.  ************************************************************
  1535.  */
  1536.     if (tree->dangerous[side]) {
  1537.       t = KingSQ(enemy);
  1538.       tree->tropism[side] += king_tropism_q[Distance(square, t)];
  1539.       t = 8 - (RankDistance(square, t) + FileDistance(square, t));
  1540.       score_mg += t;
  1541.       score_eg += t;
  1542.     }
  1543.   }
  1544.   tree->score_mg += sign[side] * score_mg;
  1545.   tree->score_eg += sign[side] * score_eg;
  1546. }
  1547.  
  1548. /* last modified 02/23/14 */
  1549. /*
  1550.  *******************************************************************************
  1551.  *                                                                             *
  1552.  *   EvaluateRooks() is used to evaluate rooks.                                *
  1553.  *                                                                             *
  1554.  *******************************************************************************
  1555.  */
  1556. void EvaluateRooks(TREE * RESTRICT tree, int side) {
  1557.   uint64_t temp, moves;
  1558.   int square, rank, fRank, file, i, t, mobility;
  1559.   int score_mg = 0, score_eg = 0;
  1560.   int enemy = Flip(side);
  1561.  
  1562. /*
  1563.  ************************************************************
  1564.  *                                                          *
  1565.  *  Initialize.                                             *
  1566.  *                                                          *
  1567.  ************************************************************
  1568.  */
  1569.   for (temp = Rooks(side); temp; temp &= temp - 1) {
  1570.     square = LSB(temp);
  1571.     file = File(square);
  1572.     rank = Rank(square);
  1573.     fRank = rankflip[side][rank];
  1574. /*
  1575.  ************************************************************
  1576.  *                                                          *
  1577.  *  Determine if the rook is on an open file or on a half-  *
  1578.  *  open file, either of which increases its ability to     *
  1579.  *  attack important squares.                               *
  1580.  *                                                          *
  1581.  ************************************************************
  1582.  */
  1583.     if (!(file_mask[file] & Pawns(side))) {
  1584.       if (!(file_mask[file] & Pawns(enemy))) {
  1585.         score_mg += rook_open_file[mg];
  1586.         score_eg += rook_open_file[eg];
  1587.       } else {
  1588.         score_mg += rook_half_open_file[mg];
  1589.         score_eg += rook_half_open_file[eg];
  1590.       }
  1591.     }
  1592. /*
  1593.  ************************************************************
  1594.  *                                                          *
  1595.  *  Check to see if the king has been forced to move and    *
  1596.  *  has trapped a rook at a1/b1/g1/h1, if so, then penalize *
  1597.  *  the trapped rook to help extricate it.                  *
  1598.  *                                                          *
  1599.  ************************************************************
  1600.  */
  1601.     if (fRank == RANK1) {
  1602.       if (rank == Rank(KingSQ(side))) {
  1603.         i = File(KingSQ(side));
  1604.         if (i > FILEE) {
  1605.           if (file > i) {
  1606.             score_mg -= rook_trapped;
  1607.             score_eg -= rook_trapped;
  1608.           }
  1609.         } else if (i < FILED && file < i) {
  1610.           score_mg -= rook_trapped;
  1611.           score_eg -= rook_trapped;
  1612.         }
  1613.       }
  1614.     }
  1615. /*
  1616.  ************************************************************
  1617.  *                                                          *
  1618.  *  Determine if the rook is on the 7th rank.  If so the    *
  1619.  *  rook exerts a "cramping" effect that is valuable.       *
  1620.  *                                                          *
  1621.  ************************************************************
  1622.  */
  1623.     else if (fRank == RANK7) {
  1624.       score_mg += rook_on_7th[mg];
  1625.       score_eg += rook_on_7th[eg];
  1626.     }
  1627. /*
  1628.  ************************************************************
  1629.  *                                                          *
  1630.  *  Mobility counts the number of squares the piece         *
  1631.  *  attacks, and weighs each square according to a complex  *
  1632.  *  formula that includes files as well as total number of  *
  1633.  *  squares attacked.                                       *
  1634.  *                                                          *
  1635.  *  For efficiency, we use a pre-computed mobility score    *
  1636.  *  that is accessed just like a magic attack generation.   *
  1637.  *                                                          *
  1638.  ************************************************************
  1639.  */
  1640.     mobility = RookMobility(square, OccupiedSquares);
  1641.     score_mg += mobility;
  1642.     score_eg += mobility;
  1643. /*
  1644.  ************************************************************
  1645.  *                                                          *
  1646.  *  Adjust the tropism count for this piece.                *
  1647.  *                                                          *
  1648.  ************************************************************
  1649.  */
  1650.     if (tree->dangerous[side]) {
  1651.       moves = king_attacks[KingSQ(enemy)];
  1652.       t = (rook_attacks[square] & moves &&
  1653.           RookAttacks(square,
  1654.               OccupiedSquares & ~(Queens(side) | (Rooks(side)))) & moves) ? 1
  1655.           : Distance(square, KingSQ(enemy));
  1656.       tree->tropism[side] += king_tropism_r[t];
  1657.     }
  1658.   }
  1659.   tree->score_mg += sign[side] * score_mg;
  1660.   tree->score_eg += sign[side] * score_eg;
  1661. }
  1662.  
  1663. /* last modified 02/23/14 */
  1664. /*
  1665.  *******************************************************************************
  1666.  *                                                                             *
  1667.  *   EvaluateWinningChances() is used to determine if one side has reached a   *
  1668.  *   position which can not be won, period, even though side may be ahead in   *
  1669.  *   material in some way.                                                     *
  1670.  *                                                                             *
  1671.  *   Return values:                                                            *
  1672.  *        0    ->     side on move can not win.                                *
  1673.  *        1    ->     side on move can win.                                    *
  1674.  *                                                                             *
  1675.  *******************************************************************************
  1676.  */
  1677. int EvaluateWinningChances(TREE * RESTRICT tree, int side, int wtm) {
  1678.   int square, ekd, promote;
  1679.   int enemy = Flip(side);
  1680.  
  1681. /*
  1682.  ************************************************************
  1683.  *                                                          *
  1684.  *  If side has a piece and no pawn, it can not possibly    *
  1685.  *  win.  If side is a piece ahead, the only way it can win *
  1686.  *  is if the enemy is already trapped on the edge of the   *
  1687.  *  board (special case to handle KRB vs KR which can be    *
  1688.  *  won if the king gets trapped).                          *
  1689.  *                                                          *
  1690.  ************************************************************
  1691.  */
  1692.   if (TotalPieces(side, pawn) == 0) {
  1693.     if (TotalPieces(side, occupied) <= 3)
  1694.       return 0;
  1695.     if (TotalPieces(side, occupied) - TotalPieces(enemy, occupied) <= 3 &&
  1696.         mask_not_edge & Kings(enemy))
  1697.       return 0;
  1698.   }
  1699. /*
  1700.  ************************************************************
  1701.  *                                                          *
  1702.  *  If "side" has a pawn, then either the pawn had better   *
  1703.  *  not be a rook pawn, or else white had better have the   *
  1704.  *  right color bishop or any other piece, otherwise it is  *
  1705.  *  not winnable if the enemy king can get to the queening  *
  1706.  *  square first.                                           *
  1707.  *                                                          *
  1708.  ************************************************************
  1709.  */
  1710.   else if (!(Pawns(side) & not_rook_pawns))
  1711.     do {
  1712.       if (TotalPieces(side, occupied) > 3 || (TotalPieces(side, occupied) == 3
  1713.               && Knights(side)))
  1714.         continue;
  1715.       if (file_mask[FILEA] & Pawns(side) && file_mask[FILEH] & Pawns(side))
  1716.         continue;
  1717.       if (Bishops(side)) {
  1718.         if (Bishops(side) & dark_squares) {
  1719.           if (file_mask[dark_corner[side]] & Pawns(side))
  1720.             continue;
  1721.         } else if (file_mask[light_corner[side]] & Pawns(side))
  1722.           continue;
  1723.       }
  1724.       if (Pawns(side) & file_mask[FILEA])
  1725.         promote = A8;
  1726.       else
  1727.         promote = H8;
  1728.       ekd = Distance(KingSQ(enemy), sqflip[side][promote]) - (wtm != side);
  1729.       if (ekd <= 1)
  1730.         return 0;
  1731.     } while (0);
  1732. /*
  1733.  ************************************************************
  1734.  *                                                          *
  1735.  *  Check to see if this is a KRP vs KR or KQP vs KQ type   *
  1736.  *  ending.  If so, and the losing king is in front of the  *
  1737.  *  passer, then this is a drawish ending.                  *
  1738.  *                                                          *
  1739.  ************************************************************
  1740.  */
  1741.   if (TotalPieces(side, pawn) == 1 && TotalPieces(enemy, pawn) == 0 &&
  1742.       ((TotalPieces(side, occupied) == 5 && TotalPieces(enemy, occupied) == 5)
  1743.           || (TotalPieces(side, occupied) == 9 &&
  1744.               TotalPieces(enemy, occupied) == 9))) {
  1745.     square = LSB(Pawns(side));
  1746.     if (FileDistance(KingSQ(enemy), square) <= 1 &&
  1747.         InFront(side, Rank(KingSQ(enemy)), Rank(square)))
  1748.       return 0;
  1749.   }
  1750. /*
  1751.  ************************************************************
  1752.  *                                                          *
  1753.  *  If this side has pawns, and we have made it through the *
  1754.  *  previous tests, then this side has winning chances.     *
  1755.  *                                                          *
  1756.  ************************************************************
  1757.  */
  1758.   if (TotalPieces(side, pawn))
  1759.     return 1;
  1760. /*
  1761.  ************************************************************
  1762.  *                                                          *
  1763.  *  If this side has two bishops, and the enemy has only a  *
  1764.  *  single kinght, the two bishops win.                     *
  1765.  *                                                          *
  1766.  ************************************************************
  1767.  */
  1768.   if (TotalPieces(side, occupied) == 6)
  1769.     if (TotalPieces(enemy, occupied) == 3 && (Knights(side)
  1770.             || !Knights(enemy)))
  1771.       return 0;
  1772. /*
  1773.  ************************************************************
  1774.  *                                                          *
  1775.  *  If one side is two knights ahead and the opponent has   *
  1776.  *  no remaining material, it is a draw.                    *
  1777.  *                                                          *
  1778.  ************************************************************
  1779.  */
  1780.   if (TotalPieces(side, occupied) == 6 && !Bishops(side)
  1781.       && TotalPieces(enemy, occupied) + TotalPieces(enemy, pawn) == 0)
  1782.     return 0;
  1783.   return 1;
  1784. }
  1785.