3838
3939inline void RememberCaptured (MOVE * move , PIECE captured )
4040{
41+ /*captured piece: bits 20-23; 0 if EMPTY, o en passant capture:*/
4142 * move |= (captured << 20 );
4243}
44+
4345inline void RememberEP (MOVE * move , SQUARE en_passant )
4446{
47+ /*stores board->en_passant in order to undo.*/
4548 * move |= (en_passant << 24 );
4649}
50+
4751inline void RememberCastleRight (MOVE * move , unsigned char rights )
4852{
53+ /*Stores lost castle rights: 'bits promoted' set to 14 if long castle is lost, 1 if short, 15 if both.*/
4954 * move |= (rights << 16 );
5055}
5156
@@ -64,17 +69,7 @@ static void RemovePiece(BOARD *board, SQUARE sq)
6469
6570static void DropPiece (BOARD * board , SQUARE sq , PIECE piece )
6671{
67- PIECE p = board -> squares [sq ];
68- board -> zobrist_key ^= zobkeys .zob_pieces [p ][sq ];
6972 board -> zobrist_key ^= zobkeys .zob_pieces [piece ][sq ];
70-
71- if (p == W_PAWN || p == B_PAWN ){
72- board -> pawn_material [GET_COLOR (p )] -= Value (p );
73- board -> pawns [GET_COLOR (p )] = BitboardUnset (sq , board -> pawns [GET_COLOR (p )]);
74- }else if (p != EMPTY && p != W_KING && p != B_KING ){
75- board -> piece_material [GET_COLOR (p )] -= Value (p );
76- }
77-
7873 if (piece == W_PAWN || piece == B_PAWN ){
7974 board -> pawn_material [GET_COLOR (piece )] += Value (piece );
8075 board -> pawns [GET_COLOR (piece )] = BitboardSet (sq , board -> pawns [GET_COLOR (piece )]);
@@ -84,11 +79,14 @@ static void DropPiece(BOARD *board, SQUARE sq, PIECE piece)
8479 board -> squares [sq ] = piece ;
8580}
8681
87- static inline void MoveWhitePawn (BOARD * board , SQUARE orig , SQUARE dest , PIECE promoted )
82+ static inline void MoveWhitePawn (BOARD * board , SQUARE orig , SQUARE dest , const MOVE * curr_move )
8883{
84+ PIECE promoted = PROMMASK (* curr_move );
85+ /*promoted does NOT store the correct color, because algebraic notation does not ensure Q != q.*/
86+
8987 if (ROW (dest ) == EIGHT_ROW ){ /*Promotion*/
9088 DropPiece (board , dest , TURN_WHITE (promoted ));
91- board -> en_passant = INVALID_SQ ; /*Invalid square: no pawn en passant.*/
89+ board -> en_passant = INVALID_SQ ; /*Invalid square: no pawn en passant.*/
9290 }else {
9391 DropPiece (board , dest , W_PAWN );
9492 if (ROW (dest ) == FOURTH_ROW && ROW (orig ) == SECOND_ROW ){
@@ -102,8 +100,9 @@ static inline void MoveWhitePawn(BOARD *board, SQUARE orig, SQUARE dest, PIECE p
102100 board -> rev_plies [board -> ply ] = 0 ;
103101}
104102
105- static inline void MoveBlackPawn (BOARD * board , SQUARE orig , SQUARE dest , PIECE promoted )
103+ static inline void MoveBlackPawn (BOARD * board , SQUARE orig , SQUARE dest , const MOVE * curr_move )
106104{
105+ PIECE promoted = PROMMASK (* curr_move );
107106 if (ROW (dest ) == FIRST_ROW ){
108107 DropPiece (board , dest , TURN_BLACK (promoted ));
109108 board -> en_passant = INVALID_SQ ;
@@ -134,10 +133,8 @@ static inline void MoveWhiteKing(BOARD *board, SQUARE orig, SQUARE dest, MOVE *c
134133 DropPiece (board , d1 , W_ROOK );
135134 board -> w_castled = 1 ;
136135 }
137-
138136 if (board -> wq_castle ) RememberCastleRight (curr_move , Q_CASTLE_RIGHT );
139137 if (board -> wk_castle ) RememberCastleRight (curr_move , K_CASTLE_RIGHT );
140- /*Stores lost castle rights: 'bits promoted' set to 14 if long castle is lost, 1 if short, 15 if both.*/
141138 }
142139 board -> wk_castle = 0 , board -> wq_castle = 0 ;
143140 board -> en_passant = INVALID_SQ ;
@@ -158,7 +155,6 @@ static inline void MoveBlackKing(BOARD *board, SQUARE orig, SQUARE dest, MOVE *c
158155 DropPiece (board , d8 , B_ROOK );
159156 board -> b_castled = 1 ;
160157 }
161-
162158 if (board -> bq_castle ) RememberCastleRight (curr_move , Q_CASTLE_RIGHT );
163159 if (board -> bk_castle ) RememberCastleRight (curr_move , K_CASTLE_RIGHT );
164160 }
@@ -179,6 +175,7 @@ static inline void MoveWhiteRook(BOARD *board, SQUARE orig, SQUARE dest, MOVE *c
179175 DropPiece (board , dest , W_ROOK );
180176 board -> en_passant = INVALID_SQ ;
181177}
178+
182179static inline void MoveBlackRook (BOARD * board , SQUARE orig , SQUARE dest , MOVE * curr_move )
183180{
184181 if (board -> bq_castle && orig == a8 ) {
@@ -198,29 +195,26 @@ void MakeMove(BOARD *board, MOVE *curr_move)
198195 board -> ply ++ ;
199196 SQUARE orig = ORIGMASK (* curr_move );
200197 SQUARE dest = DESTMASK (* curr_move );
201- PIECE promoted = PROMMASK (* curr_move );
202- /*promoted does NOT store the correct color, because algebraic notation does not ensure Q != q.*/
203198
204- /*stores PAWN_EP in order to undo.*/
205199 RememberEP (curr_move , board -> en_passant );
206200
207- /*don't update 'castle rights' or 'en passant' board->zobrist_key, too expensive?. */
201+ /*don't update 'castle rights' or 'en passant' board->zobrist_key; useless? */
208202 /*if(IN_BOARD(board->en_passant)) board->zobrist_key ^= zobkeys.zob_enpass[board->en_passant];*/
209203
210- /*captured piece: bits 20-23; 0 if EMPTY, o en passant capture:*/
211204 if (board -> squares [dest ]){
212205 RememberCaptured (curr_move , board -> squares [dest ]);
206+ RemovePiece (board , dest );
213207 board -> rev_plies [board -> ply ] = 0 ;
214208 }else {
215209 board -> rev_plies [board -> ply ] = board -> rev_plies [board -> ply - 1 ]+ 1 ;
216210 }
217211
218212 switch (board -> squares [orig ]){
219213 case W_PAWN :
220- MoveWhitePawn (board , orig , dest , promoted );
214+ MoveWhitePawn (board , orig , dest , curr_move );
221215 break ;
222216 case B_PAWN :
223- MoveBlackPawn (board , orig , dest , promoted );
217+ MoveBlackPawn (board , orig , dest , curr_move );
224218 break ;
225219 case W_KING :
226220 MoveWhiteKing (board , orig , dest , curr_move );
@@ -248,6 +242,95 @@ void MakeMove(BOARD *board, MOVE *curr_move)
248242
249243}
250244
245+
246+ /**************************************************************************************
247+ Takebacks.
248+ ***************************************************************************************/
249+
250+ static inline void TakebackWhiteKing (BOARD * board , SQUARE orig , SQUARE dest , PIECE promoted )
251+ {
252+ DropPiece (board , orig , W_KING );
253+ board -> wking_pos = orig ;
254+ if (orig == e1 ){
255+ if (dest == g1 ){ /*short castle.*/
256+ RemovePiece (board , f1 );
257+ DropPiece (board , h1 , W_ROOK );
258+ board -> wk_castle = 1 ;
259+ board -> w_castled = 0 ;
260+ }else if (dest == c1 ){ /*Long castle.*/
261+ RemovePiece (board , d1 );
262+ DropPiece (board , a1 , W_ROOK );
263+ board -> wq_castle = 1 ;
264+ board -> w_castled = 0 ;
265+ }
266+ if (promoted == Q_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
267+ board -> wq_castle = 1 ;
268+ }
269+ if (promoted == K_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
270+ board -> wk_castle = 1 ;
271+ }
272+ }
273+ }
274+
275+ static inline void TakebackBlackKing (BOARD * board , SQUARE orig , SQUARE dest , PIECE promoted )
276+ {
277+ DropPiece (board , orig , B_KING );
278+ board -> bking_pos = orig ;
279+ if (orig == e8 ){
280+ if (dest == g8 ){
281+ RemovePiece (board , f8 );
282+ DropPiece (board , h8 , B_ROOK );
283+ board -> bk_castle = 1 ;
284+ board -> b_castled = 0 ;
285+ }else if (dest == c8 ){
286+ RemovePiece (board , d8 );
287+ DropPiece (board , a8 , B_ROOK );
288+ board -> bq_castle = 1 ;
289+ board -> b_castled = 0 ;
290+ }
291+ if (promoted == Q_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
292+ board -> bq_castle = 1 ;
293+ }
294+ if (promoted == K_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
295+ board -> bk_castle = 1 ;
296+ }
297+ }
298+ }
299+
300+ static inline void TakebackWhiteRook (BOARD * board , SQUARE orig , SQUARE dest , PIECE promoted )
301+ {
302+ if (promoted ){
303+ if (promoted == Q_CASTLE_RIGHT ){
304+ board -> wq_castle = 1 ;
305+ DropPiece (board , orig , W_ROOK );
306+ }else if (promoted == K_CASTLE_RIGHT ){
307+ board -> wk_castle = 1 ;
308+ DropPiece (board , orig , W_ROOK );
309+ }else {
310+ DropPiece (board , orig , W_PAWN );
311+ }
312+ }else {
313+ DropPiece (board , orig , W_ROOK );
314+ }
315+ }
316+
317+ static inline void TakebackBlackRook (BOARD * board , SQUARE orig , SQUARE dest , PIECE promoted )
318+ {
319+ if (promoted ){
320+ if (promoted == Q_CASTLE_RIGHT ){
321+ board -> bq_castle = 1 ;
322+ DropPiece (board , orig , B_ROOK );
323+ }else if (promoted == K_CASTLE_RIGHT ){
324+ board -> bk_castle = 1 ;
325+ DropPiece (board , orig , B_ROOK );
326+ }else {
327+ DropPiece (board , orig , B_PAWN );
328+ }
329+ }else {
330+ DropPiece (board , orig , B_ROOK );
331+ }
332+ }
333+
251334void Takeback (BOARD * board , const MOVE prev_move )
252335{
253336 SQUARE orig = ORIGMASK (prev_move );
@@ -271,88 +354,20 @@ void Takeback(BOARD *board, const MOVE prev_move)
271354 DropPiece (board , orig , B_PAWN );
272355 break ;
273356 case W_KING :
274- DropPiece (board , orig , W_KING );
275- board -> wking_pos = orig ;
276- if (orig == e1 ){
277- if (dest == g1 ){ /*short castle.*/
278- RemovePiece (board , f1 );
279- DropPiece (board , h1 , W_ROOK );
280- board -> wk_castle = 1 ;
281- board -> w_castled = 0 ;
282- }else if (dest == c1 ){ /*Long castle.*/
283- RemovePiece (board , d1 );
284- DropPiece (board , a1 , W_ROOK );
285- board -> wq_castle = 1 ;
286- board -> w_castled = 0 ;
287- }
288- if (promoted == Q_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
289- board -> wq_castle = 1 ;
290- }
291- if (promoted == K_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
292- board -> wk_castle = 1 ;
293- }
294- }
357+ TakebackWhiteKing (board , orig , dest , promoted );
295358 break ;
296-
297359 case B_KING :
298- DropPiece (board , orig , B_KING );
299- board -> bking_pos = orig ;
300- if (orig == e8 ){
301- if (dest == g8 ){
302- RemovePiece (board , f8 );
303- DropPiece (board , h8 , B_ROOK );
304- board -> bk_castle = 1 ;
305- board -> b_castled = 0 ;
306- }else if (dest == c8 ){
307- RemovePiece (board , d8 );
308- DropPiece (board , a8 , B_ROOK );
309- board -> bq_castle = 1 ;
310- board -> b_castled = 0 ;
311- }
312- if (promoted == Q_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
313- board -> bq_castle = 1 ;
314- }
315- if (promoted == K_CASTLE_RIGHT || promoted == BOTH_CASTLES ){
316- board -> bk_castle = 1 ;
317- }
318- }
360+ TakebackBlackKing (board , orig , dest , promoted );
319361 break ;
320362
321363 case W_ROOK :
322- if (promoted ){
323- if (promoted == Q_CASTLE_RIGHT ){
324- board -> wq_castle = 1 ;
325- DropPiece (board , orig , W_ROOK );
326- }else if (promoted == K_CASTLE_RIGHT ){
327- board -> wk_castle = 1 ;
328- DropPiece (board , orig , W_ROOK );
329- }else {
330- DropPiece (board , orig , W_PAWN );
331- }
332- }else {
333- DropPiece (board , orig , W_ROOK );
334- }
364+ TakebackWhiteRook (board , orig , dest , promoted );
335365 break ;
336366
337367 case B_ROOK :
338- if (promoted ){
339- if (promoted == Q_CASTLE_RIGHT ){
340- board -> bq_castle = 1 ;
341- DropPiece (board , orig , B_ROOK );
342- }else if (promoted == K_CASTLE_RIGHT ){
343- board -> bk_castle = 1 ;
344- DropPiece (board , orig , B_ROOK );
345- }else {
346- DropPiece (board , orig , B_PAWN );
347- }
348- }else {
349- DropPiece (board , orig , B_ROOK );
350- }
368+ TakebackBlackRook (board , orig , dest , promoted );
351369 break ;
352- /*
353- case EMPTY:
354- break;
355- */
370+
356371 default :
357372 if (promoted ){
358373 /*drop a PAWN, same color as the piece's on dest.*/
@@ -362,6 +377,7 @@ void Takeback(BOARD *board, const MOVE prev_move)
362377 }
363378 break ;
364379 }
365- DropPiece (board , dest , captured );
380+ RemovePiece (board , dest );
381+ if (captured ) DropPiece (board , dest , captured );
366382 board -> ply -- ;
367383}
0 commit comments