+ score += make_score(mbonus, ebonus);
+
+ } while (b);
+
+ // Add the scores to the middle game and endgame eval
+ return apply_weight(score, Weights[PassedPawns]);
+ }
+
+
+ // evaluate_unstoppable_pawns() evaluates the unstoppable passed pawns for both sides, this is quite
+ // conservative and returns a winning score only when we are very sure that the pawn is winning.
+
+ Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei) {
+
+ Bitboard b, b2, blockers, supporters, queeningPath, candidates;
+ Square s, blockSq, queeningSquare;
+ Color c, winnerSide, loserSide;
+ bool pathDefended, opposed;
+ int pliesToGo, movesToGo, oppMovesToGo, sacptg, blockersCount, minKingDist, kingptg, d;
+ int pliesToQueen[] = { 256, 256 };
+
+ // Step 1. Hunt for unstoppable passed pawns. If we find at least one,
+ // record how many plies are required for promotion.
+ for (c = WHITE; c <= BLACK; c++)
+ {
+ // Skip if other side has non-pawn pieces
+ if (pos.non_pawn_material(~c))
+ continue;
+
+ b = ei.pi->passed_pawns(c);
+
+ while (b)
+ {
+ s = pop_lsb(&b);
+ queeningSquare = relative_square(c, file_of(s) | RANK_8);
+ queeningPath = forward_bb(c, s);
+
+ // Compute plies to queening and check direct advancement
+ movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2);
+ oppMovesToGo = square_distance(pos.king_square(~c), queeningSquare) - int(c != pos.side_to_move());
+ pathDefended = ((ei.attackedBy[c][ALL_PIECES] & queeningPath) == queeningPath);
+
+ if (movesToGo >= oppMovesToGo && !pathDefended)
+ continue;
+
+ // Opponent king cannot block because path is defended and position
+ // is not in check. So only friendly pieces can be blockers.
+ assert(!pos.checkers());
+ assert((queeningPath & pos.pieces()) == (queeningPath & pos.pieces(c)));
+
+ // Add moves needed to free the path from friendly pieces and retest condition
+ movesToGo += popcount<Max15>(queeningPath & pos.pieces(c));
+
+ if (movesToGo >= oppMovesToGo && !pathDefended)
+ continue;
+
+ pliesToGo = 2 * movesToGo - int(c == pos.side_to_move());
+ pliesToQueen[c] = std::min(pliesToQueen[c], pliesToGo);
+ }
+ }
+
+ // Step 2. If either side cannot promote at least three plies before the other side then situation
+ // becomes too complex and we give up. Otherwise we determine the possibly "winning side"
+ if (abs(pliesToQueen[WHITE] - pliesToQueen[BLACK]) < 3)
+ return SCORE_ZERO;
+
+ winnerSide = (pliesToQueen[WHITE] < pliesToQueen[BLACK] ? WHITE : BLACK);
+ loserSide = ~winnerSide;
+
+ // Step 3. Can the losing side possibly create a new passed pawn and thus prevent the loss?
+ b = candidates = pos.pieces(loserSide, PAWN);
+
+ while (b)
+ {
+ s = pop_lsb(&b);
+
+ // Compute plies from queening
+ queeningSquare = relative_square(loserSide, file_of(s) | RANK_8);
+ movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(loserSide, s) == RANK_2);
+ pliesToGo = 2 * movesToGo - int(loserSide == pos.side_to_move());
+
+ // Check if (without even considering any obstacles) we're too far away or doubled
+ if ( pliesToQueen[winnerSide] + 3 <= pliesToGo
+ || (forward_bb(loserSide, s) & pos.pieces(loserSide, PAWN)))
+ candidates ^= s;
+ }
+
+ // If any candidate is already a passed pawn it _may_ promote in time. We give up.
+ if (candidates & ei.pi->passed_pawns(loserSide))
+ return SCORE_ZERO;
+
+ // Step 4. Check new passed pawn creation through king capturing and pawn sacrifices
+ b = candidates;
+
+ while (b)
+ {
+ s = pop_lsb(&b);
+ sacptg = blockersCount = 0;
+ minKingDist = kingptg = 256;