Rev 33 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 33 | Rev 108 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | #include "chess.h" |
1 | #include "chess.h" |
2 | #include "data.h" |
2 | #include "data.h" |
3 | /* modified |
3 | /* modified 12/31/15 */ |
4 | /* |
4 | /* |
5 | ******************************************************************************* |
5 | ******************************************************************************* |
6 | * * |
6 | * * |
7 | * GenerateCaptures() is used to generate capture and pawn promotion moves * |
7 | * GenerateCaptures() is used to generate capture and pawn promotion moves * |
8 | * from the current position. * |
8 | * from the current position. * |
Line 11... | Line 11... | ||
11 | * pieces, plus the set of squares on the 8th rank that pawns can advance to * |
11 | * pieces, plus the set of squares on the 8th rank that pawns can advance to * |
12 | * and promote. * |
12 | * and promote. * |
13 | * * |
13 | * * |
14 | ******************************************************************************* |
14 | ******************************************************************************* |
15 | */ |
15 | */ |
16 |
|
16 | unsigned *GenerateCaptures(TREE * RESTRICT tree, int ply, int side, |
17 |
|
17 | unsigned *move) { |
18 | uint64_t promotions, pcapturesl, pcapturesr; |
18 | uint64_t target, piecebd, moves, promotions, pcapturesl, pcapturesr; |
19 | int from, to, temp, common, enemy = Flip(side); |
19 | int from, to, temp, common, enemy = Flip(side); |
20 | 20 | ||
21 | /* |
21 | /* |
22 | ************************************************************ |
22 | ************************************************************ |
23 | * * |
23 | * * |
Line 27... | Line 27... | ||
27 | * for each knight. * |
27 | * for each knight. * |
28 | * * |
28 | * * |
29 | ************************************************************ |
29 | ************************************************************ |
30 | */ |
30 | */ |
31 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
31 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
32 | from = |
32 | from = MostAdvanced(side, piecebd); |
33 | moves = knight_attacks[from] & Occupied(enemy); |
33 | moves = knight_attacks[from] & Occupied(enemy); |
34 | temp = from + (knight << 12); |
34 | temp = from + (knight << 12); |
35 | Extract(side, move, moves, temp); |
35 | Extract(side, move, moves, temp); |
36 | } |
36 | } |
37 | /* |
37 | /* |
38 | ************************************************************ |
38 | ************************************************************ |
39 | * * |
39 | * * |
40 | * We produce |
40 | * We produce sliding piece moves by locating each piece * |
- | 41 | * type in turn. We then start with the most advanced * |
|
41 | * |
42 | * piece and generate moves from that square. This uses * |
42 | * move generation to |
43 | * "magic move generation" to produce the destination * |
43 | * |
44 | * squares. * |
44 | * * |
45 | * * |
45 | ************************************************************ |
46 | ************************************************************ |
46 | */ |
47 | */ |
47 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
48 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
48 | from = |
49 | from = MostAdvanced(side, piecebd); |
49 | moves = BishopAttacks(from, OccupiedSquares) & Occupied(enemy); |
50 | moves = BishopAttacks(from, OccupiedSquares) & Occupied(enemy); |
50 | temp = from + (bishop << 12); |
51 | temp = from + (bishop << 12); |
51 | Extract(side, move, moves, temp); |
52 | Extract(side, move, moves, temp); |
52 | } |
53 | } |
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)) { |
54 | for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) { |
64 | from = |
55 | from = MostAdvanced(side, piecebd); |
65 | moves = RookAttacks(from, OccupiedSquares) & Occupied(enemy); |
56 | moves = RookAttacks(from, OccupiedSquares) & Occupied(enemy); |
66 | temp = from + (rook << 12); |
57 | temp = from + (rook << 12); |
67 | Extract(side, move, moves, temp); |
58 | Extract(side, move, moves, temp); |
68 | } |
59 | } |
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)) { |
60 | for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) { |
80 | from = |
61 | from = MostAdvanced(side, piecebd); |
81 | moves = QueenAttacks(from, OccupiedSquares) & Occupied(enemy); |
62 | moves = QueenAttacks(from, OccupiedSquares) & Occupied(enemy); |
82 | temp = from + (queen << 12); |
63 | temp = from + (queen << 12); |
83 | Extract(side, move, moves, temp); |
64 | Extract(side, move, moves, temp); |
84 | } |
65 | } |
85 | /* |
66 | /* |
Line 106... | Line 87... | ||
106 | * do this by removing all pawns but those on the 7th rank * |
87 | * do this by removing all pawns but those on the 7th rank * |
107 | * and then advancing them if the square in front is empty.* |
88 | * and then advancing them if the square in front is empty.* |
108 | * * |
89 | * * |
109 | ************************************************************ |
90 | ************************************************************ |
110 | */ |
91 | */ |
- | 92 | promotions = Pawns(side) & rank_mask[rank7[side]]; |
|
111 | promotions = |
93 | promotions = |
112 | ((side) ? (Pawns(white) & rank_mask[RANK7]) << 8 : (Pawns(black) & |
- | |
113 |
|
94 | ((side) ? promotions << 8 : promotions >> 8) & ~OccupiedSquares; |
114 | for (; promotions; Clear(to, promotions)) { |
95 | for (; promotions; Clear(to, promotions)) { |
115 | to = LSB(promotions); |
96 | to = LSB(promotions); |
116 | *move++ = |
97 | *move++ = |
117 | (to + pawnadv1[side]) | (to << 6) | (pawn << 12) | (queen << 18); |
98 | (to + pawnadv1[side]) | (to << 6) | (pawn << 12) | (queen << 18); |
118 | } |
99 | } |
119 | target = Occupied(enemy) | EnPassantTarget(ply); |
100 | target = Occupied(enemy) | EnPassantTarget(ply); |
120 | pcapturesl = |
101 | pcapturesl = |
121 | ((side) ? (Pawns(white) & mask_left_edge) << 7 : (Pawns(black) & |
102 | ((side) ? (Pawns(white) & mask_left_edge) << 7 : (Pawns(black) & |
122 | mask_left_edge) >> 9) & target; |
103 | mask_left_edge) >> 9) & target; |
123 | for (; pcapturesl; Clear(to, pcapturesl)) { |
104 | for (; pcapturesl; Clear(to, pcapturesl)) { |
124 | to = |
105 | to = MostAdvanced(side, pcapturesl); |
125 | common = (to + capleft[side]) | (to << 6) | (pawn << 12); |
106 | common = (to + capleft[side]) | (to << 6) | (pawn << 12); |
126 | if ((side) ? to < 56 : to > 7) |
107 | if ((side) ? to < 56 : to > 7) |
127 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
108 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
128 | else |
109 | else |
129 | *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18; |
110 | *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18; |
130 | } |
111 | } |
131 | pcapturesr = |
112 | pcapturesr = |
132 | ((side) ? (Pawns(white) & mask_right_edge) << 9 : (Pawns(black) & |
113 | ((side) ? (Pawns(white) & mask_right_edge) << 9 : (Pawns(black) & |
133 | mask_right_edge) >> 7) & target; |
114 | mask_right_edge) >> 7) & target; |
134 | for (; pcapturesr; Clear(to, pcapturesr)) { |
115 | for (; pcapturesr; Clear(to, pcapturesr)) { |
135 | to = |
116 | to = MostAdvanced(side, pcapturesr); |
136 | common = (to + capright[side]) | (to << 6) | (pawn << 12); |
117 | common = (to + capright[side]) | (to << 6) | (pawn << 12); |
137 | if ((side) ? to < 56 : to > 7) |
118 | if ((side) ? to < 56 : to > 7) |
138 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
119 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
139 | else |
120 | else |
140 | *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18; |
121 | *move++ = common | Abs(PcOnSq(to)) << 15 | queen << 18; |
141 | } |
122 | } |
142 | return move; |
123 | return move; |
143 | } |
124 | } |
144 | 125 | ||
145 | /* modified |
126 | /* modified 12/31/15 */ |
146 | /* |
127 | /* |
147 | ******************************************************************************* |
128 | ******************************************************************************* |
148 | * * |
129 | * * |
149 | * GenerateChecks() is used to generate non-capture moves from the current * |
130 | * GenerateChecks() is used to generate non-capture moves from the current * |
150 | * position. * |
131 | * position. * |
Line 177... | Line 158... | ||
177 | * attack. This might be fixed at some point, but it is rare enough to not * |
158 | * attack. This might be fixed at some point, but it is rare enough to not * |
178 | * be an issue except in far endgames. * |
159 | * be an issue except in far endgames. * |
179 | * * |
160 | * * |
180 | ******************************************************************************* |
161 | ******************************************************************************* |
181 | */ |
162 | */ |
182 |
|
163 | unsigned *GenerateChecks(TREE * RESTRICT tree, int side, unsigned *move) { |
183 | uint64_t temp_target, target, piecebd, moves; |
164 | uint64_t temp_target, target, piecebd, moves; |
184 | uint64_t padvances1, blockers, checkers; |
165 | uint64_t padvances1, blockers, checkers; |
185 | int from, to, promote, temp, enemy = Flip(side); |
166 | int from, to, promote, temp, enemy = Flip(side); |
186 | 167 | ||
187 | /* |
168 | /* |
188 | |
169 | ************************************************************ |
189 | * |
170 | * * |
190 | * First pass: produce direct checks. For each piece |
171 | * First pass: produce direct checks. For each piece * |
191 | * |
172 | * type, we pretend that a piece of that type stands on * |
192 | * king and we generate attacks from |
173 | * the square of the king and we generate attacks from * |
- | 174 | * that square for that piece. Now, if we can find any * |
|
193 | * |
175 | * piece of that type that attacks one of those squares, * |
194 | * |
176 | * then that piece move would deliver a direct check to * |
195 | * |
177 | * the enemy king. Easy, wasn't it? * |
196 | * |
178 | * * |
197 | |
179 | ************************************************************ |
198 | */ |
180 | */ |
199 | target = ~OccupiedSquares; |
181 | target = ~OccupiedSquares; |
200 | /* |
182 | /* |
201 | ************************************************************ |
183 | ************************************************************ |
202 | * * |
184 | * * |
Line 204... | Line 186... | ||
204 | * * |
186 | * * |
205 | ************************************************************ |
187 | ************************************************************ |
206 | */ |
188 | */ |
207 | temp_target = target & knight_attacks[KingSQ(enemy)]; |
189 | temp_target = target & knight_attacks[KingSQ(enemy)]; |
208 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
190 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
209 | from = |
191 | from = MostAdvanced(side, piecebd); |
210 | moves = knight_attacks[from] & temp_target; |
192 | moves = knight_attacks[from] & temp_target; |
211 | temp = from + (knight << 12); |
193 | temp = from + (knight << 12); |
212 | Extract(side, move, moves, temp); |
194 | Extract(side, move, moves, temp); |
213 | } |
195 | } |
214 | /* |
196 | /* |
215 | ************************************************************ |
197 | ************************************************************ |
216 | * * |
198 | * * |
217 | * |
199 | * Sliding piece direct checks. * |
218 | * * |
200 | * * |
219 | ************************************************************ |
201 | ************************************************************ |
220 | */ |
202 | */ |
221 | temp_target = target & BishopAttacks(KingSQ(enemy), OccupiedSquares); |
203 | temp_target = target & BishopAttacks(KingSQ(enemy), OccupiedSquares); |
222 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
204 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
223 | from = |
205 | from = MostAdvanced(side, piecebd); |
224 | moves = BishopAttacks(from, OccupiedSquares) & temp_target; |
206 | moves = BishopAttacks(from, OccupiedSquares) & temp_target; |
225 | temp = from + (bishop << 12); |
207 | temp = from + (bishop << 12); |
226 | Extract(side, move, moves, temp); |
208 | Extract(side, move, moves, temp); |
227 | } |
209 | } |
228 | /* |
- | |
229 | ************************************************************ |
- | |
230 | * * |
- | |
231 | * Rook direct checks. * |
- | |
232 | * * |
- | |
233 | ************************************************************ |
- | |
234 | */ |
- | |
235 | temp_target = target & RookAttacks(KingSQ(enemy), OccupiedSquares); |
210 | temp_target = target & RookAttacks(KingSQ(enemy), OccupiedSquares); |
236 | for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) { |
211 | for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) { |
237 | from = |
212 | from = MostAdvanced(side, piecebd); |
238 | moves = RookAttacks(from, OccupiedSquares) & temp_target; |
213 | moves = RookAttacks(from, OccupiedSquares) & temp_target; |
239 | temp = from + (rook << 12); |
214 | temp = from + (rook << 12); |
240 | Extract(side, move, moves, temp); |
215 | Extract(side, move, moves, temp); |
241 | } |
216 | } |
242 | /* |
- | |
243 | ************************************************************ |
- | |
244 | * * |
- | |
245 | * Queen direct checks. * |
- | |
246 | * * |
- | |
247 | ************************************************************ |
- | |
248 | */ |
- | |
249 | temp_target = target & QueenAttacks(KingSQ(enemy), OccupiedSquares); |
217 | temp_target = target & QueenAttacks(KingSQ(enemy), OccupiedSquares); |
250 | for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) { |
218 | for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) { |
251 | from = |
219 | from = MostAdvanced(side, piecebd); |
252 | moves = QueenAttacks(from, OccupiedSquares) & temp_target; |
220 | moves = QueenAttacks(from, OccupiedSquares) & temp_target; |
253 | temp = from + (queen << 12); |
221 | temp = from + (queen << 12); |
254 | Extract(side, move, moves, temp); |
222 | Extract(side, move, moves, temp); |
255 | } |
223 | } |
256 | /* |
224 | /* |
Line 261... | Line 229... | ||
261 | ************************************************************ |
229 | ************************************************************ |
262 | */ |
230 | */ |
263 | temp_target = target & pawn_attacks[enemy][KingSQ(enemy)]; |
231 | temp_target = target & pawn_attacks[enemy][KingSQ(enemy)]; |
264 | padvances1 = ((side) ? Pawns(white) << 8 : Pawns(black) >> 8) & temp_target; |
232 | padvances1 = ((side) ? Pawns(white) << 8 : Pawns(black) >> 8) & temp_target; |
265 | for (; padvances1; Clear(to, padvances1)) { |
233 | for (; padvances1; Clear(to, padvances1)) { |
266 | to = |
234 | to = MostAdvanced(side, padvances1); |
267 | *move++ = (to + pawnadv1[side]) | (to << 6) | (pawn << 12); |
235 | *move++ = (to + pawnadv1[side]) | (to << 6) | (pawn << 12); |
268 | } |
236 | } |
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 | /* |
237 | /* |
287 | ************************************************************ |
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. * |
|
288 | * * |
253 | * * |
289 | * First we look for diagonal discovered attacks. Once we * |
254 | * First we look for diagonal discovered attacks. Once we * |
290 | * know which squares hold pieces that create a discovered * |
255 | * know which squares hold pieces that create a discovered * |
291 | * check when they move, we generate those piece moves * |
256 | * check when they move, we generate those piece moves * |
292 | * piece type by piece type. * |
257 | * piece type by piece type. * |
Line 321... | Line 286... | ||
321 | * * |
286 | * * |
322 | ************************************************************ |
287 | ************************************************************ |
323 | */ |
288 | */ |
324 | temp_target = target & ~knight_attacks[KingSQ(enemy)]; |
289 | temp_target = target & ~knight_attacks[KingSQ(enemy)]; |
325 | for (piecebd = Knights(side) & blockers; piecebd; Clear(from, piecebd)) { |
290 | for (piecebd = Knights(side) & blockers; piecebd; Clear(from, piecebd)) { |
326 | from = |
291 | from = MostAdvanced(side, piecebd); |
327 | moves = knight_attacks[from] & temp_target; |
292 | moves = knight_attacks[from] & temp_target; |
328 | temp = from + (knight << 12); |
293 | temp = from + (knight << 12); |
329 | Extract(side, move, moves, temp); |
294 | Extract(side, move, moves, temp); |
330 | } |
295 | } |
331 | /* |
296 | /* |
Line 336... | Line 301... | ||
336 | ************************************************************ |
301 | ************************************************************ |
337 | */ |
302 | */ |
338 | target = ~OccupiedSquares; |
303 | target = ~OccupiedSquares; |
339 | temp_target = target & ~RookAttacks(KingSQ(enemy), OccupiedSquares); |
304 | temp_target = target & ~RookAttacks(KingSQ(enemy), OccupiedSquares); |
340 | for (piecebd = Rooks(side) & blockers; piecebd; Clear(from, piecebd)) { |
305 | for (piecebd = Rooks(side) & blockers; piecebd; Clear(from, piecebd)) { |
341 | from = |
306 | from = MostAdvanced(side, piecebd); |
342 | moves = RookAttacks(from, OccupiedSquares) & temp_target; |
307 | moves = RookAttacks(from, OccupiedSquares) & temp_target; |
343 | temp = from + (rook << 12); |
308 | temp = from + (rook << 12); |
344 | Extract(side, move, moves, temp); |
309 | Extract(side, move, moves, temp); |
345 | } |
310 | } |
346 | /* |
311 | /* |
Line 352... | Line 317... | ||
352 | */ |
317 | */ |
353 | piecebd = |
318 | piecebd = |
354 | Pawns(side) & blockers & ((side) ? ~OccupiedSquares >> 8 : |
319 | Pawns(side) & blockers & ((side) ? ~OccupiedSquares >> 8 : |
355 | ~OccupiedSquares << 8); |
320 | ~OccupiedSquares << 8); |
356 | for (; piecebd; Clear(from, piecebd)) { |
321 | for (; piecebd; Clear(from, piecebd)) { |
357 | from = |
322 | from = MostAdvanced(side, piecebd); |
358 | to = from + pawnadv1[enemy]; |
323 | to = from + pawnadv1[enemy]; |
359 | if ((side) ? to > 55 : to < 8) |
324 | if ((side) ? to > 55 : to < 8) |
360 | promote = queen; |
325 | promote = queen; |
361 | else |
326 | else |
362 | promote = 0; |
327 | promote = 0; |
Line 403... | Line 368... | ||
403 | * * |
368 | * * |
404 | ************************************************************ |
369 | ************************************************************ |
405 | */ |
370 | */ |
406 | temp_target = target & ~knight_attacks[KingSQ(enemy)]; |
371 | temp_target = target & ~knight_attacks[KingSQ(enemy)]; |
407 | for (piecebd = Knights(side) & blockers; piecebd; Clear(from, piecebd)) { |
372 | for (piecebd = Knights(side) & blockers; piecebd; Clear(from, piecebd)) { |
408 | from = |
373 | from = MostAdvanced(side, piecebd); |
409 | moves = knight_attacks[from] & temp_target; |
374 | moves = knight_attacks[from] & temp_target; |
410 | temp = from + (knight << 12); |
375 | temp = from + (knight << 12); |
411 | Extract(side, move, moves, temp); |
376 | Extract(side, move, moves, temp); |
412 | } |
377 | } |
413 | /* |
378 | /* |
Line 418... | Line 383... | ||
418 | ************************************************************ |
383 | ************************************************************ |
419 | */ |
384 | */ |
420 | target = ~OccupiedSquares; |
385 | target = ~OccupiedSquares; |
421 | temp_target = target & ~BishopAttacks(KingSQ(enemy), OccupiedSquares); |
386 | temp_target = target & ~BishopAttacks(KingSQ(enemy), OccupiedSquares); |
422 | for (piecebd = Bishops(side) & blockers; piecebd; Clear(from, piecebd)) { |
387 | for (piecebd = Bishops(side) & blockers; piecebd; Clear(from, piecebd)) { |
423 | from = |
388 | from = MostAdvanced(side, piecebd); |
424 | moves = BishopAttacks(from, OccupiedSquares) & temp_target; |
389 | moves = BishopAttacks(from, OccupiedSquares) & temp_target; |
425 | temp = from + (bishop << 12); |
390 | temp = from + (bishop << 12); |
426 | Extract(side, move, moves, temp); |
391 | Extract(side, move, moves, temp); |
427 | } |
392 | } |
428 | /* |
393 | /* |
Line 434... | Line 399... | ||
434 | */ |
399 | */ |
435 | piecebd = |
400 | piecebd = |
436 | Pawns(side) & blockers & ((side) ? ~OccupiedSquares >> 8 : |
401 | Pawns(side) & blockers & ((side) ? ~OccupiedSquares >> 8 : |
437 | ~OccupiedSquares << 8); |
402 | ~OccupiedSquares << 8); |
438 | for (; piecebd; Clear(from, piecebd)) { |
403 | for (; piecebd; Clear(from, piecebd)) { |
439 | from = |
404 | from = MostAdvanced(side, piecebd); |
440 | to = from + pawnadv1[enemy]; |
405 | to = from + pawnadv1[enemy]; |
441 | if ((side) ? to > 55 : to < 8) |
406 | if ((side) ? to > 55 : to < 8) |
442 | promote = queen; |
407 | promote = queen; |
443 | else |
408 | else |
444 | promote = 0; |
409 | promote = 0; |
Line 447... | Line 412... | ||
447 | } |
412 | } |
448 | } |
413 | } |
449 | return move; |
414 | return move; |
450 | } |
415 | } |
451 | 416 | ||
452 | /* modified |
417 | /* modified 12/31/15 */ |
453 | /* |
418 | /* |
454 | ******************************************************************************* |
419 | ******************************************************************************* |
455 | * * |
420 | * * |
456 | * GenerateCheckEvasions() is used to generate moves when the king is in * |
421 | * GenerateCheckEvasions() is used to generate moves when the king is in * |
457 | * check. * |
422 | * check. * |
Line 471... | Line 436... | ||
471 | * checking the king, then the only legal capture to try is for the king to * |
436 | * 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. * |
437 | * capture one of the checking pieces that is on an unattacked square. * |
473 | * * |
438 | * * |
474 | ******************************************************************************* |
439 | ******************************************************************************* |
475 | */ |
440 | */ |
476 |
|
441 | unsigned *GenerateCheckEvasions(TREE * RESTRICT tree, int ply, int side, |
- | 442 | unsigned *move) { |
|
477 | uint64_t target, targetc, targetp, piecebd, moves; |
443 | uint64_t target, targetc, targetp, piecebd, moves, empty, checksqs; |
478 | uint64_t padvances1, padvances2, pcapturesl, pcapturesr; |
444 | uint64_t padvances1, padvances2, pcapturesl, pcapturesr, padvances1_all; |
479 | uint64_t padvances1_all, empty, checksqs; |
- | |
480 | int from, to, temp, common, enemy = Flip(side); |
445 | int from, to, temp, common, enemy = Flip(side), king_square, checkers; |
481 | int king_square, checkers, checking_square; |
- | |
482 | int check_direction1 = 0, check_direction2 = 0; |
446 | int checking_square, check_direction1 = 0, check_direction2 = 0; |
483 | 447 | ||
484 | /* |
448 | /* |
485 | ************************************************************ |
449 | ************************************************************ |
486 | * * |
450 | * * |
487 | * First, determine how many pieces are attacking the king * |
451 | * First, determine how many pieces are attacking the king * |
Line 528... | Line 492... | ||
528 | ************************************************************ |
492 | ************************************************************ |
529 | */ |
493 | */ |
530 | from = king_square; |
494 | from = king_square; |
531 | temp = from + (king << 12); |
495 | temp = from + (king << 12); |
532 | for (moves = king_attacks[from] & ~Occupied(side); moves; Clear(to, moves)) { |
496 | for (moves = king_attacks[from] & ~Occupied(side); moves; Clear(to, moves)) { |
533 | to = |
497 | to = MostAdvanced(side, moves); |
534 | if (!Attacks(tree, enemy, to) |
498 | if (!Attacks(tree, enemy, to) |
535 | && directions[from][to] != check_direction1 && |
499 | && directions[from][to] != check_direction1 && |
536 | directions[from][to] != check_direction2) |
500 | directions[from][to] != check_direction2) |
537 | *move++ = temp | (to << 6) | (Abs(PcOnSq(to)) << 15); |
501 | *move++ = temp | (to << 6) | (Abs(PcOnSq(to)) << 15); |
538 | } |
502 | } |
Line 546... | Line 510... | ||
546 | * * |
510 | * * |
547 | ************************************************************ |
511 | ************************************************************ |
548 | */ |
512 | */ |
549 | if (checkers == 1) { |
513 | if (checkers == 1) { |
550 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
514 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
551 | from = |
515 | from = MostAdvanced(side, piecebd); |
552 | if (!PinnedOnKing(tree, side, from)) { |
516 | if (!PinnedOnKing(tree, side, from)) { |
553 | moves = knight_attacks[from] & target; |
517 | moves = knight_attacks[from] & target; |
554 | temp = from + (knight << 12); |
518 | temp = from + (knight << 12); |
555 | Extract(side, move, moves, temp); |
519 | Extract(side, move, moves, temp); |
556 | } |
520 | } |
557 | } |
521 | } |
558 | /* |
522 | /* |
559 | ************************************************************ |
523 | ************************************************************ |
560 | * * |
524 | * * |
561 | * We produce |
525 | * We produce sliding piece moves by locating each piece * |
- | 526 | * type in turn. We then start with the most advanced * |
|
562 | * |
527 | * piece and generate moves from that square. This uses * |
563 | * move generation to |
528 | * "magic move generation" to produce the destination * |
564 | * |
529 | * squares. * |
565 | * * |
530 | * * |
566 | ************************************************************ |
531 | ************************************************************ |
567 | */ |
532 | */ |
568 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
533 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
569 | from = |
534 | from = MostAdvanced(side, piecebd); |
570 | if (!PinnedOnKing(tree, side, from)) { |
535 | if (!PinnedOnKing(tree, side, from)) { |
571 | moves = BishopAttacks(from, OccupiedSquares) & target; |
536 | moves = BishopAttacks(from, OccupiedSquares) & target; |
572 | temp = from + (bishop << 12); |
537 | temp = from + (bishop << 12); |
573 | Extract(side, move, moves, temp); |
538 | Extract(side, move, moves, temp); |
574 | } |
539 | } |
575 | } |
540 | } |
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)) { |
541 | for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) { |
587 | from = |
542 | from = MostAdvanced(side, piecebd); |
588 | if (!PinnedOnKing(tree, side, from)) { |
543 | if (!PinnedOnKing(tree, side, from)) { |
589 | moves = RookAttacks(from, OccupiedSquares) & target; |
544 | moves = RookAttacks(from, OccupiedSquares) & target; |
590 | temp = from + (rook << 12); |
545 | temp = from + (rook << 12); |
591 | Extract(side, move, moves, temp); |
546 | Extract(side, move, moves, temp); |
592 | } |
547 | } |
593 | } |
548 | } |
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)) { |
549 | for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) { |
605 | from = |
550 | from = MostAdvanced(side, piecebd); |
606 | if (!PinnedOnKing(tree, side, from)) { |
551 | if (!PinnedOnKing(tree, side, from)) { |
607 | moves = QueenAttacks(from, OccupiedSquares) & target; |
552 | moves = QueenAttacks(from, OccupiedSquares) & target; |
608 | temp = from + (queen << 12); |
553 | temp = from + (queen << 12); |
609 | Extract(side, move, moves, temp); |
554 | Extract(side, move, moves, temp); |
610 | } |
555 | } |
Line 642... | Line 587... | ||
642 | * potential moves. * |
587 | * potential moves. * |
643 | * * |
588 | * * |
644 | ************************************************************ |
589 | ************************************************************ |
645 | */ |
590 | */ |
646 | for (; padvances2; Clear(to, padvances2)) { |
591 | for (; padvances2; Clear(to, padvances2)) { |
647 | to = |
592 | to = MostAdvanced(side, padvances2); |
648 | if (!PinnedOnKing(tree, side, to + pawnadv2[side])) |
593 | if (!PinnedOnKing(tree, side, to + pawnadv2[side])) |
649 | *move++ = (to + pawnadv2[side]) | (to << 6) | (pawn << 12); |
594 | *move++ = (to + pawnadv2[side]) | (to << 6) | (pawn << 12); |
650 | } |
595 | } |
651 | for (; padvances1; Clear(to, padvances1)) { |
596 | for (; padvances1; Clear(to, padvances1)) { |
652 | to = |
597 | to = MostAdvanced(side, padvances1); |
653 | if (!PinnedOnKing(tree, side, to + pawnadv1[side])) { |
598 | if (!PinnedOnKing(tree, side, to + pawnadv1[side])) { |
654 | common = (to + pawnadv1[side]) | (to << 6) | (pawn << 12); |
599 | common = (to + pawnadv1[side]) | (to << 6) | (pawn << 12); |
655 | if ((side) ? to < 56 : to > 7) |
600 | if ((side) ? to < 56 : to > 7) |
656 | *move++ = common; |
601 | *move++ = common; |
657 | else { |
602 | else { |
658 | *move++ = common | (queen << 18); |
603 | *move++ = common | (queen << 18); |
659 | *move++ = common | (knight << 18); |
604 | *move++ = common | (knight << 18); |
660 | } |
605 | } |
661 | } |
606 | } |
662 | } |
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 | */ |
|
663 | targetc = Occupied(enemy) | EnPassantTarget(ply); |
616 | targetc = Occupied(enemy) | EnPassantTarget(ply); |
664 | targetc = targetc & target; |
617 | targetc = targetc & target; |
665 | if (Pawns(enemy) & target & ((side) ? EnPassantTarget(ply) >> 8 : |
618 | if (Pawns(enemy) & target & ((side) ? EnPassantTarget(ply) >> 8 : |
666 | EnPassantTarget(ply) << 8)) |
619 | EnPassantTarget(ply) << 8)) |
667 | targetc = targetc | EnPassantTarget(ply); |
620 | targetc = targetc | EnPassantTarget(ply); |
Line 671... | Line 624... | ||
671 | } else { |
624 | } else { |
672 | pcapturesl = (Pawns(black) & mask_left_edge) >> 9 & targetc; |
625 | pcapturesl = (Pawns(black) & mask_left_edge) >> 9 & targetc; |
673 | pcapturesr = (Pawns(black) & mask_right_edge) >> 7 & targetc; |
626 | pcapturesr = (Pawns(black) & mask_right_edge) >> 7 & targetc; |
674 | } |
627 | } |
675 | for (; pcapturesl; Clear(to, pcapturesl)) { |
628 | for (; pcapturesl; Clear(to, pcapturesl)) { |
676 | to = |
629 | to = MostAdvanced(side, pcapturesl); |
677 | if (!PinnedOnKing(tree, side, to + capleft[side])) { |
630 | if (!PinnedOnKing(tree, side, to + capleft[side])) { |
678 | common = (to + capleft[side]) | (to << 6) | (pawn << 12); |
631 | common = (to + capleft[side]) | (to << 6) | (pawn << 12); |
679 | if ((side) ? to < 56 : to > 7) |
632 | if ((side) ? to < 56 : to > 7) |
680 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
633 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
681 | else { |
634 | else { |
Line 683... | Line 636... | ||
683 | *move++ = common | Abs(PcOnSq(to)) << 15 | knight << 18; |
636 | *move++ = common | Abs(PcOnSq(to)) << 15 | knight << 18; |
684 | } |
637 | } |
685 | } |
638 | } |
686 | } |
639 | } |
687 | for (; pcapturesr; Clear(to, pcapturesr)) { |
640 | for (; pcapturesr; Clear(to, pcapturesr)) { |
688 | to = |
641 | to = MostAdvanced(side, pcapturesr); |
689 | if (!PinnedOnKing(tree, side, to + capright[side])) { |
642 | if (!PinnedOnKing(tree, side, to + capright[side])) { |
690 | common = (to + capright[side]) | (to << 6) | (pawn << 12); |
643 | common = (to + capright[side]) | (to << 6) | (pawn << 12); |
691 | if ((side) ? to < 56 : to > 7) |
644 | if ((side) ? to < 56 : to > 7) |
692 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
645 | *move++ = common | (((PcOnSq(to)) ? Abs(PcOnSq(to)) : pawn) << 15); |
693 | else { |
646 | else { |
Line 698... | Line 651... | ||
698 | } |
651 | } |
699 | } |
652 | } |
700 | return move; |
653 | return move; |
701 | } |
654 | } |
702 | 655 | ||
703 | /* modified |
656 | /* modified 12/31/15 */ |
704 | /* |
657 | /* |
705 | ******************************************************************************* |
658 | ******************************************************************************* |
706 | * * |
659 | * * |
707 | * GenerateNoncaptures() is used to generate non-capture moves from the * |
660 | * GenerateNoncaptures() is used to generate non-capture moves from the * |
708 | * current position. * |
661 | * current position. * |
709 | * * |
662 | * * |
710 | * Once the valid destination squares are known, we have to locate a * |
663 | * 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 | * |
664 | * friendly piece to compute the squares it attacks. * |
714 | * * |
665 | * * |
715 | * Pawns are handled differently. Regular pawn moves are produced by * |
666 | * Pawns are handled differently. Regular pawn moves are produced by * |
716 | * shifting the pawn bitmap 8 bits "forward" and anding this with the * |
667 | * shifting the pawn bitmap 8 bits "forward" and anding this with the * |
717 | * complement of the occupied squares bitmap |
668 | * 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 * |
669 | * 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 * |
670 | * 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 * |
671 | * the complement of the occupied squares bitmap as before. If [to] reaches * |
721 | * the 8th rank, we produce a set of |
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 * |
|
722 | * |
674 | * GenerateCaptures()). * |
723 | * * |
675 | * * |
724 | ******************************************************************************* |
676 | ******************************************************************************* |
725 | */ |
677 | */ |
726 |
|
678 | unsigned *GenerateNoncaptures(TREE * RESTRICT tree, int ply, int side, |
- | 679 | unsigned *move) { |
|
727 | uint64_t target, piecebd, moves; |
680 | uint64_t target, piecebd, moves; |
728 | uint64_t padvances1, padvances2, pcapturesl, pcapturesr; |
681 | uint64_t padvances1, padvances2, pcapturesl, pcapturesr; |
729 | int from, to, temp, common, enemy = Flip(side); |
682 | int from, to, temp, common, enemy = Flip(side); |
730 | 683 | ||
731 | /* |
684 | /* |
732 | ************************************************************ |
685 | ************************************************************ |
733 | * * |
686 | * * |
734 | * First, produce castling moves |
687 | * First, produce castling moves when they are legal. * |
735 | * * |
688 | * * |
736 | ************************************************************ |
689 | ************************************************************ |
737 | */ |
690 | */ |
738 | if (Castle(ply, side) > 0) { |
691 | if (Castle(ply, side) > 0) { |
739 | if (Castle(ply, side) & 1 && !(OccupiedSquares & OO[side]) |
692 | if (Castle(ply, side) & 1 && !(OccupiedSquares & OO[side]) |
Line 759... | Line 712... | ||
759 | * for each knight. * |
712 | * for each knight. * |
760 | * * |
713 | * * |
761 | ************************************************************ |
714 | ************************************************************ |
762 | */ |
715 | */ |
763 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
716 | for (piecebd = Knights(side); piecebd; Clear(from, piecebd)) { |
764 | from = |
717 | from = MostAdvanced(side, piecebd); |
765 | moves = knight_attacks[from] & target; |
718 | moves = knight_attacks[from] & target; |
766 | temp = from + (knight << 12); |
719 | temp = from + (knight << 12); |
767 | Extract(side, move, moves, temp); |
720 | Extract(side, move, moves, temp); |
768 | } |
721 | } |
769 | /* |
722 | /* |
770 | ************************************************************ |
723 | ************************************************************ |
771 | * * |
724 | * * |
772 | * We produce |
725 | * We produce sliding piece moves by locating each piece * |
- | 726 | * type in turn. We then start with the most advanced * |
|
773 | * |
727 | * piece and generate moves from that square. This uses * |
774 | * move generation to |
728 | * "magic move generation" to produce the destination * |
775 | * |
729 | * squares. * |
776 | * * |
730 | * * |
777 | ************************************************************ |
731 | ************************************************************ |
778 | */ |
732 | */ |
779 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
733 | for (piecebd = Bishops(side); piecebd; Clear(from, piecebd)) { |
780 | from = |
734 | from = MostAdvanced(side, piecebd); |
781 | moves = BishopAttacks(from, OccupiedSquares) & target; |
735 | moves = BishopAttacks(from, OccupiedSquares) & target; |
782 | temp = from + (bishop << 12); |
736 | temp = from + (bishop << 12); |
783 | Extract(side, move, moves, temp); |
737 | Extract(side, move, moves, temp); |
784 | } |
738 | } |
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)) { |
739 | for (piecebd = Rooks(side); piecebd; Clear(from, piecebd)) { |
796 | from = |
740 | from = MostAdvanced(side, piecebd); |
797 | moves = RookAttacks(from, OccupiedSquares) & target; |
741 | moves = RookAttacks(from, OccupiedSquares) & target; |
798 | temp = from + (rook << 12); |
742 | temp = from + (rook << 12); |
799 | Extract(side, move, moves, temp); |
743 | Extract(side, move, moves, temp); |
800 | } |
744 | } |
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)) { |
745 | for (piecebd = Queens(side); piecebd; Clear(from, piecebd)) { |
812 | from = |
746 | from = MostAdvanced(side, piecebd); |
813 | moves = QueenAttacks(from, OccupiedSquares) & target; |
747 | moves = QueenAttacks(from, OccupiedSquares) & target; |
814 | temp = from + (queen << 12); |
748 | temp = from + (queen << 12); |
815 | Extract(side, move, moves, temp); |
749 | Extract(side, move, moves, temp); |
816 | } |
750 | } |
817 | /* |
751 | /* |
Line 858... | Line 792... | ||
858 | * four sets of potential moves. * |
792 | * four sets of potential moves. * |
859 | * * |
793 | * * |
860 | ************************************************************ |
794 | ************************************************************ |
861 | */ |
795 | */ |
862 | for (; padvances2; Clear(to, padvances2)) { |
796 | for (; padvances2; Clear(to, padvances2)) { |
863 | to = |
797 | to = MostAdvanced(side, padvances2); |
864 | *move++ = (to + pawnadv2[side]) | (to << 6) | (pawn << 12); |
798 | *move++ = (to + pawnadv2[side]) | (to << 6) | (pawn << 12); |
865 | } |
799 | } |
866 | for (; padvances1; Clear(to, padvances1)) { |
800 | for (; padvances1; Clear(to, padvances1)) { |
867 | to = |
801 | to = MostAdvanced(side, padvances1); |
868 | common = (to + pawnadv1[side]) | (to << 6) | (pawn << 12); |
802 | common = (to + pawnadv1[side]) | (to << 6) | (pawn << 12); |
869 | if ((side) ? to < 56 : to > 7) |
803 | if ((side) ? to < 56 : to > 7) |
870 | *move++ = common; |
804 | *move++ = common; |
871 | else { |
805 | else { |
872 | *move++ = common | (rook << 18); |
806 | *move++ = common | (rook << 18); |
Line 875... | Line 809... | ||
875 | } |
809 | } |
876 | } |
810 | } |
877 | /* |
811 | /* |
878 | ************************************************************ |
812 | ************************************************************ |
879 | * * |
813 | * * |
880 | * Generate the rest of the |
814 | * Generate the rest of the promotions here since * |
881 | * GenerateCaptures() only |
815 | * GenerateCaptures() only generated captures or * |
882 | * promotions to a queen. * |
816 | * promotions to a queen. * |
883 | * * |
817 | * * |
884 | ************************************************************ |
818 | ************************************************************ |
885 | */ |
819 | */ |
886 | target = Occupied(enemy) & rank_mask[ |
820 | target = Occupied(enemy) & rank_mask[rank8[side]]; |
887 | pcapturesl = |
821 | pcapturesl = |
888 | ((side) ? (Pawns(white) & mask_left_edge) << 7 : (Pawns(black) & |
822 | ((side) ? (Pawns(white) & mask_left_edge) << 7 : (Pawns(black) & |
889 | mask_left_edge) >> 9) & target; |
823 | mask_left_edge) >> 9) & target; |
890 | for (; pcapturesl; Clear(to, pcapturesl)) { |
824 | for (; pcapturesl; Clear(to, pcapturesl)) { |
891 | to = |
825 | to = MostAdvanced(side, pcapturesl); |
892 | common = (to + capleft[side]) | (to << 6) | (pawn << 12); |
826 | common = (to + capleft[side]) | (to << 6) | (pawn << 12); |
893 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (rook << 18); |
827 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (rook << 18); |
894 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (bishop << 18); |
828 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (bishop << 18); |
895 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (knight << 18); |
829 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (knight << 18); |
896 | } |
830 | } |
897 | pcapturesr = |
831 | pcapturesr = |
898 | ((side) ? (Pawns(white) & mask_right_edge) << 9 : (Pawns(black) & |
832 | ((side) ? (Pawns(white) & mask_right_edge) << 9 : (Pawns(black) & |
899 | mask_right_edge) >> 7) & target; |
833 | mask_right_edge) >> 7) & target; |
900 | for (; pcapturesr; Clear(to, pcapturesr)) { |
834 | for (; pcapturesr; Clear(to, pcapturesr)) { |
901 | to = |
835 | to = MostAdvanced(side, pcapturesr); |
902 | common = (to + capright[side]) | (to << 6) | (pawn << 12); |
836 | common = (to + capright[side]) | (to << 6) | (pawn << 12); |
903 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (rook << 18); |
837 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (rook << 18); |
904 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (bishop << 18); |
838 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (bishop << 18); |
905 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (knight << 18); |
839 | *move++ = common | (Abs(PcOnSq(to)) << 15) | (knight << 18); |
906 | } |
840 | } |
907 | return move; |
841 | return move; |
908 | } |
842 | } |
909 | 843 | ||
910 | /* modified |
844 | /* modified 12/31/15 */ |
911 | /* |
845 | /* |
912 | ******************************************************************************* |
846 | ******************************************************************************* |
913 | * * |
847 | * * |
914 | * PinnedOnKing() is used to determine if the piece on <square> is pinned * |
848 | * 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 * |
849 | * against the king, so that it's illegal to move it. This is used to cull * |
Line 917... | Line 851... | ||
917 | * produced. * |
851 | * produced. * |
918 | * * |
852 | * * |
919 | ******************************************************************************* |
853 | ******************************************************************************* |
920 | */ |
854 | */ |
921 | int PinnedOnKing(TREE * RESTRICT tree, int side, int square) { |
855 | int PinnedOnKing(TREE * RESTRICT tree, int side, int square) { |
922 | int ray; |
- | |
923 | int enemy = Flip(side); |
856 | int ray, enemy = Flip(side); |
924 | 857 | ||
925 | /* |
858 | /* |
926 | ************************************************************ |
859 | ************************************************************ |
927 | * * |
860 | * * |
928 | * First, determine if the piece being moved is on the * |
861 | * First, determine if the piece being moved is on the * |