]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Templetize sliding attacks
[stockfish] / src / position.cpp
index ccc29acf20974d8a09c6a26ccdc209150c76ce1a..9fa7c7294fdb3425da5cdfffd9be792850fd94f8 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <cassert>
 #include <cstring>
-#include <fstream>
 #include <iostream>
 #include <sstream>
 #include <algorithm>
@@ -387,8 +386,8 @@ Bitboard Position::attackers_to(Square s, Bitboard occ) const {
   return  (attacks_from<PAWN>(s, BLACK) & pieces(PAWN, WHITE))
         | (attacks_from<PAWN>(s, WHITE) & pieces(PAWN, BLACK))
         | (attacks_from<KNIGHT>(s)      & pieces(KNIGHT))
-        | (rook_attacks_bb(s, occ)      & pieces(ROOK, QUEEN))
-        | (bishop_attacks_bb(s, occ)    & pieces(BISHOP, QUEEN))
+        | (attacks_bb<ROOK>(s, occ)     & pieces(ROOK, QUEEN))
+        | (attacks_bb<BISHOP>(s, occ)   & pieces(BISHOP, QUEEN))
         | (attacks_from<KING>(s)        & pieces(KING));
 }
 
@@ -402,9 +401,9 @@ Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) {
 
   switch (type_of(p))
   {
-  case BISHOP: return bishop_attacks_bb(s, occ);
-  case ROOK  : return rook_attacks_bb(s, occ);
-  case QUEEN : return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ);
+  case BISHOP: return attacks_bb<BISHOP>(s, occ);
+  case ROOK  : return attacks_bb<ROOK>(s, occ);
+  case QUEEN : return attacks_bb<BISHOP>(s, occ) | attacks_bb<ROOK>(s, occ);
   default    : return StepAttacksBB[p][s];
   }
 }
@@ -427,15 +426,16 @@ bool Position::move_attacks_square(Move m, Square s) const {
 
   // Update occupancy as if the piece is moving
   occ = occupied_squares();
-  do_move_bb(&occ, make_move_bb(from, to));
+  occ ^= from;
+  occ ^= to;
 
   // The piece moved in 'to' attacks the square 's' ?
-  if (bit_is_set(attacks_from(piece, to, occ), s))
+  if (attacks_from(piece, to, occ) & s)
       return true;
 
   // Scan for possible X-ray attackers behind the moved piece
-  xray = (rook_attacks_bb(s, occ)   & pieces(ROOK, QUEEN, color_of(piece)))
-        |(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN, color_of(piece)));
+  xray = (attacks_bb<ROOK>(s, occ)   & pieces(ROOK, QUEEN, color_of(piece)))
+        |(attacks_bb<BISHOP>(s, occ) & pieces(BISHOP, QUEEN, color_of(piece)));
 
   // Verify attackers are triggered by our move and not already existing
   return xray && (xray ^ (xray & attacks_from<QUEEN>(s)));
@@ -471,12 +471,12 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
       assert(piece_on(capsq) == make_piece(them, PAWN));
       assert(piece_on(to) == NO_PIECE);
 
-      clear_bit(&b, from);
-      clear_bit(&b, capsq);
-      set_bit(&b, to);
+      b ^= from;
+      b ^= capsq;
+      b |= to;
 
-      return   !(rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, them))
-            && !(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, them));
+      return   !(attacks_bb<ROOK>(ksq, b) & pieces(ROOK, QUEEN, them))
+            && !(attacks_bb<BISHOP>(ksq, b) & pieces(BISHOP, QUEEN, them));
   }
 
   // If the moving piece is a king, check whether the destination
@@ -488,7 +488,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
   // A non-king move is legal if and only if it is not pinned or it
   // is moving along the ray towards or away from the king.
   return   !pinned
-        || !bit_is_set(pinned, from)
+        || !(pinned & from)
         ||  squares_aligned(from, to_sq(m), king_square(us));
 }
 
@@ -598,7 +598,7 @@ bool Position::is_pseudo_legal(const Move m) const {
           return false;
       }
   }
-  else if (!bit_is_set(attacks_from(pc, from), to))
+  else if (!(attacks_from(pc, from) & to))
       return false;
 
   // Evasions generator already takes care to avoid some kind of illegal moves
@@ -611,7 +611,7 @@ bool Position::is_pseudo_legal(const Move m) const {
       if (type_of(piece_on(from)) == KING)
       {
           Bitboard b = occupied_squares();
-          clear_bit(&b, from);
+          b ^= from;
           if (attackers_to(to_sq(m), b) & pieces(~us))
               return false;
       }
@@ -625,7 +625,7 @@ bool Position::is_pseudo_legal(const Move m) const {
 
           // Our move must be a blocking evasion or a capture of the checking piece
           target = squares_between(checksq, king_square(us)) | checkers();
-          if (!bit_is_set(target, to_sq(m)))
+          if (!(target & to_sq(m)))
               return false;
       }
   }
