Subversion Repositories Games.Chess Giants

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 pmbaty 1
#include "chess.h"
2
#include "data.h"
3
/* last modified 02/22/14 */
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 move, int side) {
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, and remove the current         *
23
 *  position from the repetition list.                      *
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.                                    *
52
 *                                                          *
53
 ************************************************************
54
 */
55
  switch (piece) {
56
    case pawn:
57
      if (captured == 1) {
58
        if (EnPassant(ply) == to) {
59
          TotalAllPieces++;
60
          Set(to + epsq[side], Pawns(enemy));
61
          Set(to + epsq[side], Occupied(enemy));
62
          PcOnSq(to + epsq[side]) = pieces[enemy][pawn];
63
          Material -= PieceValues(side, pawn);
64
          TotalPieces(enemy, pawn)++;
65
          captured = 0;
66
        }
67
      }
68
      if (promote) {
69
        TotalPieces(side, pawn)++;
70
        Clear(to, Pawns(side));
71
        Clear(to, Occupied(side));
72
        Clear(to, Pieces(side, promote));
73
        Material -= PieceValues(side, promote);
74
        Material += PieceValues(side, pawn);
75
        TotalPieces(side, occupied) -= p_vals[promote];
76
        TotalPieces(side, promote)--;
77
        switch (promote) {
78
          case knight:
79
          case bishop:
80
            TotalMinors(side)--;
81
            break;
82
          case rook:
83
            TotalMajors(side)--;
84
            break;
85
          case queen:
86
            TotalMajors(side) -= 2;
87
            break;
88
        }
89
      }
90
      break;
91
    case knight:
92
    case bishop:
93
    case rook:
94
    case queen:
95
      break;
96
    case king:
97
      KingSQ(side) = from;
98
      if (Abs(to - from) == 2) {
99
        if (to == rook_G[side]) {
100
          from = rook_H[side];
101
          to = rook_F[side];
102
        } else {
103
          from = rook_A[side];
104
          to = rook_D[side];
105
        }
106
        bit_move = SetMask(from) | SetMask(to);
107
        ClearSet(bit_move, Rooks(side));
108
        ClearSet(bit_move, Occupied(side));
109
        PcOnSq(to) = 0;
110
        PcOnSq(from) = pieces[side][rook];
111
      }
112
      break;
113
  }
114
/*
115
 ************************************************************
116
 *                                                          *
117
 *  Next we restore information related to a piece that was *
118
 *  captured and is now being returned to the board.        *
119
 *                                                          *
120
 ************************************************************
121
 */
122
  if (captured) {
123
    TotalAllPieces++;
124
    Set(to, Pieces(enemy, captured));
125
    Set(to, Occupied(enemy));
126
    Material += PieceValues(enemy, captured);
127
    PcOnSq(to) = pieces[enemy][captured];
128
    TotalPieces(enemy, captured)++;
129
    if (captured != pawn)
130
      TotalPieces(enemy, occupied) += p_vals[captured];
131
    switch (captured) {
132
      case pawn:
133
        break;
134
      case knight:
135
      case bishop:
136
        TotalMinors(enemy)++;
137
        break;
138
      case rook:
139
        TotalMajors(enemy)++;
140
        break;
141
      case queen:
142
        TotalMajors(enemy) += 2;
143
        break;
144
      case king:
145
        break;
146
    }
147
  }
148
#if defined(DEBUG)
149
  ValidatePosition(tree, ply, move, "UnmakeMove(1)");
150
#endif
151
  return;
152
}