]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Explicitly use delta psqt values when possible
[stockfish] / src / position.cpp
index f4752c5e318c5dc8be0f51898b547b7a032e2505..1179f6f98a8aa61733cb81df7cdecae906c4a042 100644 (file)
@@ -27,6 +27,7 @@
 #include <fstream>
 #include <iostream>
 
+#include "bitcount.h"
 #include "mersenne.h"
 #include "movegen.h"
 #include "movepick.h"
@@ -314,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
 }
 
 
@@ -553,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);
@@ -719,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);
@@ -733,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);
 
@@ -743,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
@@ -770,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;
@@ -791,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;
@@ -918,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;
@@ -933,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];
@@ -977,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);
@@ -1000,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);
@@ -1116,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;
@@ -1147,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);
@@ -1285,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,
@@ -1299,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);
@@ -1592,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);
@@ -1606,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
 }
 
 
@@ -1965,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());