@@ -647,11 +647,11 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
   PieceType pt = type_of(piece_on(from));
 
   // Direct check ?
-  if (bit_is_set(ci.checkSq[pt], to))
+  if (ci.checkSq[pt] & to)
       return true;
 
   // Discovery check ?
-  if (ci.dcCandidates && bit_is_set(ci.dcCandidates, from))
+  if (ci.dcCandidates && (ci.dcCandidates & from))
   {
       // For pawn and king moves we need to verify also direction
       if (  (pt != PAWN && pt != KING)
@@ -670,8 +670,8 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
   // Promotion with check ?
   if (is_promotion(m))
   {
-      clear_bit(&b, from);
-      return bit_is_set(attacks_from(Piece(promotion_piece_type(m)), to, b), ksq);
+      b ^= from;
+      return attacks_from(Piece(promotion_piece_type(m)), to, b) & ksq;
   }
 
   // En passant capture with check ? We have already handled the case
@@ -681,11 +681,11 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
   if (is_enpassant(m))
   {
       Square capsq = make_square(file_of(to), rank_of(from));
-      clear_bit(&b, from);
-      clear_bit(&b, capsq);
-      set_bit(&b, to);
-      return  (rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us))
-            ||(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, us));
+      b ^= from;
+      b ^= capsq;
+      b |= to;
+      return  (attacks_bb<ROOK>(ksq, b) & pieces(ROOK, QUEEN, us))
+            ||(attacks_bb<BISHOP>(ksq, b) & pieces(BISHOP, QUEEN, us));
   }
 
   // Castling with check ?
@@ -703,11 +703,11 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
           kto = relative_square(us, SQ_C1);
           rto = relative_square(us, SQ_D1);
       }
-      clear_bit(&b, kfrom);
-      clear_bit(&b, rfrom);
-      set_bit(&b, rto);
-      set_bit(&b, kto);
-      return bit_is_set(rook_attacks_bb(rto, b), ksq);
+      b ^= kfrom;
+      b ^= rfrom;
+      b |= rto;
+      b |= kto;
+      return attacks_bb<ROOK>(rto, b) & ksq;
   }
 
   return false;
@@ -752,7 +752,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   k ^= zobSideToMove;
 
   // Increment the 50 moves rule draw counter. Resetting it to zero in the
-  // case of non-reversible moves is taken care of later.
+  // case of a capture or a pawn move is taken care of later.
   st->rule50++;
   st->pliesFromNull++;
 
@@ -802,9 +802,9 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
           st->npMaterial[them] -= PieceValueMidgame[capture];
 
       // Remove the captured piece
-      clear_bit(&byColorBB[them], capsq);
-      clear_bit(&byTypeBB[capture], capsq);
-      clear_bit(&occupied, capsq);
+      byColorBB[them] ^= capsq;
+      byTypeBB[capture] ^= capsq;
+      occupied ^= capsq;
 
       // Update piece list, move the last piece at index[capsq] position and
       // shrink the list.
@@ -852,10 +852,10 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   prefetch((char*)TT.first_entry(k));
 
   // Move the piece
-  Bitboard move_bb = make_move_bb(from, to);
-  do_move_bb(&byColorBB[us], move_bb);
-  do_move_bb(&byTypeBB[pt], move_bb);
-  do_move_bb(&occupied, move_bb);
+  Bitboard from_to_bb = SquareBB[from] | SquareBB[to];
+  byColorBB[us] ^= from_to_bb;
+  byTypeBB[pt] ^= from_to_bb;
+  occupied ^= from_to_bb;
 
   board[to] = board[from];
   board[from] = NO_PIECE;
@@ -884,8 +884,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
           assert(promotion >= KNIGHT && promotion <= QUEEN);
 
           // Replace the pawn with the promoted piece
-          clear_bit(&byTypeBB[PAWN], to);
-          set_bit(&byTypeBB[promotion], to);
+          byTypeBB[PAWN] ^= to;
+          byTypeBB[promotion] |= to;
           board[to] = make_piece(us, promotion);
 
           // Update piece lists, move the last pawn at index[to] position
