Advertisement
adfasdfadsfasdf

Untitled

Jun 27th, 2023
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.31 KB | None | 0 0
  1. ```cpp
  2. template<Color color>
  3. bool static_exchange_eval(Position& board, Move move, const int threshold) {
  4.  
  5.     if (move.is_promotion()) return true;
  6.  
  7.     Square to = move.to();
  8.     Square from = move.from();
  9.     PieceType piece_captured = type_of(board.piece_at(to));
  10.     PieceType piece_capturing = type_of(board.piece_at(from));
  11.  
  12.     // If we make the capture and don't loose our piece, we should beat the threshold.
  13.     // If we don't it's likely a bad exchange.
  14.     int value = ORDERING_PIECE_VALUES[piece_captured] - threshold;
  15.     if (value < 0) return false;
  16.  
  17.     // If we loose our piece and are still positive, this is a good exchange.
  18.     value -= ORDERING_PIECE_VALUES[piece_capturing];
  19.     if (value >= 0) return true;
  20.  
  21.     // We already know the piece on 'from' is an attacker. Ignore it. The piece on to will be captured. Ignore it.
  22.     Bitboard occupied = board.occupancy() ^ square_to_bitboard(from) ^ square_to_bitboard(to);
  23.     // This will be updated to only contain pieces that only have pieces we are concerned with.
  24.     Bitboard attackers = board.attackers_of(to, occupied);
  25.  
  26.     Bitboard bishops = board.occupancy<BISHOP>() | board.occupancy<QUEEN>();
  27.     Bitboard rooks   = board.occupancy<ROOK>()   | board.occupancy<QUEEN>();
  28.  
  29.     Color side_to_play = ~color;
  30.  
  31.     while (true) {
  32.         attackers &= occupied;
  33.  
  34.         Bitboard our_attackers = attackers & board.occupancy(side_to_play);
  35.         if (!our_attackers) break; // If no remaining attackers for us, break.
  36.  
  37.         u32 ipt;
  38.         for (ipt = PAWN; ipt < KING; ipt++) { // pt == king when we break if all others didn't cause break.
  39.             if (our_attackers & board.occupancy(side_to_play, PieceType(ipt))) break;
  40.         }
  41.         auto piece_type = PieceType(ipt);
  42.  
  43.         side_to_play = ~side_to_play;
  44.  
  45.         value = -value - 1 - ORDERING_PIECE_VALUES[piece_type];
  46.         if (value >= 0) {
  47.             if (piece_type == KING && (attackers & board.occupancy(side_to_play))) side_to_play = ~side_to_play;
  48.             break;
  49.         }
  50.  
  51.         occupied ^= square_to_bitboard(lsb(our_attackers & board.occupancy(piece_type)));
  52.  
  53.         // Add discovered attacks.
  54.         if (piece_type == PAWN || piece_type == BISHOP || piece_type == QUEEN)
  55.             attackers |= tables::attacks<BISHOP>(to, occupied) & bishops;
  56.         if (piece_type == ROOK || piece_type == QUEEN)
  57.             attackers |= tables::attacks<ROOK>(to, occupied) & rooks;
  58.     }
  59.     return side_to_play != color_of(board.piece_at(from));
  60. }
  61. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement