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 | } |