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