1 #include "chess.h"
2 #include "data.h"
3 /* modified 12/31/15 */
4 /*
5  *******************************************************************************
6  *                                                                             *
7  *   GenerateCaptures() is used to generate capture and pawn promotion moves   *
8  *   from the current position.                                                *
9  *                                                                             *
10  *   The destination square set is the set of squares occupied by opponent     *
11  *   pieces, plus the set of squares on the 8th rank that pawns can advance to *
12  *   and promote.                                                              *
13  *                                                                             *
14  *******************************************************************************
15  */
GenerateCaptures(TREE * RESTRICT tree,int ply,int side,unsigned * move)16 unsigned *GenerateCaptures(TREE * RESTRICT tree, int ply, int side,
17     unsigned *move) {
18   uint64_t target, piecebd, moves, promotions, pcapturesl, pcapturesr;
19   int from, to, temp, common, enemy = Flip(side);
20 
21 /*
22  ************************************************************
23  *                                                          *
24  *  We produce knight moves by locating the most advanced   *
25  *  knight and then using that <from> square as an index    *
26  *  into the precomputed knight_attacks data.  We repeat    *
27  *  for each knight.                                        *
28  *                                                          *
29  ************************************************************
30  */
31   for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) {
32     from = MostAdvanced(side, piecebd);
33     moves = knight_attacks[from] & Occupied(enemy);
34     temp = from + (knight << 12);
35     Extract(side, move, moves, temp);
36   }
37 /*
38  ************************************************************
39  *                                                          *
40  *  We produce sliding piece moves by locating each piece   *
41  *  type in turn.  We then start with the most advanced     *
42  *  piece and generate moves from that square.  This uses   *
43  *  "magic move generation" to produce the destination      *
44  *  squares.                                                *
45  *                                                          *
46  ************************************************************
47  */
48   for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) {
49     from = MostAdvanced(side, piecebd);
50     moves = BishopAttacks(from, OccupiedSquares) & Occupied(enemy);
51     temp = from + (bishop << 12);
52     Extract(side, move, moves, temp);
53   }
54   for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) {
55     from = MostAdvanced(side, piecebd);
56     moves = RookAttacks(from, OccupiedSquares) & Occupied(enemy);
57     temp = from + (rook << 12);
58     Extract(side, move, moves, temp);
59   }
60   for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) {
61     from = MostAdvanced(side, piecebd);
62     moves = QueenAttacks(from, OccupiedSquares) & Occupied(enemy);
63     temp = from + (queen << 12);
64     Extract(side, move, moves, temp);
65   }
66 /*
67  ************************************************************
68  *                                                          *
69  *  We produce king moves by locating the only king and     *
70  *  then using that <from> square as an index into the      *
71  *  precomputed king_attacks data.                          *
72  *                                                          *
73  ************************************************************
74  */
75   from = KingSQ(side);
76   moves = king_attacks[from] & Occupied(enemy);
77   temp = from + (king << 12);
78   Extract(side, move, moves, temp);
79 /*
80  ************************************************************
81  *                                                          *
82  *  Now, produce pawn moves.  This is done differently due  *
83  *  to inconsistencies in the way a pawn moves when it      *
84  *  captures as opposed to normal non-capturing moves.      *
85  *  Another exception is capturing enpassant.  The first    *
86  *  step is to generate all possible pawn promotions.  We   *
87  *  do this by removing all pawns but those on the 7th rank *
88  *  and then advancing them if the square in front is empty.*
89  *                                                          *
90  ************************************************************
91  */
92   promotions = Pawns(side) & rank_mask[rank7[side]];
93   promotions =
94       ((side) ? promotions << 8 : promotions >> 8) & ~OccupiedSquares;
95   for (; promotions; Clear(to, promotions)) {
96     to = LSB(promotions);
97     *move++ =
98         (to + pawnadv1[side]) | (to << 6) | (pawn << 12) | (queen << 18);
99   }
100   target = Occupied(enemy) | EnPassantTarget(ply);
101   pcapturesl =
102       ((side) ? (Pawns(white) & mask_left_edge) << 7 : (Pawns(black) &
103           mask_left_edge) >> 9) & target;
104   for (; pcapturesl; Clear(to, pcapturesl)) {
105     to = MostAdvanced(side, pcapturesl);
106     common = (to + capleft[side]) | (to << 6) | (pawn << 12);
107     if ((side) ? to < 56 : to > 7)
108       *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15);
109     else
110       *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18;
111   }
112   pcapturesr =
113       ((side) ? (Pawns(white) & mask_right_edge) << 9 : (Pawns(black) &
114           mask_right_edge) >> 7) & target;
115   for (; pcapturesr; Clear(to, pcapturesr)) {
116     to = MostAdvanced(side, pcapturesr);
117     common = (to + capright[side]) | (to << 6) | (pawn << 12);
118     if ((side) ? to < 56 : to > 7)
119       *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15);
120     else
121       *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18;
122   }
123   return move;
124 }
125 
126 /* modified 12/31/15 */
127 /*
128  *******************************************************************************
129  *                                                                             *
130  *   GenerateChecks() is used to generate non-capture moves from the current   *
131  *   position.                                                                 *
132  *                                                                             *
133  *   The first pass produces a bitmap that contains the squares a particular   *
134  *   piece type would attack if sitting on the square the enemy king sits on.  *
135  *   We then use each of these squares as a source and check to see if the     *
136  *   same piece type attacks one of these common targets.  If so, we can move  *
137  *   that piece to that square and it will directly attack the king.  We do    *
138  *   this for pawns, knights, bishops, rooks and queens to produce the set of  *
139  *   "direct checking moves."                                                  *
140  *                                                                             *
141  *   Then we generate discovered checks in two passes, once for diagonal       *
142  *   attacks and once for rank/file attacks (we do it in two passes since a    *
143  *   rook can't produce a discovered check along a rank or file since it moves *
144  *   in that direction as well.  For diagonals, we first generate the bishop   *
145  *   attacks from the enemy king square and mask them with the friendly piece  *
146  *   occupied squares bitmap.  This gives us a set of up to 4 "blocking        *
147  *   pieces" that could be preventing a check.  We then remove them via the    *
148  *   "magic move generation" tricks, and see if we now reach friendly bishops  *
149  *   or queens on those diagonals.  If we have a friendly blocker, and a       *
150  *   friendly diagonal mover behind that blocker, then moving the blocker is   *
151  *   a discovered check (and there could be double-checks included but we do   *
152  *   not check for that since a single check is good enough).  We repeat this  *
153  *   for the ranks/files and we are done.                                      *
154  *                                                                             *
155  *   For the present, this code does not produce discovered checks by the      *
156  *   king since all king moves are not discovered checks because the king can  *
157  *   move in the same direction as the piece it blocks and not uncover the     *
158  *   attack.  This might be fixed at some point, but it is rare enough to not  *
159  *   be an issue except in far endgames.                                       *
160  *                                                                             *
161  *******************************************************************************
162  */
GenerateChecks(TREE * RESTRICT tree,int side,unsigned * move)163 unsigned *GenerateChecks(TREE * RESTRICT tree, int side, unsigned *move) {
164   uint64_t temp_target, target, piecebd, moves;
165   uint64_t padvances1, blockers, checkers;
166   int from, to, promote, temp, enemy = Flip(side);
167 
168 /*
169  ************************************************************
170  *                                                          *
171  *  First pass:  produce direct checks.  For each piece     *
172  *  type, we pretend that a piece of that type stands on    *
173  *  the square of the king and we generate attacks from     *
174  *  that square for that piece.  Now, if we can find any    *
175  *  piece of that type that attacks one of those squares,   *
176  *  then that piece move would deliver a direct check to    *
177  *  the enemy king.  Easy, wasn't it?                       *
178  *                                                          *
179  ************************************************************
180  */
181   target = ~OccupiedSquares;
182 /*
183  ************************************************************
184  *                                                          *
185  *  Knight direct checks.                                   *
186  *                                                          *
187  ************************************************************
188  */
189   temp_target = target & knight_attacks[KingSQ(enemy)];
190   for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) {
191     from = MostAdvanced(side, piecebd);
192     moves = knight_attacks[from] & temp_target;
193     temp = from + (knight << 12);
194     Extract(side, move, moves, temp);
195   }
196 /*
197  ************************************************************
198  *                                                          *
199  *  Sliding piece direct checks.                            *
200  *                                                          *
201  ************************************************************
202  */
203   temp_target = target & BishopAttacks(KingSQ(enemy), OccupiedSquares);
204   for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) {
205     from = MostAdvanced(side, piecebd);
206     moves = BishopAttacks(from, OccupiedSquares) & temp_target;
207     temp = from + (bishop << 12);
208     Extract(side, move, moves, temp);
209   }
210   temp_target = target & RookAttacks(KingSQ(enemy), OccupiedSquares);
211   for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) {
212     from = MostAdvanced(side, piecebd);
213     moves = RookAttacks(from, OccupiedSquares) & temp_target;
214     temp = from + (rook << 12);
215     Extract(side, move, moves, temp);
216   }
217   temp_target = target & QueenAttacks(KingSQ(enemy), OccupiedSquares);
218   for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) {
219     from = MostAdvanced(side, piecebd);
220     moves = QueenAttacks(from, OccupiedSquares) & temp_target;
221     temp = from + (queen << 12);
222     Extract(side, move, moves, temp);
223   }
224 /*
225  ************************************************************
226  *                                                          *
227  *   Pawn direct checks.                                    *
228  *                                                          *
229  ************************************************************
230  */
231   temp_target = target & pawn_attacks[enemy][KingSQ(enemy)];
232   padvances1 = ((side) ? Pawns(white) << 8 : Pawns(black) >> 8) & temp_target;
233   for (; padvances1; Clear(to, padvances1)) {
234     to = MostAdvanced(side, padvances1);
235     *move++ = (to + pawnadv1[side]) | (to << 6) | (pawn << 12);
236   }
237 /*
238  ************************************************************
239  *                                                          *
240  *  Second pass:  produce discovered checks.  Here we do    *
241  *  things a bit differently.  We first take diagonal       *
242  *  movers.  From the enemy king's position, we generate    *
243  *  diagonal moves to see if any of them end at one of our  *
244  *  pieces that does not slide diagonally, such as a rook,  *
245  *  knight or pawn.  If we find one, we look further down   *
246  *  that diagonal to see if we now find a diagonal moves    *
247  *  (queen or bishop).  If so, any legal move by the        *
248  *  blocking piece (except captures which have already been *
249  *  generated) will be a discovered check that needs to be  *
250  *  searched.  We do the same for vertical / horizontal     *
251  *  rays that are blocked by bishops, knights or pawns that *
252  *  would hide a discovered check by a rook or queen.       *
253  *                                                          *
254  *  First we look for diagonal discovered attacks.  Once we *
255  *  know which squares hold pieces that create a discovered *
256  *  check when they move, we generate those piece moves     *
257  *  piece type by piece type.                               *
258  *                                                          *
259  ************************************************************
260  */
261   blockers =
262       BishopAttacks(KingSQ(enemy),
263       OccupiedSquares) & (Rooks(side) | Knights(side) | Pawns(side));
264   if (blockers) {
265     checkers =
266         BishopAttacks(KingSQ(enemy),
267         OccupiedSquares & ~blockers) & (Bishops(side) | Queens(side));
268     if (checkers) {
269       if (plus7dir[KingSQ(enemy)] & blockers &&
270           !(plus7dir[KingSQ(enemy)] & checkers))
271         blockers &= ~plus7dir[KingSQ(enemy)];
272       if (plus9dir[KingSQ(enemy)] & blockers &&
273           !(plus9dir[KingSQ(enemy)] & checkers))
274         blockers &= ~plus9dir[KingSQ(enemy)];
275       if (minus7dir[KingSQ(enemy)] & blockers &&
276           !(minus7dir[KingSQ(enemy)] & checkers))
277         blockers &= ~minus7dir[KingSQ(enemy)];
278       if (minus9dir[KingSQ(enemy)] & blockers &&
279           !(minus9dir[KingSQ(enemy)] & checkers))
280         blockers &= ~minus9dir[KingSQ(enemy)];
281       target = ~OccupiedSquares;
282 /*
283  ************************************************************
284  *                                                          *
285  *  Knight discovered checks.                               *
286  *                                                          *
287  ************************************************************
288  */
289       temp_target = target & ~knight_attacks[KingSQ(enemy)];
290       for (piecebd = Knights(side) & blockers; piecebd; Clear(from, piecebd)) {
291         from = MostAdvanced(side, piecebd);
292         moves = knight_attacks[from] & temp_target;
293         temp = from + (knight << 12);
294         Extract(side, move, moves, temp);
295       }
296 /*
297  ************************************************************
298  *                                                          *
299  *  Rook discovered checks.                                 *
300  *                                                          *
301  ************************************************************
302  */
303       target = ~OccupiedSquares;
304       temp_target = target & ~RookAttacks(KingSQ(enemy), OccupiedSquares);
305       for (piecebd = Rooks(side) & blockers; piecebd; Clear(from, piecebd)) {
306         from = MostAdvanced(side, piecebd);
307         moves = RookAttacks(from, OccupiedSquares) & temp_target;
308         temp = from + (rook << 12);
309         Extract(side, move, moves, temp);
310       }
311 /*
312  ************************************************************
313  *                                                          *
314  *  Pawn discovered checks.                                 *
315  *                                                          *
316  ************************************************************
317  */
318       piecebd =
319           Pawns(side) & blockers & ((side) ? ~OccupiedSquares >> 8 :
320           ~OccupiedSquares << 8);
321       for (; piecebd; Clear(from, piecebd)) {
322         from = MostAdvanced(side, piecebd);
323         to = from + pawnadv1[enemy];
324         if ((side) ? to > 55 : to < 8)
325           promote = queen;
326         else
327           promote = 0;
328         *move++ = from | (to << 6) | (pawn << 12) | (promote << 18);
329       }
330     }
331   }
332 /*
333  ************************************************************
334  *                                                          *
335  *  Next, we look for rank/file discovered attacks.  Once   *
336  *  we know which squares hold pieces that create a         *
337  *  discovered check when they move, we generate them       *
338  *  piece type by piece type.                               *
339  *                                                          *
340  ************************************************************
341  */
342   blockers =
343       RookAttacks(KingSQ(enemy),
344       OccupiedSquares) & (Bishops(side) | Knights(side) | (Pawns(side) &
345           rank_mask[Rank(KingSQ(enemy))]));
346   if (blockers) {
347     checkers =
348         RookAttacks(KingSQ(enemy),
349         OccupiedSquares & ~blockers) & (Rooks(side) | Queens(side));
350     if (checkers) {
351       if (plus1dir[KingSQ(enemy)] & blockers &&
352           !(plus1dir[KingSQ(enemy)] & checkers))
353         blockers &= ~plus1dir[KingSQ(enemy)];
354       if (plus8dir[KingSQ(enemy)] & blockers &&
355           !(plus8dir[KingSQ(enemy)] & checkers))
356         blockers &= ~plus8dir[KingSQ(enemy)];
357       if (minus1dir[KingSQ(enemy)] & blockers &&
358           !(minus1dir[KingSQ(enemy)] & checkers))
359         blockers &= ~minus1dir[KingSQ(enemy)];
360       if (minus8dir[KingSQ(enemy)] & blockers &&
361           !(minus8dir[KingSQ(enemy)] & checkers))
362         blockers &= ~minus8dir[KingSQ(enemy)];
363       target = ~OccupiedSquares;
364 /*
365  ************************************************************
366  *                                                          *
367  *  Knight discovered checks.                               *
368  *                                                          *
369  ************************************************************
370  */
371       temp_target = target & ~knight_attacks[KingSQ(enemy)];
372       for (piecebd = Knights(side) & blockers; piecebd; Clear(from, piecebd)) {
373         from = MostAdvanced(side, piecebd);
374         moves = knight_attacks[from] & temp_target;
375         temp = from + (knight << 12);
376         Extract(side, move, moves, temp);
377       }
378 /*
379  ************************************************************
380  *                                                          *
381  *  Bishop discovered checks.                               *
382  *                                                          *
383  ************************************************************
384  */
385       target = ~OccupiedSquares;
386       temp_target = target & ~BishopAttacks(KingSQ(enemy), OccupiedSquares);
387       for (piecebd = Bishops(side) & blockers; piecebd; Clear(from, piecebd)) {
388         from = MostAdvanced(side, piecebd);
389         moves = BishopAttacks(from, OccupiedSquares) & temp_target;
390         temp = from + (bishop << 12);
391         Extract(side, move, moves, temp);
392       }
393 /*
394  ************************************************************
395  *                                                          *
396  *  Pawn discovered checks.                                 *
397  *                                                          *
398  ************************************************************
399  */
400       piecebd =
401           Pawns(side) & blockers & ((side) ? ~OccupiedSquares >> 8 :
402           ~OccupiedSquares << 8);
403       for (; piecebd; Clear(from, piecebd)) {
404         from = MostAdvanced(side, piecebd);
405         to = from + pawnadv1[enemy];
406         if ((side) ? to > 55 : to < 8)
407           promote = queen;
408         else
409           promote = 0;
410         *move++ = from | (to << 6) | (pawn << 12) | (promote << 18);
411       }
412     }
413   }
414   return move;
415 }
416 
417 /* modified 12/31/15 */
418 /*
419  *******************************************************************************
420  *                                                                             *
421  *   GenerateCheckEvasions() is used to generate moves when the king is in     *
422  *   check.                                                                    *
423  *                                                                             *
424  *   Three types of check-evasion moves are generated:                         *
425  *                                                                             *
426  *   (1) Generate king moves to squares that are not attacked by the           *
427  *   opponent's pieces.  This includes capture and non-capture moves.          *
428  *                                                                             *
429  *   (2) Generate interpositions along the rank/file that the checking attack  *
430  *   is coming along (assuming (a) only one piece is checking the king, and    *
431  *   (b) the checking piece is a sliding piece [bishop, rook, queen]).         *
432  *                                                                             *
433  *   (3) Generate capture moves, but only to the square(s) that are giving     *
434  *   check.  Captures are a special case.  If there is one checking piece,     *
435  *   then capturing it by any piece is tried.  If there are two pieces         *
436  *   checking the king, then the only legal capture to try is for the king to  *
437  *   capture one of the checking pieces that is on an unattacked square.       *
438  *                                                                             *
439  *******************************************************************************
440  */
GenerateCheckEvasions(TREE * RESTRICT tree,int ply,int side,unsigned * move)441 unsigned *GenerateCheckEvasions(TREE * RESTRICT tree, int ply, int side,
442     unsigned *move) {
443   uint64_t target, targetc, targetp, piecebd, moves, empty, checksqs;
444   uint64_t padvances1, padvances2, pcapturesl, pcapturesr, padvances1_all;
445   int from, to, temp, common, enemy = Flip(side), king_square, checkers;
446   int checking_square, check_direction1 = 0, check_direction2 = 0;
447 
448 /*
449  ************************************************************
450  *                                                          *
451  *  First, determine how many pieces are attacking the king *
452  *  and where they are, so we can figure out how to legally *
453  *  get out of check.                                       *
454  *                                                          *
455  ************************************************************
456  */
457   king_square = KingSQ(side);
458   checksqs = AttacksTo(tree, king_square) & Occupied(enemy);
459   checkers = PopCnt(checksqs);
460   if (checkers == 1) {
461     checking_square = LSB(checksqs);
462     if (PcOnSq(checking_square) != pieces[enemy][pawn])
463       check_direction1 = directions[checking_square][king_square];
464     target = InterposeSquares(king_square, checking_square);
465     target |= checksqs;
466     target |= Kings(enemy);
467   } else {
468     target = Kings(enemy);
469     checking_square = LSB(checksqs);
470     if (PcOnSq(checking_square) != pieces[enemy][pawn])
471       check_direction1 = directions[checking_square][king_square];
472     checking_square = MSB(checksqs);
473     if (PcOnSq(checking_square) != pieces[enemy][pawn])
474       check_direction2 = directions[checking_square][king_square];
475   }
476 /*
477  ************************************************************
478  *                                                          *
479  *  The next step is to produce the set of valid            *
480  *  destination squares.  For king moves, this is simply    *
481  *  the set of squares that are not attacked by enemy       *
482  *  pieces (if there are any such squares.)                 *
483  *                                                          *
484  *  Then, if the checking piece is not a knight, we need    *
485  *  to know the checking direction so that we can either    *
486  *  move the king off of that ray, or else block that ray.  *
487  *                                                          *
488  *  We produce king moves by locating the only king and     *
489  *  then using that <from> square as an index into the      *
490  *  precomputed king_attacks data.                          *
491  *                                                          *
492  ************************************************************
493  */
494   from = king_square;
495   temp = from + (king << 12);
496   for (moves = king_attacks[from] & ~Occupied(side); moves; Clear(to, moves)) {
497     to = MostAdvanced(side, moves);
498     if (!Attacks(tree, enemy, to)
499         && directions[from][to] != check_direction1 &&
500         directions[from][to] != check_direction2)
501       *move++ = temp | (to << 6) | (Abs(PcOnSq(to)) << 15);
502   }
503 /*
504  ************************************************************
505  *                                                          *
506  *  We produce knight moves by locating the most advanced   *
507  *  knight and then using that <from> square as an index    *
508  *  into the precomputed knight_attacks data.  We repeat    *
509  *  for each knight.                                        *
510  *                                                          *
511  ************************************************************
512  */
513   if (checkers == 1) {
514     for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) {
515       from = MostAdvanced(side, piecebd);
516       if (!PinnedOnKing(tree, side, from)) {
517         moves = knight_attacks[from] & target;
518         temp = from + (knight << 12);
519         Extract(side, move, moves, temp);
520       }
521     }
522 /*
523  ************************************************************
524  *                                                          *
525  *  We produce sliding piece moves by locating each piece   *
526  *  type in turn.  We then start with the most advanced     *
527  *  piece and generate moves from that square.  This uses   *
528  *  "magic move generation" to produce the destination      *
529  *  squares.                                                *
530  *                                                          *
531  ************************************************************
532  */
533     for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) {
534       from = MostAdvanced(side, piecebd);
535       if (!PinnedOnKing(tree, side, from)) {
536         moves = BishopAttacks(from, OccupiedSquares) & target;
537         temp = from + (bishop << 12);
538         Extract(side, move, moves, temp);
539       }
540     }
541     for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) {
542       from = MostAdvanced(side, piecebd);
543       if (!PinnedOnKing(tree, side, from)) {
544         moves = RookAttacks(from, OccupiedSquares) & target;
545         temp = from + (rook << 12);
546         Extract(side, move, moves, temp);
547       }
548     }
549     for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) {
550       from = MostAdvanced(side, piecebd);
551       if (!PinnedOnKing(tree, side, from)) {
552         moves = QueenAttacks(from, OccupiedSquares) & target;
553         temp = from + (queen << 12);
554         Extract(side, move, moves, temp);
555       }
556     }
557 /*
558  ************************************************************
559  *                                                          *
560  *  Now, produce pawn moves.  This is done differently due  *
561  *  to inconsistencies in the way a pawn moves when it      *
562  *  captures as opposed to normal non-capturing moves.      *
563  *  Another exception is capturing enpassant.  The first    *
564  *  step is to generate all possible pawn moves.  We do     *
565  *  this in 2 operations:  (1) shift the pawns forward one  *
566  *  rank then AND with empty squares;  (2) shift the pawns  *
567  *  forward two ranks and then AND with empty squares.      *
568  *                                                          *
569  ************************************************************
570  */
571     empty = ~OccupiedSquares;
572     targetp = target & empty;
573     if (side) {
574       padvances1 = Pawns(white) << 8 & targetp;
575       padvances1_all = Pawns(white) << 8 & empty;
576       padvances2 = ((padvances1_all & ((uint64_t) 255 << 16)) << 8) & targetp;
577     } else {
578       padvances1 = Pawns(black) >> 8 & targetp;
579       padvances1_all = Pawns(black) >> 8 & empty;
580       padvances2 = ((padvances1_all & ((uint64_t) 255 << 40)) >> 8) & targetp;
581     }
582 /*
583  ************************************************************
584  *                                                          *
585  *  Now that we got 'em, we simply enumerate the to squares *
586  *  as before, but in four steps since we have four sets of *
587  *  potential moves.                                        *
588  *                                                          *
589  ************************************************************
590  */
591     for (; padvances2; Clear(to, padvances2)) {
592       to = MostAdvanced(side, padvances2);
593       if (!PinnedOnKing(tree, side, to + pawnadv2[side]))
594         *move++ = (to + pawnadv2[side]) | (to << 6) | (pawn << 12);
595     }
596     for (; padvances1; Clear(to, padvances1)) {
597       to = MostAdvanced(side, padvances1);
598       if (!PinnedOnKing(tree, side, to + pawnadv1[side])) {
599         common = (to + pawnadv1[side]) | (to << 6) | (pawn << 12);
600         if ((side) ? to < 56 : to > 7)
601           *move++ = common;
602         else {
603           *move++ = common | (queen << 18);
604           *move++ = common | (knight << 18);
605         }
606       }
607     }
608 /*
609  ************************************************************
610  *                                                          *
611  *  And then we try to see if the checking piece can be     *
612  *  captured by a friendly pawn.                            *
613  *                                                          *
614  ************************************************************
615  */
616     targetc = Occupied(enemy) | EnPassantTarget(ply);
617     targetc = targetc & target;
618     if (Pawns(enemy) & target & ((side) ? EnPassantTarget(ply) >> 8 :
619             EnPassantTarget(ply) << 8))
620       targetc = targetc | EnPassantTarget(ply);
621     if (side) {
622       pcapturesl = (Pawns(white) & mask_left_edge) << 7 & targetc;
623       pcapturesr = (Pawns(white) & mask_right_edge) << 9 & targetc;
624     } else {
625       pcapturesl = (Pawns(black) & mask_left_edge) >> 9 & targetc;
626       pcapturesr = (Pawns(black) & mask_right_edge) >> 7 & targetc;
627     }
628     for (; pcapturesl; Clear(to, pcapturesl)) {
629       to = MostAdvanced(side, pcapturesl);
630       if (!PinnedOnKing(tree, side, to + capleft[side])) {
631         common = (to + capleft[side]) | (to << 6) | (pawn << 12);
632         if ((side) ? to < 56 : to > 7)
633           *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15);
634         else {
635           *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18;
636           *move++ = common | Abs(PcOnSq(to)) << 15 | knight << 18;
637         }
638       }
639     }
640     for (; pcapturesr; Clear(to, pcapturesr)) {
641       to = MostAdvanced(side, pcapturesr);
642       if (!PinnedOnKing(tree, side, to + capright[side])) {
643         common = (to + capright[side]) | (to << 6) | (pawn << 12);
644         if ((side) ? to < 56 : to > 7)
645           *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15);
646         else {
647           *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18;
648           *move++ = common | Abs(PcOnSq(to)) << 15 | knight << 18;
649         }
650       }
651     }
652   }
653   return move;
654 }
655 
656 /* modified 12/31/15 */
657 /*
658  *******************************************************************************
659  *                                                                             *
660  *   GenerateNoncaptures() is used to generate non-capture moves from the      *
661  *   current position.                                                         *
662  *                                                                             *
663  *   Once the valid destination squares are known, we have to locate a         *
664  *   friendly piece to compute the squares it attacks.                         *
665  *                                                                             *
666  *   Pawns are handled differently.  Regular pawn moves are produced by        *
667  *   shifting the pawn bitmap 8 bits "forward" and anding this with the        *
668  *   complement of the occupied squares bitmap double advances are then        *
669  *   produced by anding the pawn bitmap with a mask containing 1's on the      *
670  *   second rank, shifting this 16 bits "forward" and then anding this with    *
671  *   the complement of the occupied squares bitmap as before.  If [to] reaches *
672  *   the 8th rank, we produce a set of three moves, promoting the pawn to      *
673  *   knight, bishop and rook (queen promotions were generated earlier by       *
674  *   GenerateCaptures()).                                                      *
675  *                                                                             *
676  *******************************************************************************
677  */
GenerateNoncaptures(TREE * RESTRICT tree,int ply,int side,unsigned * move)678 unsigned *GenerateNoncaptures(TREE * RESTRICT tree, int ply, int side,
679     unsigned *move) {
680   uint64_t target, piecebd, moves;
681   uint64_t padvances1, padvances2, pcapturesl, pcapturesr;
682   int from, to, temp, common, enemy = Flip(side);
683 
684 /*
685  ************************************************************
686  *                                                          *
687  *  First, produce castling moves when they are legal.      *
688  *                                                          *
689  ************************************************************
690  */
691   if (Castle(ply, side) > 0) {
692     if (Castle(ply, side) & 1 && !(OccupiedSquares & OO[side])
693         && !Attacks(tree, enemy, OOsqs[side][0])
694         && !Attacks(tree, enemy, OOsqs[side][1])
695         && !Attacks(tree, enemy, OOsqs[side][2])) {
696       *move++ = (king << 12) + (OOto[side] << 6) + OOfrom[side];
697     }
698     if (Castle(ply, side) & 2 && !(OccupiedSquares & OOO[side])
699         && !Attacks(tree, enemy, OOOsqs[side][0])
700         && !Attacks(tree, enemy, OOOsqs[side][1])
701         && !Attacks(tree, enemy, OOOsqs[side][2])) {
702       *move++ = (king << 12) + (OOOto[side] << 6) + OOfrom[side];
703     }
704   }
705   target = ~OccupiedSquares;
706 /*
707  ************************************************************
708  *                                                          *
709  *  We produce knight moves by locating the most advanced   *
710  *  knight and then using that <from> square as an index    *
711  *  into the precomputed knight_attacks data.  We repeat    *
712  *  for each knight.                                        *
713  *                                                          *
714  ************************************************************
715  */
716   for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) {
717     from = MostAdvanced(side, piecebd);
718     moves = knight_attacks[from] & target;
719     temp = from + (knight << 12);
720     Extract(side, move, moves, temp);
721   }
722 /*
723  ************************************************************
724  *                                                          *
725  *  We produce sliding piece moves by locating each piece   *
726  *  type in turn.  We then start with the most advanced     *
727  *  piece and generate moves from that square.  This uses   *
728  *  "magic move generation" to produce the destination      *
729  *  squares.                                                *
730  *                                                          *
731  ************************************************************
732  */
733   for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) {
734     from = MostAdvanced(side, piecebd);
735     moves = BishopAttacks(from, OccupiedSquares) & target;
736     temp = from + (bishop << 12);
737     Extract(side, move, moves, temp);
738   }
739   for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) {
740     from = MostAdvanced(side, piecebd);
741     moves = RookAttacks(from, OccupiedSquares) & target;
742     temp = from + (rook << 12);
743     Extract(side, move, moves, temp);
744   }
745   for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) {
746     from = MostAdvanced(side, piecebd);
747     moves = QueenAttacks(from, OccupiedSquares) & target;
748     temp = from + (queen << 12);
749     Extract(side, move, moves, temp);
750   }
751 /*
752  ************************************************************
753  *                                                          *
754  *  We produce king moves by locating the only king and     *
755  *  then using that <from> square as an index into the      *
756  *  precomputed king_attacks data.                          *
757  *                                                          *
758  ************************************************************
759  */
760   from = KingSQ(side);
761   moves = king_attacks[from] & target;
762   temp = from + (king << 12);
763   Extract(side, move, moves, temp);
764 /*
765  ************************************************************
766  *                                                          *
767  *  Now, produce pawn moves.  This is done differently due  *
768  *  to inconsistencies in the way a pawn moves when it      *
769  *  captures as opposed to normal non-capturing moves.      *
770  *  First we generate all possible pawn moves.  We do this  *
771  *  in 4 operations:  (1) shift the pawns forward one rank  *
772  *  then and with empty squares;  (2) shift the pawns       *
773  *  forward two ranks and then and with empty squares;      *
774  *  (3) remove the a-pawn(s) then shift the pawns           *
775  *  diagonally left then and with enemy occupied squares;   *
776  *  (4) remove the h-pawn(s) then shift the pawns           *
777  *  diagonally right then and with enemy occupied squares.  *
778  *  note that the only captures produced are under-         *
779  *  promotions, because the rest were done in GenCap.       *
780  *                                                          *
781  ************************************************************
782  */
783   padvances1 = ((side) ? Pawns(side) << 8 : Pawns(side) >> 8) & target;
784   padvances2 =
785       ((side) ? (padvances1 & mask_advance_2_w) << 8 : (padvances1 &
786           mask_advance_2_b) >> 8) & target;
787 /*
788  ************************************************************
789  *                                                          *
790  *  Now that we got 'em, we simply enumerate the to         *
791  *  squares as before, but in four steps since we have      *
792  *  four sets of potential moves.                           *
793  *                                                          *
794  ************************************************************
795  */
796   for (; padvances2; Clear(to, padvances2)) {
797     to = MostAdvanced(side, padvances2);
798     *move++ = (to + pawnadv2[side]) | (to << 6) | (pawn << 12);
799   }
800   for (; padvances1; Clear(to, padvances1)) {
801     to = MostAdvanced(side, padvances1);
802     common = (to + pawnadv1[side]) | (to << 6) | (pawn << 12);
803     if ((side) ? to < 56 : to > 7)
804       *move++ = common;
805     else {
806       *move++ = common | (rook << 18);
807       *move++ = common | (bishop << 18);
808       *move++ = common | (knight << 18);
809     }
810   }
811 /*
812  ************************************************************
813  *                                                          *
814  *  Generate the rest of the promotions here since          *
815  *  GenerateCaptures() only generated captures or           *
816  *  promotions to a queen.                                  *
817  *                                                          *
818  ************************************************************
819  */
820   target = Occupied(enemy) & rank_mask[rank8[side]];
821   pcapturesl =
822       ((side) ? (Pawns(white) & mask_left_edge) << 7 : (Pawns(black) &
823           mask_left_edge) >> 9) & target;
824   for (; pcapturesl; Clear(to, pcapturesl)) {
825     to = MostAdvanced(side, pcapturesl);
826     common = (to + capleft[side]) | (to << 6) | (pawn << 12);
827     *move++ = common | (Abs(PcOnSq(to)) << 15) | (rook << 18);
828     *move++ = common | (Abs(PcOnSq(to)) << 15) | (bishop << 18);
829     *move++ = common | (Abs(PcOnSq(to)) << 15) | (knight << 18);
830   }
831   pcapturesr =
832       ((side) ? (Pawns(white) & mask_right_edge) << 9 : (Pawns(black) &
833           mask_right_edge) >> 7) & target;
834   for (; pcapturesr; Clear(to, pcapturesr)) {
835     to = MostAdvanced(side, pcapturesr);
836     common = (to + capright[side]) | (to << 6) | (pawn << 12);
837     *move++ = common | (Abs(PcOnSq(to)) << 15) | (rook << 18);
838     *move++ = common | (Abs(PcOnSq(to)) << 15) | (bishop << 18);
839     *move++ = common | (Abs(PcOnSq(to)) << 15) | (knight << 18);
840   }
841   return move;
842 }
843 
844 /* modified 12/31/15 */
845 /*
846  *******************************************************************************
847  *                                                                             *
848  *   PinnedOnKing() is used to determine if the piece on <square> is pinned    *
849  *   against the king, so that it's illegal to move it.  This is used to cull  *
850  *   potential moves by GenerateCheckEvasions() so that illegal moves are not  *
851  *   produced.                                                                 *
852  *                                                                             *
853  *******************************************************************************
854  */
PinnedOnKing(TREE * RESTRICT tree,int side,int square)855 int PinnedOnKing(TREE * RESTRICT tree, int side, int square) {
856   int ray, enemy = Flip(side);
857 
858 /*
859  ************************************************************
860  *                                                          *
861  *  First, determine if the piece being moved is on the     *
862  *  same diagonal, rank or file as the king.  If not, then  *
863  *  it can't be pinned and we return (0).                   *
864  *                                                          *
865  ************************************************************
866  */
867   ray = directions[square][KingSQ(side)];
868   if (!ray)
869     return 0;
870 /*
871  ************************************************************
872  *                                                          *
873  *  If they are on the same ray, then determine if the king *
874  *  blocks a bishop attack in one direction from this       *
875  *  square and a bishop or queen blocks a bishop attack on  *
876  *  the same diagonal in the opposite direction (or the     *
877  *  same rank/file for rook/queen.)                         *
878  *                                                          *
879  ************************************************************
880  */
881   switch (Abs(ray)) {
882     case 1:
883       if (RankAttacks(square) & Kings(side))
884         return (RankAttacks(square) & (Rooks(enemy) | Queens(enemy))) != 0;
885       else
886         return 0;
887     case 7:
888       if (Diagh1Attacks(square) & Kings(side))
889         return (Diagh1Attacks(square) & (Bishops(enemy) | Queens(enemy))) !=
890             0;
891       else
892         return 0;
893     case 8:
894       if (FileAttacks(square) & Kings(side))
895         return (FileAttacks(square) & (Rooks(enemy) | Queens(enemy))) != 0;
896       else
897         return 0;
898     case 9:
899       if (Diaga1Attacks(square) & Kings(side))
900         return (Diaga1Attacks(square) & (Bishops(enemy) | Queens(enemy))) !=
901             0;
902       else
903         return 0;
904   }
905   return 0;
906 }
907