]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Use a 32 bit bitwise 'and' in SimpleHash lookup
[stockfish] / src / position.cpp
index ded3dd172d735ac8a8870305d6b5bddcbab8222e..aac03eb24a328150f71443bdd03ef8f3797e353f 100644 (file)
@@ -101,20 +101,23 @@ namespace {
       operator[]('B') = WB; operator[]('b') = BB;
       operator[]('N') = WN; operator[]('n') = BN;
       operator[]('P') = WP; operator[]('p') = BP;
-      operator[](' ') = PIECE_NONE; operator[]('.') = PIECE_NONE_DARK_SQ;
+      operator[](' ') = PIECE_NONE;
+      operator[]('.') = PIECE_NONE_DARK_SQ;
     }
 
     char from_piece(Piece p) const {
 
-        std::map<char, Piece>::const_iterator it;
-        for (it = begin(); it != end(); ++it)
-            if (it->second == p)
-                return it->first;
+      std::map<char, Piece>::const_iterator it;
+      for (it = begin(); it != end(); ++it)
+          if (it->second == p)
+              return it->first;
 
-        assert(false);
-        return 0;
+      assert(false);
+      return 0;
     }
-  } pieceLetters;
+  };
+
+  PieceLetters pieceLetters;
 }
 
 
@@ -149,9 +152,9 @@ Position::Position(const Position& pos, int th) {
   nodes = 0;
 }
 
-Position::Position(const string& fen, int th) {
+Position::Position(const string& fen, bool isChess960, int th) {
 
-  from_fen(fen);
+  from_fen(fen, isChess960);
   threadID = th;
 }
 
@@ -172,7 +175,7 @@ void Position::detach() {
 /// string. This function is not very robust - make sure that input FENs are
 /// correct (this is assumed to be the responsibility of the GUI).
 
-void Position::from_fen(const string& fen) {
+void Position::from_fen(const string& fen, bool c960) {
 /*
    A FEN string defines a particular position using only the ASCII character set.
 
@@ -202,6 +205,7 @@ void Position::from_fen(const string& fen) {
 */
 
   char token;
+  int hmc, fmn;
   std::istringstream ss(fen);
   Rank rank = RANK_8;
   File file = FILE_A;
@@ -261,7 +265,13 @@ void Position::from_fen(const string& fen) {
           st->epSquare = fenEpSquare;
   }
 
-  // 5-6. Halfmove clock and fullmove number are not parsed
+  // 5. Halfmove clock
+  if (ss >> hmc)
+      st->rule50 = hmc;
+
+  // 6. Fullmove number
+  if (ss >> fmn)
+      startPosPlyCounter = (fmn - 1) * 2 + int(sideToMove == BLACK);
 
   // Various initialisations
   castleRightsMask[make_square(initialKFile,  RANK_1)] ^= WHITE_OO | WHITE_OOO;
@@ -271,10 +281,7 @@ void Position::from_fen(const string& fen) {
   castleRightsMask[make_square(initialQRFile, RANK_1)] ^= WHITE_OOO;
   castleRightsMask[make_square(initialQRFile, RANK_8)] ^= BLACK_OOO;
 
-  isChess960 =   initialKFile  != FILE_E
-              || initialQRFile != FILE_A
-              || initialKRFile != FILE_H;
-
+  isChess960 = c960;
   find_checkers();
 
   st->key = compute_key();
@@ -521,16 +528,24 @@ Bitboard Position::attacks_from(Piece p, Square s) const {
 
   switch (p)
   {
-  case WP:          return attacks_from<PAWN>(s, WHITE);
-  case BP:          return attacks_from<PAWN>(s, BLACK);
-  case WN: case BN: return attacks_from<KNIGHT>(s);
   case WB: case BB: return attacks_from<BISHOP>(s);
   case WR: case BR: return attacks_from<ROOK>(s);
   case WQ: case BQ: return attacks_from<QUEEN>(s);
-  case WK: case BK: return attacks_from<KING>(s);
-  default: break;
+  default: return NonSlidingAttacksBB[p][s];
+  }
+}
+
+Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) {
+
+  assert(square_is_ok(s));
+
+  switch (p)
+  {
+  case WB: case BB: return bishop_attacks_bb(s, occ);
+  case WR: case BR: return rook_attacks_bb(s, occ);
+  case WQ: case BQ: return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ);
+  default: return NonSlidingAttacksBB[p][s];
   }
-  return false;
 }
 
 
@@ -627,9 +642,9 @@ 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)
-          || (direction_between_squares(from, king_square(us)) == direction_between_squares(move_to(m), king_square(us))));
+  return   !pinned
+        || !bit_is_set(pinned, from)
+        ||  squares_aligned(from, move_to(m), king_square(us));
 }
 
 
@@ -687,7 +702,7 @@ bool Position::move_is_check(Move m, const CheckInfo& ci) const {
   {
       // For pawn and king moves we need to verify also direction
       if (  (pt != PAWN && pt != KING)
-          ||(direction_between_squares(from, ci.ksq) != direction_between_squares(to, ci.ksq)))
+          || !squares_aligned(from, to, ci.ksq))
           return true;
   }
 
@@ -758,6 +773,23 @@ bool Position::move_is_check(Move m, const CheckInfo& ci) const {
 }
 
 
+/// Position::do_setup_move() makes a permanent move on the board.
+/// It should be used when setting up a position on board.
+/// You can't undo the move.
+
+void Position::do_setup_move(Move m, StateInfo& newSt) {
+
+  do_move(m, newSt);
+
+  // Reset "game ply" in case we made a non-reversible move.
+  // "game ply" is used for repetition detection.
+  if (st->rule50 == 0)
+      st->gamePly = 0;
+
+  // Update the number of plies played from the starting position
+  startPosPlyCounter++;
+}
+
 /// Position::do_move() makes a move, and saves all information necessary
 /// to a StateInfo object. The move is assumed to be legal.
 /// Pseudo-legal moves should be filtered out before this function is called.
@@ -1525,22 +1557,6 @@ void Position::clear() {
 }
 
 
-/// Position::reset_game_ply() simply sets gamePly to 0. It is used from the
-/// UCI interface code, whenever a non-reversible move is made in a
-/// 'position fen <fen> moves m1 m2 ...' command.  This makes it possible
-/// for the program to handle games of arbitrary length, as long as the GUI
-/// handles draws by the 50 move rule correctly.
-
-void Position::reset_game_ply() {
-
-  st->gamePly = 0;
-}
-
-void Position::inc_startpos_ply_counter() {
-
-  startPosPlyCounter++;
-}
-
 /// Position::put_piece() puts a piece on the given square of the board,
 /// updating the board array, pieces list, bitboards, and piece counts.
 
@@ -1675,7 +1691,7 @@ bool Position::is_draw() const {
       return true;
 
   // Draw by the 50 moves rule?
-  if (st->rule50 > 99 && (st->rule50 > 100 || !is_mate()))
+  if (st->rule50 > 99 && !is_mate())
       return true;
 
   // Draw by repetition?