// Capture the flag
if (pos.capture_the_flag(Us))
{
- bool isKingCTF = pos.capture_the_flag_piece() == KING;
+ PieceType ptCtf = pos.capture_the_flag_piece();
Bitboard ctfPieces = pos.pieces(Us, pos.capture_the_flag_piece());
- int scale = pos.count(Us, pos.capture_the_flag_piece());
- while (ctfPieces)
+ Bitboard ctfTargets = pos.capture_the_flag(Us) & pos.board_bb();
+ Bitboard onHold = 0;
+ Bitboard processed = 0;
+ // Traverse all paths of the CTF pieces to the CTF targets.
+ // Put squares that are attacked or occupied on hold for one iteration.
+ for (int dist = 0; ctfPieces && (ctfTargets & ~processed); dist++)
{
- Square s1 = pop_lsb(&ctfPieces);
- Bitboard target_squares = pos.capture_the_flag(Us) & pos.board_bb();
- while (target_squares)
+ score += make_score(2500, 2500) * popcount(ctfTargets & ctfPieces) / (1 + dist * dist);
+ Bitboard current = ctfPieces;
+ processed |= ctfPieces;
+ ctfPieces = onHold & ~processed;
+ onHold = 0;
+ while (current)
{
- Square s2 = pop_lsb(&target_squares);
- int dist = distance(s1, s2)
- + (isKingCTF || pos.flag_move() ? popcount(pos.attackers_to(s2, Them)) : 0)
- + !!(pos.pieces(Us) & s2);
- score += make_score(2500, 2500) / (1 + scale * dist * dist);
+ Square s = pop_lsb(¤t);
+ Bitboard attacks = ( (PseudoAttacks[Us][ptCtf][s] & pos.pieces())
+ | (PseudoMoves[Us][ptCtf][s] & ~pos.pieces())) & ~processed & pos.board_bb();
+ ctfPieces |= attacks & ~pos.pieces(Us) & ~attackedBy[Them][ALL_PIECES];
+ onHold |= attacks;
}
}
}