Subversion Repositories Games.Chess Giants

Rev

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

Rev Author Line No. Line
33 pmbaty 1
#include "chess.h"
2
#include "data.h"
108 pmbaty 3
/* last modified 01/06/16 */
33 pmbaty 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
 */
108 pmbaty 14
void UnmakeMove(TREE * RESTRICT tree, int ply, int side, int move) {
33 pmbaty 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 *
108 pmbaty 22
 *  to this move being made by simply copying the old       *
23
 *  values.                                                 *
33 pmbaty 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      *
108 pmbaty 51
 *  appropriate routine (this only has to deal with pawns   *
52
 *  and king moves that are castling moves.                 *
33 pmbaty 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
}