Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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