@@ -941,11 +941,11 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
       else
       {
           // Direct checks
-          if (bit_is_set(ci.checkSq[pt], to))
-              st->checkersBB = SetMaskBB[to];
+          if (ci.checkSq[pt] & to)
+              st->checkersBB |= to;
 
           // Discovery checks
-          if (ci.dcCandidates && bit_is_set(ci.dcCandidates, from))
+          if (ci.dcCandidates && (ci.dcCandidates & from))
           {
               if (pt != ROOK)
                   st->checkersBB |= attacks_from<ROOK>(king_square(them)) & pieces(ROOK, QUEEN, us);
@@ -1000,8 +1000,8 @@ void Position::undo_move(Move m) {
       assert(promotion >= KNIGHT && promotion <= QUEEN);
 
       // Replace the promoted piece with the pawn
-      clear_bit(&byTypeBB[promotion], to);
-      set_bit(&byTypeBB[PAWN], to);
+      byTypeBB[promotion] ^= to;
+      byTypeBB[PAWN] |= to;
       board[to] = make_piece(us, PAWN);
 
       // Update piece lists, move the last promoted piece at index[to] position
@@ -1017,10 +1017,10 @@ void Position::undo_move(Move m) {
   }
 
   // Put the piece back at the source square
-  Bitboard move_bb = make_move_bb(to, from);
-  do_move_bb(&byColorBB[us], move_bb);
-  do_move_bb(&byTypeBB[pt], move_bb);
-  do_move_bb(&occupied, move_bb);
+  Bitboard from_to_bb = SquareBB[from] | SquareBB[to];
+  byColorBB[us] ^= from_to_bb;
+  byTypeBB[pt] ^= from_to_bb;
+  occupied ^= from_to_bb;
 
   board[from] = board[to];
   board[to] = NO_PIECE;
@@ -1045,9 +1045,9 @@ void Position::undo_move(Move m) {
       }
 
       // Restore the captured piece
-      set_bit(&byColorBB[them], capsq);
-      set_bit(&byTypeBB[capture], capsq);
-      set_bit(&occupied, capsq);
+      byColorBB[them] |= capsq;
+      byTypeBB[capture] |= capsq;
+      occupied |= capsq;
 
       board[capsq] = make_piece(them, capture);
 
@@ -1101,20 +1101,20 @@ void Position::do_castle_move(Move m) {
   assert(piece_on(rfrom) == make_piece(us, ROOK));
 
   // Remove pieces from source squares
-  clear_bit(&byColorBB[us], kfrom);
-  clear_bit(&byTypeBB[KING], kfrom);
-  clear_bit(&occupied, kfrom);
-  clear_bit(&byColorBB[us], rfrom);
-  clear_bit(&byTypeBB[ROOK], rfrom);
-  clear_bit(&occupied, rfrom);
+  byColorBB[us] ^= kfrom;
+  byTypeBB[KING] ^= kfrom;
+  occupied ^= kfrom;
+  byColorBB[us] ^= rfrom;
+  byTypeBB[ROOK] ^= rfrom;
+  occupied ^= rfrom;
 
   // Put pieces on destination squares
-  set_bit(&byColorBB[us], kto);
-  set_bit(&byTypeBB[KING], kto);
-  set_bit(&occupied, kto);
-  set_bit(&byColorBB[us], rto);
-  set_bit(&byTypeBB[ROOK], rto);
-  set_bit(&occupied, rto);
+  byColorBB[us] |= kto;
+  byTypeBB[KING] |= kto;
+  occupied |= kto;
+  byColorBB[us] |= rto;
+  byTypeBB[ROOK] |= rto;
+  occupied |= rto;
 
   // Update board
   Piece king = make_piece(us, KING);
@@ -1155,9 +1155,6 @@ void Position::do_castle_move(Move m) {
       st->castleRights &= castleRightsMask[kfrom];
       st->key ^= zobCastle[st->castleRights];
 
-      // Reset rule 50 counter
-      st->rule50 = 0;
-
       // Update checkers BB
       st->checkersBB = attackers_to(king_square(~us)) & pieces(us);
 
@@ -1269,13 +1266,13 @@ int Position::see(Move m) const {
       assert(type_of(piece_on(capQq)) == PAWN);
 
       // Remove the captured pawn
-      clear_bit(&occ, capQq);
+      occ ^= capQq;
       capturedType = PAWN;
   }
 
   // Find all attackers to the destination square, with the moving piece
   // removed, but possibly an X-ray attacker added behind it.
-  clear_bit(&occ, from);
+  occ ^= from;
   attackers = attackers_to(to, occ);
 
   // If the opponent has no attackers we are finished
@@ -1304,8 +1301,8 @@ int Position::see(Move m) const {
       // and scan for new X-ray attacks behind the attacker.
       b = stmAttackers & pieces(pt);
       occ ^= (b & (~b + 1));
-      attackers |=  (rook_attacks_bb(to, occ)   & pieces(ROOK, QUEEN))
-                  | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN));
+      attackers |=  (attacks_bb<ROOK>(to, occ)   & pieces(ROOK, QUEEN))
+                  | (attacks_bb<BISHOP>(to, occ) & pieces(BISHOP, QUEEN));
 
       attackers &= occ; // Cut out pieces we've already done
 
@@ -1379,9 +1376,9 @@ void Position::put_piece(Piece p, Square s) {
   index[s] = pieceCount[c][pt]++;
   pieceList[c][pt][index[s]] = s;
 
-  set_bit(&byTypeBB[pt], s);
-  set_bit(&byColorBB[c], s);
-  set_bit(&occupied, s);
+  byTypeBB[pt] |= s;
+  byColorBB[c] |= s;
+  occupied |= s;
 }