home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Jeux / Reflexion / Crafty-15.19.lha / crafty-15.19 / src / movgen.c < prev    next >
C/C++ Source or Header  |  1998-09-13  |  53KB  |  1,292 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "chess.h"
  4. #include "data.h"
  5.  
  6. /* modified 03/11/97 */
  7. /*
  8. ********************************************************************************
  9. *                                                                              *
  10. *   GenerateCaptures() is used to generate capture and pawn promotion moves    *
  11. *   from the current position.                                                 *
  12. *                                                                              *
  13. *   the destination square set is the set of squares occupied by opponent      *
  14. *   pieces, plus the set of squares on the 8th rank that pawns can advance to  *
  15. *   and promote.                                                               *
  16. *                                                                              *
  17. ********************************************************************************
  18. */
  19. int* GenerateCaptures(TREE *tree, int ply, int wtm, int *move)
  20. {
  21.   register BITBOARD target, piecebd, moves;
  22.   register BITBOARD  promotions, pcapturesl, pcapturesr;
  23.   register int from, to, temp;
  24.  
  25.   if (wtm) {
  26. /*
  27.  ----------------------------------------------------------
  28. |                                                          |
  29. |   now, produce knight moves by cycling through the       |
  30. |   *_knight board to locate a [from] square and then      |
  31. |   cycling through knight_attacks[] to locate to squares  |
  32. |   that a knight on [from] attacks.                       |
  33. |                                                          |
  34.  ----------------------------------------------------------
  35. */
  36.     piecebd=WhiteKnights;
  37.     while (piecebd) {
  38.       from=LastOne(piecebd);
  39.       moves=And(knight_attacks[from],BlackPieces);
  40.       temp=from+(knight<<12);
  41.       while (moves) {
  42.         to=LastOne(moves);
  43.         *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  44.         Clear(to,moves);
  45.       }
  46.       Clear(from,piecebd);
  47.     }
  48. /*
  49.  ----------------------------------------------------------
  50. |                                                          |
  51. |   now, produce bishop moves by cycling through the       |
  52. |   *_bishop board to locate a [from] square and then      |
  53. |   generate the AttacksFrom() bitmap which supplies the   |
  54. |   list of valid <to> squares.                            |
  55. |                                                          |
  56.  ----------------------------------------------------------
  57. */
  58.     piecebd=WhiteBishops;
  59.     while (piecebd) {
  60.       from=LastOne(piecebd);
  61.       moves=And(AttacksBishop(from),BlackPieces);
  62.       temp=from+(bishop<<12);
  63.       while (moves) {
  64.         to=LastOne(moves);
  65.         *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  66.         Clear(to,moves);
  67.       }
  68.       Clear(from,piecebd);
  69.     }
  70. /*
  71.  ----------------------------------------------------------
  72. |                                                          |
  73. |   now, produce rook moves by cycling through the         |
  74. |   *_rook board to locate a [from] square and then        |
  75. |   generate the AttacksFrom() bitmap which supplies the   |
  76. |   list of valid <to> squares.                            |
  77. |                                                          |
  78.  ----------------------------------------------------------
  79. */
  80.     piecebd=WhiteRooks;
  81.     while (piecebd) {
  82.       from=LastOne(piecebd);
  83.       moves=And(AttacksRook(from),BlackPieces);
  84.       temp=from+(rook<<12);
  85.       while (moves) {
  86.         to=LastOne(moves);
  87.         *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  88.         Clear(to,moves);
  89.       }
  90.       Clear(from,piecebd);
  91.     }
  92. /*
  93.  ----------------------------------------------------------
  94. |                                                          |
  95. |   now, produce queen moves by cycling through the        |
  96. |   *_queen board to locate a [from] square and then       |
  97. |   generate the AttacksFrom() bitmap which supplies the   |
  98. |   list of valid <to> squares.                            |
  99. |                                                          |
  100.  ----------------------------------------------------------
  101. */
  102.     piecebd=WhiteQueens;
  103.     while (piecebd) {
  104.       from=LastOne(piecebd);
  105.       moves=And(AttacksQueen(from),BlackPieces);
  106.       temp=from+(queen<<12);
  107.       while (moves) {
  108.         to=LastOne(moves);
  109.         *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  110.         Clear(to,moves);
  111.       }
  112.       Clear(from,piecebd);
  113.     }
  114. /*
  115.  ----------------------------------------------------------
  116. |                                                          |
  117. |   now, produce king moves by cycling through the         |
  118. |   *_king board to locate a [from] square and then        |
  119. |   cycling through king_attacks[] to locate to squares    |
  120. |   that a king on [from] attacks.                         |
  121. |                                                          |
  122.  ----------------------------------------------------------
  123. */
  124.     from=WhiteKingSQ;
  125.     moves=And(king_attacks[from],BlackPieces);
  126.     temp=from+(king<<12);
  127.     while (moves) {
  128.       to=LastOne(moves);
  129.       *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  130.       Clear(to,moves);
  131.     }
  132. /*
  133.  ----------------------------------------------------------
  134. |                                                          |
  135. |   now, produce pawn moves.  this is done differently due |
  136. |   to inconsistencies in the way a pawn moves when it     |
  137. |   captures as opposed to normal non-capturing moves.     |
  138. |   another exception is capturing enpassant.  the first   |
  139. |   step is to generate all possible pawn promotions.  we  |
  140. |   do this by masking  all pawns but those on the 7th     |
  141. |   rank and then advancing them ahead if the square in    |
  142. |   front is empty.                                        |
  143. |                                                          |
  144.  ----------------------------------------------------------
  145. */
  146.     promotions=And(Shiftr(And(WhitePawns,rank_mask[RANK7]),8),Compl(Occupied));
  147.     while (promotions) {
  148.       to=LastOne(promotions);
  149.       *move++=(to-8)|(to<<6)|(pawn<<12)|(queen<<18);
  150.       Clear(to,promotions);
  151.     }
  152.  
  153.     target=Or(BlackPieces,EnPassantTarget(ply));
  154.     pcapturesl=And(Shiftr(And(WhitePawns,mask_left_edge),7),target);
  155.     while (pcapturesl) {
  156.       to=LastOne(pcapturesl);
  157.       if (to < 56) {
  158.         if(PieceOnSquare(to)) 
  159.           *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15);
  160.         else
  161.           *move++=(to-7)|(to<<6)|(pawn<<12)|(pawn<<15);
  162.       }
  163.       else 
  164.         *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(queen<<18);
  165.       Clear(to,pcapturesl);
  166.     }
  167.  
  168.     pcapturesr=And(Shiftr(And(WhitePawns,mask_right_edge),9),target);
  169.     while (pcapturesr) {
  170.       to=LastOne(pcapturesr);
  171.       if (to < 56) {
  172.         if(PieceOnSquare(to)) 
  173.           *move++=(to-9)|(to<<6)|(pawn<<12)|(-PieceOnSquare(to)<<15);
  174.         else
  175.           *move++=(to-9)|(to<<6)|(pawn<<12)|(pawn<<15);
  176.       }
  177.       else 
  178.         *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(queen<<18);
  179.       Clear(to,pcapturesr);
  180.     }
  181.   }
  182. /*
  183.  ----------------------------------------------------------
  184. |                                                          |
  185. |   now, produce knight moves by cycling through the       |
  186. |   *_knight board to locate a [from] square and then      |
  187. |   cycling through knight_attacks[] to locate to squares  |
  188. |   that a knight on [from] attacks.                       |
  189. |                                                          |
  190.  ----------------------------------------------------------
  191. */
  192.   else {
  193.     piecebd=BlackKnights;
  194.     while (piecebd) {
  195.       from=FirstOne(piecebd);
  196.       moves=And(knight_attacks[from],WhitePieces);
  197.       temp=from+(knight<<12);
  198.       while (moves) {
  199.         to=FirstOne(moves);
  200.         *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  201.         Clear(to,moves);
  202.       }
  203.       Clear(from,piecebd);
  204.     }
  205. /*
  206.  ----------------------------------------------------------
  207. |                                                          |
  208. |   now, produce bishop moves by cycling through the       |
  209. |   *_bishop board to locate a [from] square and then      |
  210. |   generate the AttacksFrom() bitmap which supplies the   |
  211. |   list of valid <to> squares.                            |
  212. |                                                          |
  213.  ----------------------------------------------------------
  214. */
  215.     piecebd=BlackBishops;
  216.     while (piecebd) {
  217.       from=FirstOne(piecebd);
  218.       moves=And(AttacksBishop(from),WhitePieces);
  219.       temp=from+(bishop<<12);
  220.       while (moves) {
  221.         to=FirstOne(moves);
  222.         *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  223.         Clear(to,moves);
  224.       }
  225.       Clear(from,piecebd);
  226.     }
  227. /*
  228.  ----------------------------------------------------------
  229. |                                                          |
  230. |   now, produce rook moves by cycling through the         |
  231. |   *_rook board to locate a [from] square and then        |
  232. |   generate the AttacksFrom() bitmap which supplies the   |
  233. |   list of valid <to> squares.                            |
  234. |                                                          |
  235.  ----------------------------------------------------------
  236. */
  237.     piecebd=BlackRooks;
  238.     while (piecebd) {
  239.       from=FirstOne(piecebd);
  240.       moves=And(AttacksRook(from),WhitePieces);
  241.       temp=from+(rook<<12);
  242.       while (moves) {
  243.         to=FirstOne(moves);
  244.         *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  245.         Clear(to,moves);
  246.       }
  247.       Clear(from,piecebd);
  248.     }
  249. /*
  250.  ----------------------------------------------------------
  251. |                                                          |
  252. |   now, produce queen moves by cycling through the        |
  253. |   *_queen board to locate a [from] square and then       |
  254. |   generate the AttacksFrom() bitmap which supplies the   |
  255. |   list of valid <to> squares.                            |
  256. |                                                          |
  257.  ----------------------------------------------------------
  258. */
  259.     piecebd=BlackQueens;
  260.     while (piecebd) {
  261.       from=FirstOne(piecebd);
  262.       moves=And(AttacksQueen(from),WhitePieces);
  263.       temp=from+(queen<<12);
  264.       while (moves) {
  265.         to=FirstOne(moves);
  266.         *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  267.         Clear(to,moves);
  268.       }
  269.       Clear(from,piecebd);
  270.     }
  271. /*
  272.  ----------------------------------------------------------
  273. |                                                          |
  274. |   now, produce king moves by cycling through the         |
  275. |   *_king board to locate a [from] square and then        |
  276. |   cycling through king_attacks[] to locate to squares    |
  277. |   that a king on [from] attacks.                         |
  278. |                                                          |
  279.  ----------------------------------------------------------
  280. */
  281.     from=BlackKingSQ;
  282.     moves=And(king_attacks[from],WhitePieces);
  283.     temp=from+(king<<12);
  284.     while (moves) {
  285.       to=FirstOne(moves);
  286.       *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  287.       Clear(to,moves);
  288.     }
  289. /*
  290.  ----------------------------------------------------------
  291. |                                                          |
  292. |   now, produce pawn moves.  this is done differently due |
  293. |   to inconsistencies in the way a pawn moves when it     |
  294. |   captures as opposed to normal non-capturing moves.     |
  295. |   another exception is capturing enpassant.  the first   |
  296. |   step is to generate all possible pawn promotions.  we  |
  297. |   do this by masking  all pawns but those on the 7th     |
  298. |   rank and then advancing them ahead if the square in    |
  299. |   front is empty.                                        |
  300. |                                                          |
  301.  ----------------------------------------------------------
  302. */
  303.     promotions=And(Shiftl(And(BlackPawns,rank_mask[RANK2]),8),
  304.                    Compl(Occupied));
  305.     while (promotions) {
  306.       to=FirstOne(promotions);
  307.       *move++=(to+8)|(to<<6)|(pawn<<12)|(queen<<18);
  308.       Clear(to,promotions);
  309.     }
  310.  
  311.     target=Or(WhitePieces,EnPassantTarget(ply));
  312.     pcapturesl=And(Shiftl(And(BlackPawns,mask_left_edge),9),target);
  313.     while (pcapturesl) {
  314.       to=FirstOne(pcapturesl);
  315.       if (to > 7) {
  316.         if(PieceOnSquare(to)) 
  317.           *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15);
  318.         else
  319.           *move++=(to+9)|(to<<6)|(pawn<<12)|(pawn<<15);
  320.       }
  321.       else
  322.         *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(queen<<18);
  323.       Clear(to,pcapturesl);
  324.     }
  325.  
  326.     pcapturesr=And(Shiftl(And(BlackPawns,mask_right_edge),7),target);
  327.     while (pcapturesr) {
  328.       to=FirstOne(pcapturesr);
  329.       if (to > 7) {
  330.         if(PieceOnSquare(to)) 
  331.           *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15);
  332.         else
  333.           *move++=(to+7)|(to<<6)|(pawn<<12)|(pawn<<15);
  334.       }
  335.       else
  336.         *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(queen<<18);
  337.       Clear(to,pcapturesr);
  338.     }
  339.   }
  340.   return(move);
  341. }
  342.  
  343. /* modified 01/11/96 */
  344. /*
  345. ********************************************************************************
  346. *                                                                              *
  347. *   GenerateCheckEvasions() is used to generate moves when the king is in      *
  348. *   check.                                                                     *
  349. *                                                                              *
  350. *   three types of check-evasion moves are generated:                          *
  351. *                                                                              *
  352. *   (1) generate king moves to squares that are not attacked by the opponent's *
  353. *   pieces.  this includes capture and non-capture moves.                      *
  354. *                                                                              *
  355. *   (2) generate interpositions along the rank/file that the checking attack   *
  356. *   is coming along (assuming (a) only one piece is checking the king, and     *
  357. *   (b) the checking piece is a sliding piece [bishop, rook, queen]).          *
  358. *                                                                              *
  359. *   (3) generate capture moves, but only to the square(s) that are giving      *
  360. *   check.  captures are a special case.  if there is one checking piece, then *
  361. *   capturing it by any piece is tried.  if there are two pieces checking the  *
  362. *   king, then the only legal capture to try is for the king to capture one of *
  363. *   the checking pieces that is on an un-attacked square.                      *
  364. *                                                                              *
  365. ********************************************************************************
  366. */
  367. int* GenerateCheckEvasions(TREE *tree, int ply, int wtm, int *move)
  368. {
  369.   register BITBOARD target, targetc, targetp, piecebd, moves;
  370.   register BITBOARD padvances1, padvances2, pcapturesl, pcapturesr;
  371.   register BITBOARD padvances1_all, empty, checksqs;
  372.   register int from, to, temp;
  373.   register int king_square, checkers, checking_square;
  374.   register int check_direction1=0, check_direction2=0;
  375.  
  376. /*
  377.  ----------------------------------------------------------
  378. |                                                          |
  379. |   first, determine how many pieces are attacking the     |
  380. |   king and where they are, so we can figure out how to   |
  381. |   legally get out of check.                              |
  382. |                                                          |
  383.  ----------------------------------------------------------
  384. */
  385.   if (wtm) {
  386.     king_square=WhiteKingSQ;
  387.     checksqs=And(AttacksTo(tree,king_square),BlackPieces);
  388.     checkers=PopCnt(checksqs);
  389.     if (checkers == 1) {
  390.       checking_square=FirstOne(And(AttacksTo(tree,king_square),
  391.                                     BlackPieces));
  392.       if (PieceOnSquare(checking_square) != -pawn)
  393.         check_direction1=directions[checking_square][king_square];
  394.       target=InterposeSquares(check_direction1,king_square,checking_square);
  395.       target=Or(target,And(AttacksTo(tree,king_square),BlackPieces));
  396.       target=Or(target,BlackKing);
  397.     }
  398.     else {
  399.       target=BlackKing;
  400.       checking_square=FirstOne(checksqs);
  401.       if (PieceOnSquare(checking_square) != -pawn)
  402.         check_direction1=directions[checking_square][king_square];
  403.       Clear(checking_square,checksqs);
  404.       checking_square=FirstOne(checksqs);
  405.       if (PieceOnSquare(checking_square) != -pawn)
  406.         check_direction2=directions[checking_square][king_square];
  407.     }
  408. /*
  409.  ----------------------------------------------------------
  410. |                                                          |
  411. |   the next step is to produce the set of valid           |
  412. |   destination squares.  for king moves, this is simply   |
  413. |   the set of squares that are not attacked by enemy      |
  414. |   pieces (if there are any such squares.)                |
  415. |                                                          |
  416. |   then, if the checking piece is not a knight, we need   |
  417. |   to know the checking direction so that we can either   |
  418. |   move the king "off" of that direction, or else "block" |
  419. |   that direction.                                        |
  420. |                                                          |
  421. |   first produce king moves by cycling through the        |
  422. |   *_king board to locate a [from] square and then        |
  423. |   cycling through attacks_to[] to locate to squares      |
  424. |   that the king on [from] attacks.                       |
  425. |                                                          |
  426.  ----------------------------------------------------------
  427. */
  428.     from=king_square;
  429.     moves=And(king_attacks[from],Compl(WhitePieces));
  430.     temp=from+(king<<12);
  431.     while (moves) {
  432.       to=LastOne(moves);
  433.       if (!Attacked(tree,to,0) && (directions[from][to] != check_direction1) &&
  434.                                  (directions[from][to] != check_direction2))
  435.         *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  436.       Clear(to,moves);
  437.     }
  438. /*
  439.  ----------------------------------------------------------
  440. |                                                          |
  441. |   now, produce knight moves by cycling through the       |
  442. |   *_knight board to locate a [from] square and then      |
  443. |   cycling through knight_attacks[] to locate to squares  |
  444. |   that a knight on [from] attacks.                       |
  445. |                                                          |
  446.  ----------------------------------------------------------
  447. */
  448.     if (checkers == 1) {
  449.       piecebd=WhiteKnights;
  450.       while (piecebd) {
  451.         from=LastOne(piecebd);
  452.         if (!PinnedOnKing(tree,wtm,from)) {
  453.           moves=And(knight_attacks[from],target);
  454.           temp=from+(knight<<12);
  455.           while (moves) {
  456.             to=LastOne(moves);
  457.             *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  458.             Clear(to,moves);
  459.           }
  460.         }
  461.         Clear(from,piecebd);
  462.       }
  463. /*
  464.  ----------------------------------------------------------
  465. |                                                          |
  466. |   now, produce bishop moves by cycling through the       |
  467. |   *_bishop board to locate a [from] square and then      |
  468. |   generate the AttacksFrom() bitmap which supplies the   |
  469. |   list of valid <to> squares.                            |
  470. |                                                          |
  471.  ----------------------------------------------------------
  472. */
  473.       piecebd=WhiteBishops;
  474.       while (piecebd) {
  475.         from=LastOne(piecebd);
  476.         if (!PinnedOnKing(tree,wtm,from)) {
  477.           moves=And(AttacksBishop(from),target);
  478.           temp=from+(bishop<<12);
  479.           while (moves) {
  480.             to=LastOne(moves);
  481.             *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  482.             Clear(to,moves);
  483.           }
  484.         }
  485.         Clear(from,piecebd);
  486.       }
  487. /*
  488.  ----------------------------------------------------------
  489. |                                                          |
  490. |   now, produce rook moves by cycling through the         |
  491. |   *_rook board to locate a [from] square and then        |
  492. |   generate the AttacksFrom() bitmap which supplies the   |
  493. |   list of valid <to> squares.                            |
  494. |                                                          |
  495.  ----------------------------------------------------------
  496. */
  497.       piecebd=WhiteRooks;
  498.       while (piecebd) {
  499.         from=LastOne(piecebd);
  500.         if (!PinnedOnKing(tree,wtm,from)) {
  501.           moves=And(AttacksRook(from),target);
  502.           temp=from+(rook<<12);
  503.           while (moves) {
  504.             to=LastOne(moves);
  505.             *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  506.             Clear(to,moves);
  507.           }
  508.         }
  509.         Clear(from,piecebd);
  510.       }
  511. /*
  512.  ----------------------------------------------------------
  513. |                                                          |
  514. |   now, produce queen moves by cycling through the        |
  515. |   *_queen board to locate a [from] square and then       |
  516. |   generate the AttacksFrom() bitmap which supplies the   |
  517. |   list of valid <to> squares.                            |
  518. |                                                          |
  519.  ----------------------------------------------------------
  520. */
  521.       piecebd=WhiteQueens;
  522.       while (piecebd) {
  523.         from=LastOne(piecebd);
  524.         if (!PinnedOnKing(tree,wtm,from)) {
  525.           moves=And(AttacksQueen(from),target);
  526.           temp=from+(queen<<12);
  527.           while (moves) {
  528.             to=LastOne(moves);
  529.             *move++=temp|(to<<6)|((-PieceOnSquare(to))<<15);
  530.             Clear(to,moves);
  531.           }
  532.         }
  533.         Clear(from,piecebd);
  534.       }
  535. /*
  536.  ----------------------------------------------------------
  537. |                                                          |
  538. |   now, produce pawn moves.  this is done differently due |
  539. |   to inconsistencies in the way a pawn moves when it     |
  540. |   captures as opposed to normal non-capturing moves.     |
  541. |   another exception is capturing enpassant.  the first   |
  542. |   step is to generate all possible pawn moves.  we do    |
  543. |   this in 2 operations:  (1) shift the pawns forward one |
  544. |   rank then and with empty squares;  (2) shift the pawns |
  545. |   forward two ranks and then and with empty squares.     |
  546. |                                                          |
  547.  ----------------------------------------------------------
  548. */
  549.       empty=Compl(Occupied);
  550.       targetp=And(target,empty);
  551.       padvances1=And(Shiftr(WhitePawns,8),targetp);
  552.       padvances1_all=And(Shiftr(WhitePawns,8),empty);
  553.       padvances2=And(Shiftr(And(padvances1_all,Shiftr(mask_8,16)),8),targetp);
  554. /*
  555.  ----------------------------------------------------------
  556. |                                                          |
  557. |   now that we got 'em, we simply enumerate the to        |
  558. |   squares as before, but in four steps since we have     |
  559. |   four sets of potential moves.                          |
  560. |                                                          |
  561.  ----------------------------------------------------------
  562. */
  563.       while (padvances2) {
  564.         to=LastOne(padvances2);
  565.         if (!PinnedOnKing(tree,wtm,to-16)) *move++=(to-16)|(to<<6)|(pawn<<12);
  566.         Clear(to,padvances2);
  567.       }
  568.       while (padvances1) {
  569.         to=LastOne(padvances1);
  570.         if (!PinnedOnKing(tree,wtm,to-8)) {
  571.           if (to < 56) *move++=(to-8)|(to<<6)|(pawn<<12);
  572.           else {
  573.             *move++=(to-8)|(to<<6)|(pawn<<12)|(queen<<18);
  574.             *move++=(to-8)|(to<<6)|(pawn<<12)|(rook<<18);
  575.             *move++=(to-8)|(to<<6)|(pawn<<12)|(bishop<<18);
  576.             *move++=(to-8)|(to<<6)|(pawn<<12)|(knight<<18);
  577.           }
  578.         }
  579.         Clear(to,padvances1);
  580.       }
  581.  
  582.       targetc=Or(BlackPieces,EnPassantTarget(ply));
  583.       targetc=And(targetc,target);
  584.       if (And(And(BlackPawns,target),Shiftl(EnPassantTarget(ply),8)))
  585.         targetc=Or(targetc,EnPassantTarget(ply));
  586.       pcapturesl=And(Shiftr(And(WhitePawns,mask_left_edge),7),targetc);
  587.       pcapturesr=And(Shiftr(And(WhitePawns,mask_right_edge),9),targetc);
  588.       while (pcapturesl) {
  589.         to=LastOne(pcapturesl);
  590.         if (!PinnedOnKing(tree,wtm,to-7)) {
  591.           if (to < 56) {
  592.             if(PieceOnSquare(to)) 
  593.               *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15);
  594.             else
  595.               *move++=(to-7)|(to<<6)|(pawn<<12)|(pawn<<15);
  596.           }
  597.           else {
  598.             *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(queen<<18);
  599.             *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(rook<<18);
  600.             *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(bishop<<18);
  601.             *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(knight<<18);
  602.           }
  603.         }
  604.         Clear(to,pcapturesl);
  605.       }
  606.       while (pcapturesr) {
  607.         to=LastOne(pcapturesr);
  608.         if (!PinnedOnKing(tree,wtm,to-9)) {
  609.           if (to < 56) {
  610.             if(PieceOnSquare(to)) 
  611.               *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15);
  612.             else
  613.               *move++=(to-9)|(to<<6)|(pawn<<12)|(pawn<<15);
  614.           }
  615.           else {
  616.             *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(queen<<18);
  617.             *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(rook<<18);
  618.             *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(bishop<<18);
  619.             *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(knight<<18);
  620.           }
  621.         }
  622.         Clear(to,pcapturesr);
  623.       }
  624.     }
  625.   }
  626. /*
  627.  ----------------------------------------------------------
  628. |                                                          |
  629. |   first, determine how many pieces are attacking the     |
  630. |   king and where they are, so we can figure out how to   |
  631. |   legally get out of check.                              |
  632. |                                                          |
  633.  ----------------------------------------------------------
  634. */
  635.   else {
  636.     king_square=BlackKingSQ;
  637.     checksqs=And(AttacksTo(tree,king_square),WhitePieces);
  638.     checkers=PopCnt(checksqs);
  639.     if (checkers == 1) {
  640.       checking_square=FirstOne(And(AttacksTo(tree,king_square),
  641.                                     WhitePieces));
  642.       if (PieceOnSquare(checking_square) != pawn)
  643.         check_direction1=directions[checking_square][king_square];
  644.       target=InterposeSquares(check_direction1,king_square,checking_square);
  645.       target=Or(target,And(AttacksTo(tree,king_square),WhitePieces));
  646.       target=Or(target,WhiteKing);
  647.     }
  648.     else {
  649.       target=WhiteKing;
  650.       checking_square=FirstOne(checksqs);
  651.       if (PieceOnSquare(checking_square) != pawn)
  652.         check_direction1=directions[checking_square][king_square];
  653.       Clear(checking_square,checksqs);
  654.       checking_square=FirstOne(checksqs);
  655.       if (PieceOnSquare(checking_square) != pawn)
  656.         check_direction2=directions[checking_square][king_square];
  657.     }
  658. /*
  659.  ----------------------------------------------------------
  660. |                                                          |
  661. |   the first step is to produce the set of valid          |
  662. |   destination squares.  for king moves, this is simply   |
  663. |   the set of squares that are not attacked by enemy      |
  664. |   pieces (if there are any such squares.)                |
  665. |                                                          |
  666. |   then, if the checking piece is not a knight, we need   |
  667. |   to know the checking direction so that we can either   |
  668. |   move the king "off" of that direction, or else "block" |
  669. |   that direction.                                        |
  670. |                                                          |
  671. |   first produce king moves by cycling through the        |
  672. |   *_king board to locate a [from] square and then        |
  673. |   cycling through attacks_to[] to locate to squares      |
  674. |   that the king on [from] attacks.                       |
  675. |                                                          |
  676.  ----------------------------------------------------------
  677. */
  678.     from=king_square;
  679.     moves=And(king_attacks[from],Compl(BlackPieces));
  680.     temp=from+(king<<12);
  681.     while (moves) {
  682.       to=FirstOne(moves);
  683.       if (!Attacked(tree,to,1) && (directions[from][to] != check_direction1) &&
  684.                                  (directions[from][to] != check_direction2))
  685.         *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  686.       Clear(to,moves);
  687.     }
  688. /*
  689.  ----------------------------------------------------------
  690. |                                                          |
  691. |   now, produce knight moves by cycling through the       |
  692. |   *_knight board to locate a [from] square and then      |
  693. |   cycling through knight_attacks[] to locate to squares  |
  694. |   that a knight on [from] attacks.                       |
  695. |                                                          |
  696.  ----------------------------------------------------------
  697. */
  698.     if (checkers == 1) {
  699.       piecebd=BlackKnights;
  700.       while (piecebd) {
  701.         from=FirstOne(piecebd);
  702.         if (!PinnedOnKing(tree,wtm,from)) {
  703.           moves=And(knight_attacks[from],target);
  704.           temp=from+(knight<<12);
  705.           while (moves) {
  706.             to=FirstOne(moves);
  707.             *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  708.             Clear(to,moves);
  709.           }
  710.         }
  711.         Clear(from,piecebd);
  712.       }
  713. /*
  714.  ----------------------------------------------------------
  715. |                                                          |
  716. |   now, produce bishop moves by cycling through the       |
  717. |   *_bishop board to locate a [from] square and then      |
  718. |   generate the AttacksFrom() bitmap which supplies the   |
  719. |   list of valid <to> squares.                            |
  720. |                                                          |
  721.  ----------------------------------------------------------
  722. */
  723.       piecebd=BlackBishops;
  724.       while (piecebd) {
  725.         from=FirstOne(piecebd);
  726.         if (!PinnedOnKing(tree,wtm,from)) {
  727.           moves=And(AttacksBishop(from),target);
  728.           temp=from+(bishop<<12);
  729.           while (moves) {
  730.             to=FirstOne(moves);
  731.             *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  732.             Clear(to,moves);
  733.           }
  734.         }
  735.         Clear(from,piecebd);
  736.       }
  737. /*
  738.  ----------------------------------------------------------
  739. |                                                          |
  740. |   now, produce rook moves by cycling through the         |
  741. |   *_rook board to locate a [from] square and then        |
  742. |   generate the AttacksFrom() bitmap which supplies the   |
  743. |   list of valid <to> squares.                            |
  744. |                                                          |
  745.  ----------------------------------------------------------
  746. */
  747.       piecebd=BlackRooks;
  748.       while (piecebd) {
  749.         from=FirstOne(piecebd);
  750.         if (!PinnedOnKing(tree,wtm,from)) {
  751.           moves=And(AttacksRook(from),target);
  752.           temp=from+(rook<<12);
  753.           while (moves) {
  754.             to=FirstOne(moves);
  755.             *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  756.             Clear(to,moves);
  757.           }
  758.         }
  759.         Clear(from,piecebd);
  760.       }
  761. /*
  762.  ----------------------------------------------------------
  763. |                                                          |
  764. |   now, produce queen moves by cycling through the        |
  765. |   *_queen board to locate a [from] square and then       |
  766. |                                                          |
  767.  ----------------------------------------------------------
  768. */
  769.       piecebd=BlackQueens;
  770.       while (piecebd) {
  771.         from=FirstOne(piecebd);
  772.         if (!PinnedOnKing(tree,wtm,from)) {
  773.           moves=And(AttacksQueen(from),target);
  774.           temp=from+(queen<<12);
  775.           while (moves) {
  776.             to=FirstOne(moves);
  777.             *move++=temp|(to<<6)|(PieceOnSquare(to)<<15);
  778.             Clear(to,moves);
  779.           }
  780.         }
  781.         Clear(from,piecebd);
  782.       }
  783. /*
  784.  ----------------------------------------------------------
  785. |                                                          |
  786. |   now, produce pawn moves.  this is done differently due |
  787. |   to inconsistencies in the way a pawn moves when it     |
  788. |   captures as opposed to normal non-capturing moves.     |
  789. |   another exception is capturing enpassant.  the first   |
  790. |   step is to generate all possible pawn moves.  we do    |
  791. |   this in 4 operations:  (1) shift the pawns forward one |
  792. |   rank then and with empty squares;  (2) shift the pawns |
  793. |   forward two ranks and then and with empty squares;     |
  794. |   (3) remove the a-pawn(s) then shift the pawns          |
  795. |   diagonally left then and with enemy occupied squares;  |
  796. |   (4) remove the h-pawn(s) then shift the pawns          |
  797. |   diagonally right then and with enemy occupied squares; |
  798. |   note that enemy occupied squares includes the special  |
  799. |   case of the enpassant target square also.              |
  800. |                                                          |
  801.  ----------------------------------------------------------
  802. */
  803.       empty=Compl(Occupied);
  804.       targetp=And(target,empty);
  805.       padvances1=And(Shiftl(BlackPawns,8),targetp);
  806.       padvances1_all=And(Shiftl(BlackPawns,8),empty);
  807.       padvances2=And(Shiftl(And(padvances1_all,Shiftl(mask_120,16)),8),targetp);
  808. /*
  809.  ----------------------------------------------------------
  810. |                                                          |
  811. |   now that we got 'em, we simply enumerate the to        |
  812. |   squares as before, but in four steps since we have     |
  813. |   four sets of potential moves.                          |
  814. |                                                          |
  815.  ----------------------------------------------------------
  816. */
  817.       while (padvances2) {
  818.         to=FirstOne(padvances2);
  819.         if (!PinnedOnKing(tree,wtm,to+16)) *move++=(to+16)|(to<<6)|(pawn<<12);
  820.         Clear(to,padvances2);
  821.       }
  822.       while (padvances1) {
  823.         to=FirstOne(padvances1);
  824.         if (!PinnedOnKing(tree,wtm,to+8)) {
  825.           if (to > 7) *move++=(to+8)|(to<<6)|(pawn<<12);
  826.           else {
  827.             *move++=(to+8)|(to<<6)|(pawn<<12)|(queen<<18);
  828.             *move++=(to+8)|(to<<6)|(pawn<<12)|(rook<<18);
  829.             *move++=(to+8)|(to<<6)|(pawn<<12)|(bishop<<18);
  830.             *move++=(to+8)|(to<<6)|(pawn<<12)|(knight<<18);
  831.           }
  832.         }
  833.         Clear(to,padvances1);
  834.       }
  835.  
  836.       targetc=Or(WhitePieces,EnPassantTarget(ply));
  837.       targetc=And(targetc,target);
  838.       if (And(And(WhitePawns,target),Shiftr(EnPassantTarget(ply),8)))
  839.         targetc=Or(targetc,EnPassantTarget(ply));
  840.       pcapturesl=And(Shiftl(And(BlackPawns,mask_left_edge),9),targetc);
  841.       pcapturesr=And(Shiftl(And(BlackPawns,mask_right_edge),7),targetc);
  842.       while (pcapturesl) {
  843.         to=FirstOne(pcapturesl);
  844.         if (!PinnedOnKing(tree,wtm,to+9)) {
  845.           if (to > 7) {
  846.             if(PieceOnSquare(to)) 
  847.               *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15);
  848.             else
  849.               *move++=(to+9)|(to<<6)|(pawn<<12)|(pawn<<15);
  850.           }
  851.           else {
  852.             *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(queen<<18);
  853.             *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(rook<<18);
  854.             *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(bishop<<18);
  855.             *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(knight<<18);
  856.           }
  857.         }
  858.         Clear(to,pcapturesl);
  859.       }
  860.       while (pcapturesr) {
  861.         to=FirstOne(pcapturesr);
  862.         if (!PinnedOnKing(tree,wtm,to+7)) {
  863.           if (to > 7) {
  864.             if(PieceOnSquare(to)) 
  865.               *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15);
  866.             else
  867.               *move++=(to+7)|(to<<6)|(pawn<<12)|(pawn<<15);
  868.           }
  869.           else {
  870.             *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(queen<<18);
  871.             *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(rook<<18);
  872.             *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(bishop<<18);
  873.             *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(knight<<18);
  874.           }
  875.         }
  876.         Clear(to,pcapturesr);
  877.       }
  878.     }
  879.   }
  880.   return(move);
  881. }
  882.  
  883. /* modified 03/11/97 */
  884. /*
  885. ********************************************************************************
  886. *                                                                              *
  887. *   GenerateMoves() is used to generate non-capture moves from the current     *
  888. *   position.                                                                  *
  889. *                                                                              *
  890. *   once the valid destination squares are known, we have to locate a friendly *
  891. *   piece to get a attacks_to[] entry.  we then produce the moves for this     *
  892. *   piece by using the source square as [from] and enumerating each square it  *
  893. *   attacks into [to].                                                         *
  894. *                                                                              *
  895. *   pawns are handled differently.  regular pawn moves are produced by         *
  896. *   shifting the pawn bitmap 8 bits "forward" and anding this with the         *
  897. *   complement of the occupied squares bitmap  double advances are then        *
  898. *   produced by anding the pawn bitmap with a mask containing 1's on the       *
  899. *   second rank, shifting this 16 bits "forward" and then anding this with     *
  900. *   the complement of the occupied squares bitmap as before.  if [to]          *
  901. *   reaches the 8th rank, we produce a set of four moves, promoting the pawn   *
  902. *   to knight, bishop, rook and queen.                                         *
  903. *                                                                              *
  904. ********************************************************************************
  905. */
  906. int* GenerateNonCaptures(TREE *tree, int ply, int wtm, int *move)
  907. {
  908.   register BITBOARD target, piecebd, moves;
  909.   register BITBOARD  padvances1, padvances2, pcapturesl, pcapturesr;
  910.   register int from, to, temp;
  911.  
  912.   if (wtm) {
  913. /*
  914.  ----------------------------------------------------------
  915. |                                                          |
  916. |   first, produce castling moves if it is legal.          |
  917. |                                                          |
  918.  ----------------------------------------------------------
  919. */
  920.     if (WhiteCastle(ply) > 0) {
  921.       if ((WhiteCastle(ply)&1) && !And(Occupied,Shiftr(mask_2,5)) &&
  922.           !Attacked(tree,E1,0) && !Attacked(tree,F1,0) && !Attacked(tree,G1,0)) {
  923.         *move++=12676;
  924.       }
  925.       if ((WhiteCastle(ply)&2) && !And(Occupied,Shiftr(mask_3,1)) &&
  926.           !Attacked(tree,C1,0) && !Attacked(tree,D1,0) && !Attacked(tree,E1,0)) {
  927.         *move++=12420;
  928.       }
  929.     }
  930. /*
  931.  ----------------------------------------------------------
  932. |                                                          |
  933. |   now, produce knight moves by cycling through the       |
  934. |   *_knight board to locate a [from] square and then      |
  935. |   cycling through knight_attacks[] to locate to squares  |
  936. |   that a knight on [from] attacks.                       |
  937. |                                                          |
  938.  ----------------------------------------------------------
  939. */
  940.     target=Compl(Occupied);
  941.     piecebd=WhiteKnights;
  942.     while (piecebd) {
  943.       from=LastOne(piecebd);
  944.       moves=And(knight_attacks[from],target);
  945.       temp=from+(knight<<12);
  946.       while (moves) {
  947.         to=LastOne(moves);
  948.         *move++=temp|(to<<6);
  949.         Clear(to,moves);
  950.       }
  951.       Clear(from,piecebd);
  952.     }
  953. /*
  954.  ----------------------------------------------------------
  955. |                                                          |
  956. |   now, produce bishop moves by cycling through the       |
  957. |   *_bishop board to locate a [from] square and then      |
  958. |   generate the AttacksFrom() bitmap which supplies the   |
  959. |   list of valid <to> squares.                            |
  960. |                                                          |
  961.  ----------------------------------------------------------
  962. */
  963.     piecebd=WhiteBishops;
  964.     while (piecebd) {
  965.       from=LastOne(piecebd);
  966.       moves=And(AttacksBishop(from),target);
  967.       temp=from+(bishop<<12);
  968.       while (moves) {
  969.         to=LastOne(moves);
  970.         *move++=temp|(to<<6);
  971.         Clear(to,moves);
  972.       }
  973.       Clear(from,piecebd);
  974.     }
  975. /*
  976.  ----------------------------------------------------------
  977. |                                                          |
  978. |   now, produce rook moves by cycling through the         |
  979. |   *_rook board to locate a [from] square and then        |
  980. |   generate the AttacksFrom() bitmap which supplies the   |
  981. |   list of valid <to> squares.                            |
  982. |                                                          |
  983.  ----------------------------------------------------------
  984. */
  985.     piecebd=WhiteRooks;
  986.     while (piecebd) {
  987.       from=LastOne(piecebd);
  988.       moves=And(AttacksRook(from),target);
  989.       temp=from+(rook<<12);
  990.       while (moves) {
  991.         to=LastOne(moves);
  992.         *move++=temp|(to<<6);
  993.         Clear(to,moves);
  994.       }
  995.       Clear(from,piecebd);
  996.     }
  997. /*
  998.  ----------------------------------------------------------
  999. |                                                          |
  1000. |   now, produce queen moves by cycling through the        |
  1001. |   *_queen board to locate a [from] square and then       |
  1002. |   generate the AttacksFrom() bitmap which supplies the   |
  1003. |   list of valid <to> squares.                            |
  1004. |                                                          |
  1005.  ----------------------------------------------------------
  1006. */
  1007.     piecebd=WhiteQueens;
  1008.     while (piecebd) {
  1009.       from=LastOne(piecebd);
  1010.       moves=And(AttacksQueen(from),target);
  1011.       temp=from+(queen<<12);
  1012.       while (moves) {
  1013.         to=LastOne(moves);
  1014.         *move++=temp|(to<<6);
  1015.         Clear(to,moves);
  1016.       }
  1017.       Clear(from,piecebd);
  1018.     }
  1019. /*
  1020.  ----------------------------------------------------------
  1021. |                                                          |
  1022. |   now, produce king moves by cycling through the         |
  1023. |   *_king board to locate a [from] square and then        |
  1024. |   cycling through king_attacks[] to locate to squares    |
  1025. |   that a king on [from] attacks.                         |
  1026. |                                                          |
  1027.  ----------------------------------------------------------
  1028. */
  1029.     from=WhiteKingSQ;
  1030.     moves=And(king_attacks[from],target);
  1031.     temp=from+(king<<12);
  1032.     while (moves) {
  1033.       to=LastOne(moves);
  1034.       *move++=temp|(to<<6);
  1035.       Clear(to,moves);
  1036.     }
  1037. /*
  1038.  ----------------------------------------------------------
  1039. |                                                          |
  1040. |   now, produce pawn moves.  this is done differently due |
  1041. |   to inconsistencies in the way a pawn moves when it     |
  1042. |   captures as opposed to normal non-capturing moves.     |
  1043. |   first we generate all possible pawn moves.  we do      |
  1044. |   this in 4 operations:  (1) shift the pawns forward one |
  1045. |   rank then and with empty squares;  (2) shift the pawns |
  1046. |   forward two ranks and then and with empty squares;     |
  1047. |   (3) remove the a-pawn(s) then shift the pawns          |
  1048. |   diagonally left then and with enemy occupied squares;  |
  1049. |   (4) remove the h-pawn(s) then shift the pawns          |
  1050. |   diagonally right then and with enemy occupied squares. |
  1051. |   note that the only captures produced are under-        |
  1052. |   promotions, because the rest were done in GenCap.      |
  1053. |                                                          |
  1054.  ----------------------------------------------------------
  1055. */
  1056.     padvances1=And(Shiftr(WhitePawns,8),target);
  1057.     padvances2=And(Shiftr(And(padvances1,mask_advance_2_w),8),target);
  1058. /*
  1059.  ----------------------------------------------------------
  1060. |                                                          |
  1061. |   now that we got 'em, we simply enumerate the to        |
  1062. |   squares as before, but in four steps since we have     |
  1063. |   four sets of potential moves.                          |
  1064. |                                                          |
  1065.  ----------------------------------------------------------
  1066. */
  1067.     while (padvances2) {
  1068.       to=LastOne(padvances2);
  1069.       *move++=(to-16)|(to<<6)|(pawn<<12);
  1070.       Clear(to,padvances2);
  1071.     }
  1072.  
  1073.     while (padvances1) {
  1074.       to=LastOne(padvances1);
  1075.       if (to < 56) *move++=(to-8)|(to<<6)|(pawn<<12);
  1076.       else {
  1077.         *move++=(to-8)|(to<<6)|(pawn<<12)|(rook<<18);
  1078.         *move++=(to-8)|(to<<6)|(pawn<<12)|(bishop<<18);
  1079.         *move++=(to-8)|(to<<6)|(pawn<<12)|(knight<<18);
  1080.       }
  1081.       Clear(to,padvances1);
  1082.     }
  1083.  
  1084.     target=And(BlackPieces,rank_mask[RANK8]);
  1085.     pcapturesl=And(Shiftr(And(WhitePawns,mask_left_edge),7),target);
  1086.     pcapturesr=And(Shiftr(And(WhitePawns,mask_right_edge),9),target);
  1087.     while (pcapturesl) {
  1088.       to=LastOne(pcapturesl);
  1089.       *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(rook<<18);
  1090.       *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(bishop<<18);
  1091.       *move++=(to-7)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(knight<<18);
  1092.       Clear(to,pcapturesl);
  1093.     }
  1094.     while (pcapturesr) {
  1095.       to=LastOne(pcapturesr);
  1096.       *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(rook<<18);
  1097.       *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(bishop<<18);
  1098.       *move++=(to-9)|(to<<6)|(pawn<<12)|((-PieceOnSquare(to))<<15)|(knight<<18);
  1099.       Clear(to,pcapturesr);
  1100.     }
  1101.   }
  1102. /*
  1103.  ----------------------------------------------------------
  1104. |                                                          |
  1105. |   first, produce castling moves if it is legal.          |
  1106. |                                                          |
  1107.  ----------------------------------------------------------
  1108. */
  1109.   else {
  1110.     if (BlackCastle(ply) > 0) {
  1111.       if ((BlackCastle(ply)&1) && !And(Occupied,Shiftr(mask_2,61)) &&
  1112.           !Attacked(tree,E8,1) && !Attacked(tree,F8,1) && !Attacked(tree,G8,1)) {
  1113.         *move++=16316;
  1114.       }
  1115.       if ((BlackCastle(ply)&2) && !And(Occupied,Shiftr(mask_3,57)) &&
  1116.           !Attacked(tree,C8,1) && !Attacked(tree,D8,1) && !Attacked(tree,E8,1)) {
  1117.         *move++=16060;
  1118.       }
  1119.     }
  1120. /*
  1121.  ----------------------------------------------------------
  1122. |                                                          |
  1123. |   now, produce knight moves by cycling through the       |
  1124. |   *_knight board to locate a [from] square and then      |
  1125. |   cycling through knight_attacks[] to locate to squares  |
  1126. |   that a knight on [from] attacks.                       |
  1127. |                                                          |
  1128.  ----------------------------------------------------------
  1129. */
  1130.     target=Compl(Occupied);
  1131.     piecebd=BlackKnights;
  1132.     while (piecebd) {
  1133.       from=FirstOne(piecebd);
  1134.       moves=And(knight_attacks[from],target);
  1135.       temp=from+(knight<<12);
  1136.       while (moves) {
  1137.         to=FirstOne(moves);
  1138.         *move++=temp|(to<<6);
  1139.         Clear(to,moves);
  1140.       }
  1141.       Clear(from,piecebd);
  1142.     }
  1143. /*
  1144.  ----------------------------------------------------------
  1145. |                                                          |
  1146. |   now, produce bishop moves by cycling through the       |
  1147. |   *_bishop board to locate a [from] square and then      |
  1148. |   generate the AttacksFrom() bitmap which supplies the   |
  1149. |   list of valid <to> squares.                            |
  1150. |                                                          |
  1151.  ----------------------------------------------------------
  1152. */
  1153.     piecebd=BlackBishops;
  1154.     while (piecebd) {
  1155.       from=FirstOne(piecebd);
  1156.       moves=And(AttacksBishop(from),target);
  1157.       temp=from+(bishop<<12);
  1158.       while (moves) {
  1159.         to=FirstOne(moves);
  1160.         *move++=temp|(to<<6);
  1161.         Clear(to,moves);
  1162.       }
  1163.       Clear(from,piecebd);
  1164.     }
  1165. /*
  1166.  ----------------------------------------------------------
  1167. |                                                          |
  1168. |   now, produce rook moves by cycling through the         |
  1169. |   *_rook board to locate a [from] square and then        |
  1170. |   generate the AttacksFrom() bitmap which supplies the   |
  1171. |   list of valid <to> squares.                            |
  1172. |                                                          |
  1173.  ----------------------------------------------------------
  1174. */
  1175.     piecebd=BlackRooks;
  1176.     while (piecebd) {
  1177.       from=FirstOne(piecebd);
  1178.       moves=And(AttacksRook(from),target);
  1179.       temp=from+(rook<<12);
  1180.       while (moves) {
  1181.         to=FirstOne(moves);
  1182.         *move++=temp|(to<<6);
  1183.         Clear(to,moves);
  1184.       }
  1185.       Clear(from,piecebd);
  1186.     }
  1187. /*
  1188.  ----------------------------------------------------------
  1189. |                                                          |
  1190. |   now, produce queen moves by cycling through the        |
  1191. |   *_queen board to locate a [from] square and then       |
  1192. |   generate the AttacksFrom() bitmap which supplies the   |
  1193. |   list of valid <to> squares.                            |
  1194. |                                                          |
  1195.  ----------------------------------------------------------
  1196. */
  1197.     piecebd=BlackQueens;
  1198.     while (piecebd) {
  1199.       from=FirstOne(piecebd);
  1200.       moves=And(AttacksQueen(from),target);
  1201.       temp=from+(queen<<12);
  1202.       while (moves) {
  1203.         to=FirstOne(moves);
  1204.         *move++=temp|(to<<6);
  1205.         Clear(to,moves);
  1206.       }
  1207.       Clear(from,piecebd);
  1208.     }
  1209. /*
  1210.  ----------------------------------------------------------
  1211. |                                                          |
  1212. |   now, produce king moves by cycling through the         |
  1213. |   *_king board to locate a [from] square and then        |
  1214. |   cycling through king_attacks[] to locate to squares    |
  1215. |   that a king on [from] attacks.                         |
  1216. |                                                          |
  1217.  ----------------------------------------------------------
  1218. */
  1219.     from=BlackKingSQ;
  1220.     moves=And(king_attacks[from],target);
  1221.     temp=from+(king<<12);
  1222.     while (moves) {
  1223.       to=FirstOne(moves);
  1224.       *move++=temp|(to<<6);
  1225.       Clear(to,moves);
  1226.     }
  1227. /*
  1228.  ----------------------------------------------------------
  1229. |                                                          |
  1230. |   now, produce pawn moves.  this is done differently due |
  1231. |   to inconsistencies in the way a pawn moves when it     |
  1232. |   captures as opposed to normal non-capturing moves.     |
  1233. |   first we generate all possible pawn moves.  we do      |
  1234. |   this in 4 operations:  (1) shift the pawns forward one |
  1235. |   rank then and with empty squares;  (2) shift the pawns |
  1236. |   forward two ranks and then and with empty squares;     |
  1237. |   (3) remove the a-pawn(s) then shift the pawns          |
  1238. |   diagonally left then and with enemy occupied squares;  |
  1239. |   (4) remove the h-pawn(s) then shift the pawns          |
  1240. |   diagonally right then and with enemy occupied squares. |
  1241. |   note that the only captures produced are under-        |
  1242. |   promotions, because the rest were done in GenCap.      |
  1243. |                                                          |
  1244.  ----------------------------------------------------------
  1245. */
  1246.     padvances1=And(Shiftl(BlackPawns,8),target);
  1247.     padvances2=And(Shiftl(And(padvances1,mask_advance_2_b),8),target);
  1248. /*
  1249.  ----------------------------------------------------------
  1250. |                                                          |
  1251. |   now that we got 'em, we simply enumerate the to        |
  1252. |   squares as before, but in four steps since we have     |
  1253. |   four sets of potential moves.                          |
  1254. |                                                          |
  1255.  ----------------------------------------------------------
  1256. */
  1257.     while (padvances2) {
  1258.       to=FirstOne(padvances2);
  1259.       *move++=(to+16)|(to<<6)|(pawn<<12);
  1260.       Clear(to,padvances2);
  1261.     }
  1262.     while (padvances1) {
  1263.       to=FirstOne(padvances1);
  1264.       if (to > 7) *move++=(to+8)|(to<<6)|(pawn<<12);
  1265.       else {
  1266.         *move++=(to+8)|(to<<6)|(pawn<<12)|(rook<<18);
  1267.         *move++=(to+8)|(to<<6)|(pawn<<12)|(bishop<<18);
  1268.         *move++=(to+8)|(to<<6)|(pawn<<12)|(knight<<18);
  1269.       }
  1270.       Clear(to,padvances1);
  1271.     }
  1272.     target=And(WhitePieces,rank_mask[RANK1]);
  1273.     pcapturesl=And(Shiftl(And(BlackPawns,mask_left_edge),9),target);
  1274.     pcapturesr=And(Shiftl(And(BlackPawns,mask_right_edge),7),target);
  1275.     while (pcapturesl) {
  1276.       to=FirstOne(pcapturesl);
  1277.       *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(rook<<18);
  1278.       *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(bishop<<18);
  1279.       *move++=(to+9)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(knight<<18);
  1280.       Clear(to,pcapturesl);
  1281.     }
  1282.     while (pcapturesr) {
  1283.       to=FirstOne(pcapturesr);
  1284.       *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(rook<<18);
  1285.       *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(bishop<<18);
  1286.       *move++=(to+7)|(to<<6)|(pawn<<12)|(PieceOnSquare(to)<<15)|(knight<<18);
  1287.       Clear(to,pcapturesr);
  1288.     }
  1289.   }
  1290.   return(move);
  1291. }
  1292.