]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Explicitly use delta psqt values when possible
[stockfish] / src / position.cpp
index 6e6bf38b3dda159a5703386f3d7e1fe192d693ab..1179f6f98a8aa61733cb81df7cdecae906c4a042 100644 (file)
@@ -315,9 +315,10 @@ void Position::print(Move m) const {
 
 /// Position::copy() creates a copy of the input position.
 
-void Position::copy(const Position &pos) {
+void Position::copy(const Positionpos) {
 
   memcpy(this, &pos, sizeof(Position));
+  saveState(); // detach and copy state info
 }
 
 
@@ -554,12 +555,12 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const {
           && (direction_between_squares(from, ksq) != direction_between_squares(to, ksq)))
           return true;
 
-      if (move_promotion(m)) // Promotion with check?
+      if (move_is_promotion(m)) // Promotion with check?
       {
           Bitboard b = occupied_squares();
           clear_bit(&b, from);
 
-          switch (move_promotion(m))
+          switch (move_promotion_piece(m))
           {
           case KNIGHT:
               return bit_is_set(piece_attacks<KNIGHT>(to), ksq);
@@ -720,7 +721,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
 
   if (move_is_castle(m))
       do_castle_move(m);
-  else if (move_promotion(m))
+  else if (move_is_promotion(m))
       do_promotion_move(m);
   else if (move_is_ep(m))
       do_ep_move(m);
@@ -734,7 +735,8 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
     assert(color_of_piece_on(from) == us);
     assert(color_of_piece_on(to) == them || piece_on(to) == EMPTY);
 
-    PieceType piece = type_of_piece_on(from);
+    Piece piece = piece_on(from);
+    PieceType pt = type_of_piece(piece);
 
     st->capture = type_of_piece_on(to);
 
@@ -744,23 +746,21 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
     // Move the piece
     Bitboard move_bb = make_move_bb(from, to);
     do_move_bb(&(byColorBB[us]), move_bb);
-    do_move_bb(&(byTypeBB[piece]), move_bb);
+    do_move_bb(&(byTypeBB[pt]), move_bb);
     do_move_bb(&(byTypeBB[0]), move_bb); // HACK: byTypeBB[0] == occupied squares
 
     board[to] = board[from];
     board[from] = EMPTY;
 
     // Update hash key
-    st->key ^= zobrist[us][piece][from] ^ zobrist[us][piece][to];
+    st->key ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];
 
     // Update incremental scores
-    st->mgValue -= pst<MidGame>(us, piece, from);
-    st->mgValue += pst<MidGame>(us, piece, to);
-    st->egValue -= pst<EndGame>(us, piece, from);
-    st->egValue += pst<EndGame>(us, piece, to);
+    st->mgValue += pst_delta<MidGame>(piece, from, to);
+    st->egValue += pst_delta<EndGame>(piece, from, to);
 
     // If the moving piece was a king, update the king square
-    if (piece == KING)
+    if (pt == KING)
         kingSquare[us] = to;
 
     // Reset en passant square
@@ -771,7 +771,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
     }
 
     // If the moving piece was a pawn do some special extra work
-    if (piece == PAWN)
+    if (pt == PAWN)
     {
         // Reset rule 50 draw counter
         st->rule50 = 0;
@@ -792,19 +792,22 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
     }
 
     // Update piece lists
-    pieceList[us][piece][index[from]] = to;
+    pieceList[us][pt][index[from]] = to;
     index[to] = index[from];
 
-    // Update castle rights
-    st->key ^= zobCastle[st->castleRights];
-    st->castleRights &= castleRightsMask[from];
-    st->castleRights &= castleRightsMask[to];
-    st->key ^= zobCastle[st->castleRights];
+    // Update castle rights, try to shortcut a common case
+    if ((castleRightsMask[from] & castleRightsMask[to]) != ALL_CASTLES)
+    {
+        st->key ^= zobCastle[st->castleRights];
+        st->castleRights &= castleRightsMask[from];
+        st->castleRights &= castleRightsMask[to];
+        st->key ^= zobCastle[st->castleRights];
+    }
 
     // Update checkers bitboard, piece must be already moved
     st->checkersBB = EmptyBoardBB;
     Square ksq = king_square(them);
-    switch (piece)
+    switch (pt)
     {
     case PAWN:   update_checkers<PAWN>(&(st->checkersBB), ksq, from, to, dcCandidates);   break;
     case KNIGHT: update_checkers<KNIGHT>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
@@ -919,9 +922,11 @@ void Position::do_castle_move(Move m) {
   set_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares
 
   // Update board array
+  Piece king = piece_of_color_and_type(us, KING);
+  Piece rook = piece_of_color_and_type(us, ROOK);
   board[kfrom] = board[rfrom] = EMPTY;
-  board[kto] = piece_of_color_and_type(us, KING);
-  board[rto] = piece_of_color_and_type(us, ROOK);
+  board[kto] = king;
+  board[rto] = rook;
 
   // Update king square
   kingSquare[us] = kto;
@@ -934,14 +939,10 @@ void Position::do_castle_move(Move m) {
   index[rto] = tmp;
 
   // Update incremental scores
-  st->mgValue -= pst<MidGame>(us, KING, kfrom);
-  st->mgValue += pst<MidGame>(us, KING, kto);
-  st->egValue -= pst<EndGame>(us, KING, kfrom);
-  st->egValue += pst<EndGame>(us, KING, kto);
-  st->mgValue -= pst<MidGame>(us, ROOK, rfrom);
-  st->mgValue += pst<MidGame>(us, ROOK, rto);
-  st->egValue -= pst<EndGame>(us, ROOK, rfrom);
-  st->egValue += pst<EndGame>(us, ROOK, rto);
+  st->mgValue += pst_delta<MidGame>(king, kfrom, kto);
+  st->egValue += pst_delta<EndGame>(king, kfrom, kto);
+  st->mgValue += pst_delta<MidGame>(rook, rfrom, rto);
+  st->egValue += pst_delta<EndGame>(rook, rfrom, rto);
 
   // Update hash key
   st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto];
@@ -978,7 +979,7 @@ void Position::do_promotion_move(Move m) {
 
   assert(is_ok());
   assert(move_is_ok(m));
-  assert(move_promotion(m));
+  assert(move_is_promotion(m));
 
   us = side_to_move();
   them = opposite_color(us);
@@ -1001,7 +1002,7 @@ void Position::do_promotion_move(Move m) {
   board[from] = EMPTY;
 
   // Insert promoted piece
-  promotion = move_promotion(m);
+  promotion = move_promotion_piece(m);
   assert(promotion >= KNIGHT && promotion <= QUEEN);
   set_bit(&(byColorBB[us]), to);
   set_bit(&(byTypeBB[promotion]), to);
@@ -1117,12 +1118,11 @@ void Position::do_ep_move(Move m) {
   st->pawnKey ^= zobrist[them][PAWN][capsq];
 
   // Update incremental scores
+  Piece pawn = piece_of_color_and_type(us, PAWN);
+  st->mgValue += pst_delta<MidGame>(pawn, from, to);
+  st->egValue += pst_delta<EndGame>(pawn, from, to);
   st->mgValue -= pst<MidGame>(them, PAWN, capsq);
-  st->mgValue -= pst<MidGame>(us, PAWN, from);
-  st->mgValue += pst<MidGame>(us, PAWN, to);
   st->egValue -= pst<EndGame>(them, PAWN, capsq);
-  st->egValue -= pst<EndGame>(us, PAWN, from);
-  st->egValue += pst<EndGame>(us, PAWN, to);
 
   // Reset en passant square
   st->epSquare = SQ_NONE;
@@ -1148,7 +1148,7 @@ void Position::undo_move(Move m) {
 
   if (move_is_castle(m))
       undo_castle_move(m);
-  else if (move_promotion(m))
+  else if (move_is_promotion(m))
       undo_promotion_move(m);
   else if (move_is_ep(m))
       undo_ep_move(m);
@@ -1286,7 +1286,7 @@ void Position::undo_promotion_move(Move m) {
   PieceType promotion;
 
   assert(move_is_ok(m));
-  assert(move_promotion(m));
+  assert(move_is_promotion(m));
 
   // When we have arrived here, some work has already been done by
   // Position::undo_move.  In particular, the side to move has been switched,
@@ -1300,7 +1300,7 @@ void Position::undo_promotion_move(Move m) {
   assert(piece_on(from) == EMPTY);
 
   // Remove promoted piece
-  promotion = move_promotion(m);
+  promotion = move_promotion_piece(m);
   assert(piece_on(to)==piece_of_color_and_type(us, promotion));
   assert(promotion >= KNIGHT && promotion <= QUEEN);
   clear_bit(&(byColorBB[us]), to);
@@ -1593,7 +1593,7 @@ int Position::see(Square from, Square to) const {
       if (pt == KING && stmAttackers)
       {
           assert(n < 32);
-          swapList[n++] = 100;
+          swapList[n++] = QueenValueMidgame*10;
           break;
       }
   } while (stmAttackers);
@@ -1607,15 +1607,16 @@ int Position::see(Square from, Square to) const {
 }
 
 
-/// Position::setStartState() copies the content of the argument
+/// Position::saveState() copies the content of the current state
 /// inside startState and makes st point to it. This is needed
 /// when the st pointee could become stale, as example because
 /// the caller is about to going out of scope.
 
-void Position::setStartState(const StateInfo& s) {
+void Position::saveState() {
 
-  startState = s;
+  startState = *st;
   st = &startState;
+  st->previous = NULL; // as a safe guard
 }
 
 
@@ -1966,7 +1967,7 @@ void Position::init_piece_square_tables() {
 /// the white and black sides reversed. This is only useful for debugging,
 /// especially for finding evaluation symmetry bugs.
 
-void Position::flipped_copy(const Position &pos) {
+void Position::flipped_copy(const Positionpos) {
 
   assert(pos.is_ok());
 
@@ -2091,7 +2092,7 @@ bool Position::is_ok(int* failedStep) const {
 
   // Is there more than 2 checkers?
   if (failedStep) (*failedStep)++;
-  if (debugCheckerCount && count_1s<false>(st->checkersBB) > 2)
+  if (debugCheckerCount && count_1s(st->checkersBB) > 2)
       return false;
 
   // Bitboards OK?
@@ -2166,7 +2167,7 @@ bool Position::is_ok(int* failedStep) const {
   if (debugPieceCounts)
       for (Color c = WHITE; c <= BLACK; c++)
           for (PieceType pt = PAWN; pt <= KING; pt++)
-              if (pieceCount[c][pt] != count_1s<false>(pieces_of_color_and_type(c, pt)))
+              if (pieceCount[c][pt] != count_1s(pieces_of_color_and_type(c, pt)))
                   return false;
 
   if (failedStep) (*failedStep)++;