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 * |