Subversion Repositories Games.Chess Giants

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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