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