Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "chess.h"
  2. #include "data.h"
  3. /* last modified 01/06/16 */
  4. /*
  5.  *******************************************************************************
  6.  *                                                                             *
  7.  *   UnmakeMove() is responsible for updating the position database whenever a *
  8.  *   move is retracted.  It is the exact inverse of MakeMove(). The hash       *
  9.  *   signature(s) are not updated, they are just restored to their status that *
  10.  *   was saved before the move was made, to save time.                         *
  11.  *                                                                             *
  12.  *******************************************************************************
  13.  */
  14. void UnmakeMove(TREE * RESTRICT tree, int ply, int side, int move) {
  15.   uint64_t bit_move;
  16.   int piece, from, to, captured, promote, enemy = Flip(side);
  17.  
  18. /*
  19.  ************************************************************
  20.  *                                                          *
  21.  *  First, restore the hash signatures to their state prior *
  22.  *  to this move being made by simply copying the old       *
  23.  *  values.                                                 *
  24.  *                                                          *
  25.  ************************************************************
  26.  */
  27.   HashKey = tree->save_hash_key[ply];
  28.   PawnHashKey = tree->save_pawn_hash_key[ply];
  29. /*
  30.  ************************************************************
  31.  *                                                          *
  32.  *  Now do the things that are common to all pieces, such   *
  33.  *  as updating the bitboards and hash signature.           *
  34.  *                                                          *
  35.  ************************************************************
  36.  */
  37.   piece = Piece(move);
  38.   from = From(move);
  39.   to = To(move);
  40.   captured = Captured(move);
  41.   promote = Promote(move);
  42.   bit_move = SetMask(from) | SetMask(to);
  43.   ClearSet(bit_move, Pieces(side, piece));
  44.   ClearSet(bit_move, Occupied(side));
  45.   PcOnSq(to) = 0;
  46.   PcOnSq(from) = pieces[side][piece];
  47. /*
  48.  ************************************************************
  49.  *                                                          *
  50.  *  Now do the piece-specific things by jumping to the      *
  51.  *  appropriate routine (this only has to deal with pawns   *
  52.  *  and king moves that are castling moves.                 *
  53.  *                                                          *
  54.  ************************************************************
  55.  */
  56.   switch (piece) {
  57.     case pawn:
  58.       if (captured == 1) {
  59.         if (EnPassant(ply) == to) {
  60.           TotalAllPieces++;
  61.           Set(to + epsq[side], Pawns(enemy));
  62.           Set(to + epsq[side], Occupied(enemy));
  63.           PcOnSq(to + epsq[side]) = pieces[enemy][pawn];
  64.           Material -= PieceValues(side, pawn);
  65.           TotalPieces(enemy, pawn)++;
  66.           captured = 0;
  67.         }
  68.       }
  69.       if (promote) {
  70.         TotalPieces(side, pawn)++;
  71.         Clear(to, Pawns(side));
  72.         Clear(to, Occupied(side));
  73.         Clear(to, Pieces(side, promote));
  74.         Material -= PieceValues(side, promote);
  75.         Material += PieceValues(side, pawn);
  76.         TotalPieces(side, occupied) -= p_vals[promote];
  77.         TotalPieces(side, promote)--;
  78.       }
  79.       break;
  80.     case knight:
  81.     case bishop:
  82.     case rook:
  83.     case queen:
  84.       break;
  85.     case king:
  86.       KingSQ(side) = from;
  87.       if (Abs(to - from) == 2) {
  88.         if (to == rook_G[side]) {
  89.           from = rook_H[side];
  90.           to = rook_F[side];
  91.         } else {
  92.           from = rook_A[side];
  93.           to = rook_D[side];
  94.         }
  95.         bit_move = SetMask(from) | SetMask(to);
  96.         ClearSet(bit_move, Rooks(side));
  97.         ClearSet(bit_move, Occupied(side));
  98.         PcOnSq(to) = 0;
  99.         PcOnSq(from) = pieces[side][rook];
  100.       }
  101.       break;
  102.   }
  103. /*
  104.  ************************************************************
  105.  *                                                          *
  106.  *  Next we restore information related to a piece that was *
  107.  *  captured and is now being returned to the board.        *
  108.  *                                                          *
  109.  ************************************************************
  110.  */
  111.   if (captured) {
  112.     TotalAllPieces++;
  113.     Set(to, Pieces(enemy, captured));
  114.     Set(to, Occupied(enemy));
  115.     Material += PieceValues(enemy, captured);
  116.     PcOnSq(to) = pieces[enemy][captured];
  117.     TotalPieces(enemy, captured)++;
  118.     if (captured != pawn)
  119.       TotalPieces(enemy, occupied) += p_vals[captured];
  120.   }
  121. #if defined(DEBUG)
  122.   ValidatePosition(tree, ply, move, "UnmakeMove(1)");
  123. #endif
  124.   return;
  125. }
  126.