]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Guard against 'divide by zero' in bench
[stockfish] / src / position.cpp
index c26ab1b6884abe0c17066dac51ada332f900033c..4d3f32a4d984d3b8edc5c92a3aff05d808098078 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "bitcount.h"
 #include "movegen.h"
+#include "notation.h"
 #include "position.h"
 #include "psqtab.h"
 #include "rkiss.h"
@@ -89,7 +90,7 @@ CheckInfo::CheckInfo(const Position& pos) {
 /// object do not depend on any external data so we detach state pointer from
 /// the source one.
 
-void Position::operator=(const Position& pos) {
+Position& Position::operator=(const Position& pos) {
 
   memcpy(this, &pos, sizeof(Position));
   startState = *st;
@@ -97,6 +98,8 @@ void Position::operator=(const Position& pos) {
   nodes = 0;
 
   assert(pos_is_ok());
+
+  return *this;
 }
 
 
@@ -187,7 +190,7 @@ void Position::from_fen(const string& fenStr, bool isChess960, Thread* th) {
           for (rsq = relative_square(c, SQ_A1); type_of(piece_on(rsq)) != ROOK; rsq++) {}
 
       else if (token >= 'A' && token <= 'H')
-          rsq = make_square(File(token - 'A'), relative_rank(c, RANK_1));
+          rsq = File(token - 'A') | relative_rank(c, RANK_1);
 
       else
           continue;
@@ -199,7 +202,7 @@ void Position::from_fen(const string& fenStr, bool isChess960, Thread* th) {
   if (   ((fen >> col) && (col >= 'a' && col <= 'h'))
       && ((fen >> row) && (row == '3' || row == '6')))
   {
-      st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
+      st->epSquare = File(col - 'a') | Rank(row - '1');
 
       if (!(attackers_to(st->epSquare) & pieces(sideToMove, PAWN)))
           st->epSquare = SQ_NONE;
@@ -268,7 +271,7 @@ const string Position::to_fen() const {
 
       for (File file = FILE_A; file <= FILE_H; file++)
       {
-          sq = make_square(file, rank);
+          sq = file | rank;
 
           if (is_empty(sq))
               emptyCnt++;
@@ -357,7 +360,7 @@ Bitboard Position::hidden_checkers() const {
 
   while (pinners)
   {
-      b = between_bb(ksq, pop_1st_bit(&pinners)) & pieces();
+      b = between_bb(ksq, pop_lsb(&pinners)) & pieces();
 
       if (b && !more_than_one(b) && (b & pieces(sideToMove)))
           result |= b;
@@ -448,7 +451,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
   // En passant captures are a tricky special case. Because they are rather
   // uncommon, we do it simply by testing whether the king is attacked after
   // the move is made.
-  if (is_enpassant(m))
+  if (type_of(m) == ENPASSANT)
   {
       Color them = ~us;
       Square to = to_sq(m);
@@ -469,7 +472,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
   // square is attacked by the opponent. Castling moves are checked
   // for legality during move generation.
   if (type_of(piece_on(from)) == KING)
-      return is_castle(m) || !(attackers_to(to_sq(m)) & pieces(~us));
+      return type_of(m) == CASTLE || !(attackers_to(to_sq(m)) & pieces(~us));
 
   // 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.
@@ -485,7 +488,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
 
 bool Position::move_is_legal(const Move m) const {
 
-  for (MoveList<MV_LEGAL> ml(*this); !ml.end(); ++ml)
+  for (MoveList<LEGAL> ml(*this); !ml.end(); ++ml)
       if (ml.move() == m)
           return true;
 
@@ -506,7 +509,7 @@ bool Position::is_pseudo_legal(const Move m) const {
   Piece pc = piece_moved(m);
 
   // Use a slower but simpler function for uncommon cases
-  if (is_special(m))
+  if (type_of(m) != NORMAL)
       return move_is_legal(m);
 
   // Is not a promotion, so promotion piece must be empty
@@ -595,7 +598,7 @@ bool Position::is_pseudo_legal(const Move m) const {
       if (type_of(pc) != KING)
       {
           Bitboard b = checkers();
-          Square checksq = pop_1st_bit(&b);
+          Square checksq = pop_lsb(&b);
 
           if (b) // double check ? In this case a king move is required
               return false;
@@ -640,23 +643,23 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
   }
 
   // Can we skip the ugly special cases ?
-  if (!is_special(m))
+  if (type_of(m) == NORMAL)
       return false;
 
   Color us = sideToMove;
   Square ksq = king_square(~us);
 
   // Promotion with check ?
-  if (is_promotion(m))
+  if (type_of(m) == PROMOTION)
       return attacks_from(Piece(promotion_type(m)), to, pieces() ^ from) & ksq;
 
   // En passant capture with check ? We have already handled the case
   // of direct checks and ordinary discovered check, the only case we
   // need to handle is the unusual case of a discovered check through
   // the captured pawn.
-  if (is_enpassant(m))
+  if (type_of(m) == ENPASSANT)
   {
-      Square capsq = make_square(file_of(to), rank_of(from));
+      Square capsq = file_of(to) | rank_of(from);
       Bitboard b = (pieces() ^ from ^ capsq) | to;
 
       return  (attacks_bb<  ROOK>(ksq, b) & pieces(us, QUEEN, ROOK))
@@ -664,7 +667,7 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
   }
 
   // Castling with check ?
-  if (is_castle(m))
+  if (type_of(m) == CASTLE)
   {
       Square kfrom = from;
       Square rfrom = to; // 'King captures the rook' notation
@@ -713,7 +716,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   st->rule50++;
   st->pliesFromNull++;
 
-  if (is_castle(m))
+  if (type_of(m) == CASTLE)
   {
       st->key = k;
       do_castle_move<true>(m);
@@ -726,7 +729,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   Square to = to_sq(m);
   Piece piece = piece_on(from);
   PieceType pt = type_of(piece);
-  PieceType capture = is_enpassant(m) ? PAWN : type_of(piece_on(to));
+  PieceType capture = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to));
 
   assert(color_of(piece) == us);
   assert(color_of(piece_on(to)) != us);
@@ -740,7 +743,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
       // update non-pawn material.
       if (capture == PAWN)
       {
-          if (is_enpassant(m))
+          if (type_of(m) == ENPASSANT)
           {
               capsq += pawn_push(them);
 
@@ -832,7 +835,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
           k ^= zobEp[file_of(st->epSquare)];
       }
 
-      if (is_promotion(m))
+      if (type_of(m) == PROMOTION)
       {
           PieceType promotion = promotion_type(m);
 
@@ -892,7 +895,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
 
   if (moveIsCheck)
   {
-      if (is_special(m))
+      if (type_of(m) != NORMAL)
           st->checkersBB = attackers_to(king_square(them)) & pieces(us);
       else
       {
@@ -927,7 +930,7 @@ void Position::undo_move(Move m) {
 
   sideToMove = ~sideToMove;
 
-  if (is_castle(m))
+  if (type_of(m) == CASTLE)
   {
       do_castle_move<false>(m);
       return;
@@ -945,7 +948,7 @@ void Position::undo_move(Move m) {
   assert(color_of(piece) == us);
   assert(capture != KING);
 
-  if (is_promotion(m))
+  if (type_of(m) == PROMOTION)
   {
       PieceType promotion = promotion_type(m);
 
@@ -988,7 +991,7 @@ void Position::undo_move(Move m) {
   {
       Square capsq = to;
 
-      if (is_enpassant(m))
+      if (type_of(m) == ENPASSANT)
       {
           capsq -= pawn_push(us);
 
@@ -1025,7 +1028,7 @@ template<bool Do>
 void Position::do_castle_move(Move m) {
 
   assert(is_ok(m));
-  assert(is_castle(m));
+  assert(type_of(m) == CASTLE);
 
   Square kto, kfrom, rfrom, rto, kAfter, rAfter;
 
@@ -1188,7 +1191,7 @@ int Position::see(Move m) const {
   // As castle moves are implemented as capturing the rook, they have
   // SEE == RookValueMidgame most of the times (unless the rook is under
   // attack).
-  if (is_castle(m))
+  if (type_of(m) == CASTLE)
       return 0;
 
   from = from_sq(m);
@@ -1197,7 +1200,7 @@ int Position::see(Move m) const {
   occ = pieces();
 
   // Handle en passant moves
-  if (is_enpassant(m))
+  if (type_of(m) == ENPASSANT)
   {
       Square capQq = to - pawn_push(sideToMove);
 
@@ -1321,7 +1324,7 @@ Key Position::compute_key() const {
 
   for (Bitboard b = pieces(); b; )
   {
-      Square s = pop_1st_bit(&b);
+      Square s = pop_lsb(&b);
       k ^= zobrist[color_of(piece_on(s))][type_of(piece_on(s))][s];
   }
 
@@ -1347,7 +1350,7 @@ Key Position::compute_pawn_key() const {
 
   for (Bitboard b = pieces(PAWN); b; )
   {
-      Square s = pop_1st_bit(&b);
+      Square s = pop_lsb(&b);
       k ^= zobrist[color_of(piece_on(s))][PAWN][s];
   }
 
@@ -1384,7 +1387,7 @@ Score Position::compute_psq_score() const {
 
   for (Bitboard b = pieces(); b; )
   {
-      Square s = pop_1st_bit(&b);
+      Square s = pop_lsb(&b);
       score += pieceSquareTable[piece_on(s)][s];
   }
 
@@ -1420,7 +1423,7 @@ bool Position::is_draw() const {
       return true;
 
   // Draw by the 50 moves rule?
-  if (st->rule50 > 99 && (!in_check() || MoveList<MV_LEGAL>(*this).size()))
+  if (st->rule50 > 99 && (!in_check() || MoveList<LEGAL>(*this).size()))
       return true;
 
   // Draw by repetition?
@@ -1475,7 +1478,7 @@ void Position::init() {
       Bitboard b = cr;
       while (b)
       {
-          Key k = zobCastle[1ULL << pop_1st_bit(&b)];
+          Key k = zobCastle[1ULL << pop_lsb(&b)];
           zobCastle[cr] ^= k ? k : rk.rand<Key>();
       }
   }