]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Change from [Color][PieceType] to [Piece]
[stockfish] / src / position.cpp
index aa06db08c106ae9f5c1689e2e3b110671f21a25c..eeedbbb22d1fd8d332ed25deb83acdeb07dda9d3 100644 (file)
@@ -36,7 +36,7 @@ using std::string;
 
 namespace Zobrist {
 
-  Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+  Key psq[PIECE_NB][SQUARE_NB];
   Key enpassant[FILE_NB];
   Key castling[CASTLING_RIGHT_NB];
   Key side;
@@ -112,7 +112,7 @@ void Position::init() {
   for (Color c = WHITE; c <= BLACK; ++c)
       for (PieceType pt = PAWN; pt <= KING; ++pt)
           for (Square s = SQ_A1; s <= SQ_H8; ++s)
-              Zobrist::psq[c][pt][s] = rng.rand<Key>();
+              Zobrist::psq[make_piece(c, pt)][s] = rng.rand<Key>();
 
   for (File f = FILE_A; f <= FILE_H; ++f)
       Zobrist::enpassant[f] = rng.rand<Key>();
@@ -178,7 +178,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
 
   std::memset(this, 0, sizeof(Position));
   std::memset(si, 0, sizeof(StateInfo));
-  std::fill_n(&pieceList[0][0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
+  std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
   st = si;
 
   ss >> std::noskipws;
@@ -194,7 +194,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
 
       else if ((idx = PieceToChar.find(token)) != string::npos)
       {
-          put_piece(color_of(Piece(idx)), type_of(Piece(idx)), sq);
+          put_piece(Piece(idx), sq);
           ++sq;
       }
   }
@@ -324,8 +324,8 @@ void Position::set_state(StateInfo* si) const {
   {
       Square s = pop_lsb(&b);
       Piece pc = piece_on(s);
-      si->key ^= Zobrist::psq[color_of(pc)][type_of(pc)][s];
-      si->psq += PSQT::psq[color_of(pc)][type_of(pc)][s];
+      si->key ^= Zobrist::psq[pc][s];
+      si->psq += PSQT::psq[pc][s];
   }
 
   if (si->epSquare != SQ_NONE)
@@ -339,17 +339,17 @@ void Position::set_state(StateInfo* si) const {
   for (Bitboard b = pieces(PAWN); b; )
   {
       Square s = pop_lsb(&b);
-      si->pawnKey ^= Zobrist::psq[color_of(piece_on(s))][PAWN][s];
+      si->pawnKey ^= Zobrist::psq[piece_on(s)][s];
   }
 
   for (Color c = WHITE; c <= BLACK; ++c)
       for (PieceType pt = PAWN; pt <= KING; ++pt)
-          for (int cnt = 0; cnt < pieceCount[c][pt]; ++cnt)
-              si->materialKey ^= Zobrist::psq[c][pt][cnt];
+          for (int cnt = 0; cnt < pieceCount[make_piece(c, pt)]; ++cnt)
+              si->materialKey ^= Zobrist::psq[make_piece(c, pt)][cnt];
 
   for (Color c = WHITE; c <= BLACK; ++c)
       for (PieceType pt = KNIGHT; pt <= QUEEN; ++pt)
-          si->nonPawnMaterial[c] += pieceCount[c][pt] * PieceValue[MG][pt];
+          si->nonPawnMaterial[c] += pieceCount[make_piece(c, pt)] * PieceValue[MG][pt];
 }
 
 
@@ -657,23 +657,24 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
   Color them = ~us;
   Square from = from_sq(m);
   Square to = to_sq(m);
-  PieceType pt = type_of(piece_on(from));
-  PieceType captured = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to));
+  Piece pc = piece_on(from);
+  Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);
 
-  assert(color_of(piece_on(from)) == us);
-  assert(piece_on(to) == NO_PIECE || color_of(piece_on(to)) == (type_of(m) != CASTLING ? them : us));
-  assert(captured != KING);
+  assert(color_of(pc) == us);
+  assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
+  assert(type_of(captured) != KING);
 
   if (type_of(m) == CASTLING)
   {
-      assert(pt == KING);
+      assert(pc == make_piece(us, KING));
+      assert(captured == make_piece(us, ROOK));
 
       Square rfrom, rto;
       do_castling<true>(us, from, to, rfrom, rto);
 
-      captured = NO_PIECE_TYPE;
-      st->psq += PSQT::psq[us][ROOK][rto] - PSQT::psq[us][ROOK][rfrom];
-      k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
+      st->psq += PSQT::psq[captured][rto] - PSQT::psq[captured][rfrom];
+      k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
+      captured = NO_PIECE;
   }
 
   if (captured)
@@ -682,13 +683,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
 
       // If the captured piece is a pawn, update pawn hash key, otherwise
       // update non-pawn material.
-      if (captured == PAWN)
+      if (type_of(captured) == PAWN)
       {
           if (type_of(m) == ENPASSANT)
           {
               capsq -= pawn_push(us);
 
-              assert(pt == PAWN);
+              assert(pc == make_piece(us, PAWN));
               assert(to == st->epSquare);
               assert(relative_rank(us, to) == RANK_6);
               assert(piece_on(to) == NO_PIECE);
@@ -697,28 +698,28 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
               board[capsq] = NO_PIECE; // Not done by remove_piece()
           }
 
-          st->pawnKey ^= Zobrist::psq[them][PAWN][capsq];
+          st->pawnKey ^= Zobrist::psq[captured][capsq];
       }
       else
           st->nonPawnMaterial[them] -= PieceValue[MG][captured];
 
       // Update board and piece lists
-      remove_piece(them, captured, capsq);
+      remove_piece(captured, capsq);
 
       // Update material hash key and prefetch access to materialTable
-      k ^= Zobrist::psq[them][captured][capsq];
-      st->materialKey ^= Zobrist::psq[them][captured][pieceCount[them][captured]];
+      k ^= Zobrist::psq[captured][capsq];
+      st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
       prefetch(thisThread->materialTable[st->materialKey]);
 
       // Update incremental scores
-      st->psq -= PSQT::psq[them][captured][capsq];
+      st->psq -= PSQT::psq[captured][capsq];
 
       // Reset rule 50 counter
       st->rule50 = 0;
   }
 
   // Update hash key
