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