Subversion Repositories Games.Chess Giants

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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. }
  974.