-  k ^= Zobrist::psq[us][pt][from] ^ Zobrist::psq[us][pt][to];
+  k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
 
   // Reset en passant square
   if (st->epSquare != SQ_NONE)
@@ -737,10 +738,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
 
   // Move the piece. The tricky Chess960 castling is handled earlier
   if (type_of(m) != CASTLING)
-      move_piece(us, pt, from, to);
+      move_piece(pc, from, to);
 
   // If the moving piece is a pawn do some special extra work
-  if (pt == PAWN)
+  if (type_of(pc) == PAWN)
   {
       // Set en-passant square if the moved pawn can be captured
       if (   (int(to) ^ int(from)) == 16
@@ -752,29 +753,29 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
 
       else if (type_of(m) == PROMOTION)
       {
-          PieceType promotion = promotion_type(m);
+          Piece promotion = make_piece(us, promotion_type(m));
 
           assert(relative_rank(us, to) == RANK_8);
-          assert(promotion >= KNIGHT && promotion <= QUEEN);
+          assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
 
-          remove_piece(us, PAWN, to);
-          put_piece(us, promotion, to);
+          remove_piece(pc, to);
+          put_piece(promotion, to);
 
           // Update hash keys
-          k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to];
-          st->pawnKey ^= Zobrist::psq[us][PAWN][to];
-          st->materialKey ^=  Zobrist::psq[us][promotion][pieceCount[us][promotion]-1]
-                            ^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
+          k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
+          st->pawnKey ^= Zobrist::psq[pc][to];
+          st->materialKey ^=  Zobrist::psq[promotion][pieceCount[promotion]-1]
+                            ^ Zobrist::psq[pc][pieceCount[pc]];
 
           // Update incremental score
-          st->psq += PSQT::psq[us][promotion][to] - PSQT::psq[us][PAWN][to];
+          st->psq += PSQT::psq[promotion][to] - PSQT::psq[pc][to];
 
           // Update material
           st->nonPawnMaterial[us] += PieceValue[MG][promotion];
       }
 
       // Update pawn hash key and prefetch access to pawnsTable
-      st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to];
+      st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
       prefetch(thisThread->pawnsTable[st->pawnKey]);
 
       // Reset rule 50 draw counter
@@ -782,10 +783,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
   }
 
   // Update incremental scores
-  st->psq += PSQT::psq[us][pt][to] - PSQT::psq[us][pt][from];
+  st->psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];
 
   // Set capture piece
-  st->capturedType = captured;
+  st->capturedPiece = captured;
 
   // Update the key with the final value
   st->key = k;
@@ -814,20 +815,20 @@ void Position::undo_move(Move m) {
   Color us = sideToMove;
   Square from = from_sq(m);
   Square to = to_sq(m);
-  PieceType pt = type_of(piece_on(to));
+  Piece pc = piece_on(to);
 
   assert(empty(from) || type_of(m) == CASTLING);
-  assert(st->capturedType != KING);
+  assert(type_of(st->capturedPiece) != KING);
 
   if (type_of(m) == PROMOTION)
   {
       assert(relative_rank(us, to) == RANK_8);
-      assert(pt == promotion_type(m));
-      assert(pt >= KNIGHT && pt <= QUEEN);
+      assert(type_of(pc) == promotion_type(m));
+      assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);
 
-      remove_piece(us, pt, to);
-      put_piece(us, PAWN, to);
-      pt = PAWN;
+      remove_piece(pc, to);
+      pc = make_piece(us, PAWN);
+      put_piece(pc, to);
   }
 
   if (type_of(m) == CASTLING)
@@ -837,9 +838,9 @@ void Position::undo_move(Move m) {
   }
   else
   {
-      move_piece(us, pt, to, from); // Put the piece back at the source square
+      move_piece(pc, to, from); // Put the piece back at the source square
 
-      if (st->capturedType)
+      if (st->capturedPiece)
       {
           Square capsq = to;
 
@@ -847,14 +848,14 @@ void Position::undo_move(Move m) {
           {
               capsq -= pawn_push(us);
 
-              assert(pt == PAWN);
+              assert(type_of(pc) == PAWN);
               assert(to == st->previous->epSquare);
               assert(relative_rank(us, to) == RANK_6);
               assert(piece_on(capsq) == NO_PIECE);
-              assert(st->capturedType == PAWN);
+              assert(st->capturedPiece == make_piece(~us, PAWN));
           }
 
-          put_piece(~us, st->capturedType, capsq); // Restore the captured piece
+          put_piece(st->capturedPiece, capsq); // Restore the captured piece
       }
   }
 
@@ -867,7 +868,7 @@ void Position::undo_move(Move m) {
 
 
 /// Position::do_castling() is a helper used to do/undo a castling move. This
-/// is a bit tricky, especially in Chess960.
+/// is a bit tricky in Chess960 where from/to squares can overlap.
 template<bool Do>
 void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
 
@@ -877,11 +878,11 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ
   to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
 
   // Remove both pieces first since squares could overlap in Chess960
-  remove_piece(us, KING, Do ? from : to);
-  remove_piece(us, ROOK, Do ? rfrom : rto);
+  remove_piece(make_piece(us, KING), Do ? from : to);
+  remove_piece(make_piece(us, ROOK), Do ? rfrom : rto);
   board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
-  put_piece(us, KING, Do ? to : from);
-  put_piece(us, ROOK, Do ? rto : rfrom);
+  put_piece(make_piece(us, KING), Do ? to : from);
+  put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
 }
 
 
@@ -931,17 +932,16 @@ void Position::undo_null_move() {
 
 Key Position::key_after(Move m) const {
 
-  Color us = sideToMove;
   Square from = from_sq(m);
   Square to = to_sq(m);
-  PieceType pt = type_of(piece_on(from));
-  PieceType captured = type_of(piece_on(to));
+  Piece pc = piece_on(from);
+  Piece captured = piece_on(to);
   Key k = st->key ^ Zobrist::side;
 
   if (captured)
-      k ^= Zobrist::psq[~us][captured][to];
+      k ^= Zobrist::psq[captured][to];
 
-  return k ^ Zobrist::psq[us][pt][to] ^ Zobrist::psq[us][pt][from];
+  return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
 }
 
 
@@ -1139,12 +1139,13 @@ bool Position::pos_is_ok(int* failedStep) const {
           for (Color c = WHITE; c <= BLACK; ++c)
               for (PieceType pt = PAWN; pt <= KING; ++pt)
               {
-                  if (pieceCount[c][pt] != popcount(pieces(c, pt)))
+                  Piece pc = make_piece(c, pt);
+
+                  if (pieceCount[pc] != popcount(pieces(c, pt)))
                       return false;
 
-                  for (int i = 0; i < pieceCount[c][pt];  ++i)
-                      if (   board[pieceList[c][pt][i]] != make_piece(c, pt)
-                          || index[pieceList[c][pt][i]] != i)
+                  for (int i = 0; i < pieceCount[pc]; ++i)
+                      if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
                           return false;
               }