Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.     Protector -- a UCI chess engine
  3.  
  4.     Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com)
  5.  
  6.     This program is free software: you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation, either version 3 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  
  19. */
  20.  
  21. /*
  22.    This module contains a bitboard-based chess move generator.
  23.  */
  24. #include <assert.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include "bitboard.h"
  29. #include "io.h"
  30.  
  31. #ifndef __builtin_popcountll // Pierre-Marie Baty -- __builtin_popcountll support for MSVC 32-bit
  32. int __builtin_popcountll (unsigned long long x) {
  33.    static const unsigned long long m1 = 0x5555555555555555; //binary: 0101...
  34.    static const unsigned long long m2 = 0x3333333333333333; //binary: 00110011..
  35.    static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...
  36.    static const unsigned long long h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
  37.    x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
  38.    x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
  39.    x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits
  40.    return (int)((x * h01) >> 56);  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
  41. }
  42. #endif // Pierre-Marie Baty -- __builtin_popcountll support for MSVC 32-bit
  43.  
  44. #ifndef __builtin_ctzll // Pierre-Marie Baty -- __builtin_ctzll support for MSVC 32-bit
  45. int __builtin_ctzll (unsigned long long x)
  46. {
  47.    // Returns the number of trailing 0-bits in x, starting at the least significant bit position.
  48.    // If x is zero, the result is undefined.
  49.    // This uses a binary search algorithm from Hacker's Delight.
  50.    int n = 1;
  51.    if ((x & 0x00000000FFFFFFFF) == 0) { n = n + 32; x = x >> 32; }
  52.    if ((x & 0x000000000000FFFF) == 0) { n = n + 16; x = x >> 16; }
  53.    if ((x & 0x00000000000000FF) == 0) { n = n + 8; x = x >> 8; }
  54.    if ((x & 0x000000000000000F) == 0) { n = n + 4; x = x >> 4; }
  55.    if ((x & 0x0000000000000003) == 0) { n = n + 2; x = x >> 2; }
  56.    return (n - (x & 1));
  57. }
  58. #endif // Pierre-Marie Baty -- __builtin_ctzll support for MSVC 32-bit
  59.  
  60. #ifndef __builtin_clzll // Pierre-Marie Baty -- __builtin_clzll support for MSVC 32-bit
  61. int __builtin_clzll (unsigned long long x)
  62. {
  63.    // Returns the number of leading 0-bits in x, starting at the most significant bit position.
  64.    // If x is zero, the result is undefined.
  65.    // This uses a binary search (counting down) algorithm from Hacker's Delight.
  66.    unsigned long long y;
  67.    int n = 64;
  68.    y = x >> 32; if (y != 0) { n = n - 32; x = y; }
  69.    y = x >> 16; if (y != 0) { n = n - 16; x = y; }
  70.    y = x >> 8; if (y != 0) { n = n - 8; x = y; }
  71.    y = x >> 4; if (y != 0) { n = n - 4; x = y; }
  72.    y = x >> 2; if (y != 0) { n = n - 2; x = y; }
  73.    y = x >> 1; if (y != 0) return (n - 2);
  74.    return (n - (int) x);
  75. }
  76. #endif // Pierre-Marie Baty -- __builtin_clzll support for MSVC 32-bit
  77.  
  78. #define offset(sq1,sq2) ( ( (sq2)-(sq1) ) / distance(sq1,sq2) )
  79.  
  80. /**
  81.  * Macros for internal use.
  82.  */
  83. #define HLANE(sq)    ( rank(sq) )
  84. #define HLANEBIT(sq) ( FILE_H - file(sq) )
  85. #define VLANE(sq)    ( file(sq) )
  86. #define VLANEBIT(sq) ( RANK_8 - rank(sq) )
  87. #define ULANE(sq)    ( file(sq) - rank(sq) + 7 )
  88. #define ULANEBIT(sq) ( RANK_8 - rank(sq) )
  89. #define DLANE(sq)    ( file(sq) + rank(sq) )
  90. #define DLANEBIT(sq) ( rank(sq) )
  91. #define HLANE_SQUARE(lane,bit) ( getSquare ( 7-(bit), (lane) ) )
  92. #define VLANE_SQUARE(lane,bit) ( getSquare ( (lane), 7-(bit) ) )
  93. #define ULANE_SQUARE(lane,bit) ( getSquare ( (lane)-(bit), 7-(bit) ) )
  94. #define DLANE_SQUARE(lane,bit) ( getSquare ( (lane)-(bit), (bit) ) )
  95.  
  96. static bool isInitialized = FALSE;
  97.  
  98. UINT64 minValue[_64_];
  99. UINT64 maxValue[_64_];
  100. INT8 highestBit[0x10000];
  101. INT8 lowestBit[0x10000];
  102. INT8 numSetBits[0x10000];
  103. UINT8 rankOverlay[0x10000];
  104. UINT8 bitshiftGap[8][256];
  105. int hLaneNumber[_64_], vLaneNumber[_64_];
  106. int uLaneNumber[_64_], dLaneNumber[_64_];
  107.  
  108. Bitboard generalMoves[0x0f][_64_];
  109.  
  110. /* *INDENT-OFF* */
  111. const Bitboard squaresOfFile[8] = {
  112.    0x0101010101010101llu,
  113.    0x0202020202020202llu,
  114.    0x0404040404040404llu,
  115.    0x0808080808080808llu,
  116.    0x1010101010101010llu,
  117.    0x2020202020202020llu,
  118.    0x4040404040404040llu,
  119.    0x8080808080808080llu
  120. };
  121. const Bitboard squaresOfRank[8] = {
  122.    0x00000000000000ffllu,
  123.    0x000000000000ff00llu,
  124.    0x0000000000ff0000llu,
  125.    0x00000000ff000000llu,
  126.    0x000000ff00000000llu,
  127.    0x0000ff0000000000llu,
  128.    0x00ff000000000000llu,
  129.    0xff00000000000000llu
  130. };
  131. const Bitboard squaresOfLateralFiles[8] = {
  132.    0x0202020202020202llu,
  133.    0x0505050505050505llu,
  134.    0x0a0a0a0a0a0a0a0allu,
  135.    0x1414141414141414llu,
  136.    0x2828282828282828llu,
  137.    0x5050505050505050llu,
  138.    0xa0a0a0a0a0a0a0a0llu,
  139.    0x4040404040404040llu
  140. };
  141. /* *INDENT-ON* */
  142.  
  143. Bitboard squaresOfFileRange[8][8];
  144. Bitboard squaresOfRankRange[8][8];
  145. Bitboard nonA, nonH, border, center, lightSquares, darkSquares, queenSide,
  146.    kingSide, centerFiles, extendedCenter;
  147. Bitboard squaresBehind[_64_][_64_];
  148. Bitboard squaresBetween[_64_][_64_];
  149. Bitboard squaresInDistance[8][_64_];
  150. Bitboard squaresInTaxiDistance[15][_64_];
  151. Bitboard squaresAbove[2][_64_];
  152. Bitboard squaresBelow[2][_64_];
  153. Bitboard squaresLeftOf[_64_];
  154. Bitboard squaresRightOf[_64_];
  155. Bitboard orthoKingAttackers[_64_];
  156. Bitboard diaKingAttackers[_64_];
  157. Bitboard knightKingAttackers[_64_];
  158. Bitboard pawnKingAttackers[2][_64_];
  159.  
  160. SquareLaneInfo squareLaneInfo[_64_];
  161. Bitboard hlane[_64_][256];
  162. Bitboard vlane[_64_][256];
  163. Bitboard ulane[_64_][256];
  164. Bitboard dlane[_64_][256];
  165. ObstacleSquareInfo obsi[_64_];
  166. Bitboard pawnMoves[2][_64_][256];
  167. Bitboard interestedPawns[2][_64_][256];
  168. Bitboard castlings[2][16][256];
  169. int castlingLane[] = { HLANE(E1), HLANE(E8) };
  170. Bitboard promotionCandidates[2];
  171. SetSquaresInfo setSquares[4][0x10000];
  172. Bitboard preMaskRook[64], preMaskBishop[64];
  173. Bitboard magicRookMoves[64][IMAX_ROOK];
  174. Bitboard magicBishopMoves[64][IMAX_BISHOP];
  175. MagicSquareInfoRook magicSquareInfoRook[64];
  176. MagicSquareInfoBishop magicSquareInfoBishop[64];
  177.  
  178. /* *INDENT-OFF* */
  179. const Bitboard magicRookNumber[64] = {
  180.    2341871876025885824llu, 5908793080399659264llu,
  181.    2814784401577026llu, 4755810071654563842llu,
  182.    4683749110191751172llu, 648520571176420352llu,
  183.    288793875996213508llu, 36039242390061312llu,
  184.    2233855853176307712llu, 360296835543278592llu,
  185.    37470368710784llu, 2261832991510528llu,
  186.    74595267411776576llu, 4612831726723531008llu,
  187.    17491104022660138llu, 9015996489662496llu,
  188.    164381455144716288llu, 4785426803991552llu,
  189.    2603080765009821794llu, 4504870937840771llu,
  190.    73202185810346241llu, 2594073935322554944llu,
  191.    577059170398781952llu, 687199551504llu,
  192.    36029072970620928llu, 4755818807417635204llu,
  193.    2305854279342097445llu, 4654506018003485187llu,
  194.    1369095394823243808llu, 1650609881216llu,
  195.    35189740863840llu, 17609634498592llu,
  196.    17867407885440llu, 1307170084179935305llu,
  197.    5224509820511455237llu, 30399366238175240llu,
  198.    685674177139050632llu, 4504708001565696llu,
  199.    576777574861506688llu, 2305843147759948801llu,
  200.    36046664624070657llu, 2305862800624326656llu,
  201.    35201686183936llu, 76563943050448912llu,
  202.    4828140284174931982llu, 93630429790212llu,
  203.    2305862800758624268llu, 4918212371161546978llu,
  204.    1197987317416064llu, 4629700452154347536llu,
  205.    144220742299427329llu, 1152928385211832832llu,
  206.    40132191457288llu, 9354573578272llu,
  207.    650209674406199320llu, 36029355649925192llu,
  208.    3470081245843620386llu, 9208682512641llu,
  209.    586664357648667141llu, 113161891886927874llu,
  210.    19144700892151826llu, 594756909391937601llu,
  211.    562958551810122llu, 1152922124158043138llu,
  212. };
  213.  
  214. const Bitboard magicBishopNumber[64] = {
  215.    2287018567549508llu, 20833559275112450llu,
  216.    1157535125460746242llu, 2343279465658384466llu,
  217.    182423557274534246llu, 91204498130747394llu,
  218.    79165240377360llu, 18024053647361153llu,
  219.    4756927389883318784llu, 2377974339296303121llu,
  220.    1529092243969llu, 18016872700051744llu,
  221.    1153204084472553600llu, 873698516757668385llu,
  222.    1125942867148800llu, 26423192526848llu,
  223.    289939073072784384llu, 10714208241454656llu,
  224.    2306405960274414104llu, 54114131212519426llu,
  225.    109212291534684230llu, 2306971108957557248llu,
  226.    288239189760215296llu, 166643228131737628llu,
  227.    3459894829004630016llu, 35193180131968llu,
  228.    576478344523031040llu, 1134696069202368llu,
  229.    298367873364066368llu, 2882596248975577091llu,
  230.    432437927499531776llu, 72621163549300482llu,
  231.    468396630660612192llu, 576812875222894592llu,
  232.    3463272528741531664llu, 2612123106223325312llu,
  233.    3242874314789487108llu, 3461016494560002066llu,
  234.    4539883779662384llu, 5909074606504807464llu,
  235.    4684333518172472324llu, 306280543752814656llu,
  236.    2345387698176llu, 293016142258114592llu,
  237.    5073215437209668llu, 79251277611040llu,
  238.    602532708688384llu, 20310252071682068llu,
  239.    4467607076866llu, 648573875995549696llu,
  240.    288232580007339520llu, 1188986585695191042llu,
  241.    9306611390751752llu, 5498105049088llu,
  242.    4625205909830770716llu, 1152994261659095304llu,
  243.    126118725618245632llu, 2305851875981395204llu,
  244.    351843796394505llu, 40532672078233696llu,
  245.    9009398294791225llu, 4611688257515749392llu,
  246.    1152930369572702464llu, 2306989456245202960llu,
  247. };
  248. /* *INDENT-ON* */
  249.  
  250. bool testSquare(const Bitboard bitboard, const Square square)
  251. {
  252.    return (bool) (((bitboard) & minValue[(square)]) != EMPTY_BITBOARD);
  253. }
  254.  
  255. /**
  256.  * Get the king moves for the specified square.
  257.  */
  258. Bitboard getKingMoves(const Square square)
  259. {
  260.    return generalMoves[KING][square];
  261. }
  262.  
  263. /**
  264.  * Get castling moves depending from the castling rights and
  265.  * the current position.
  266.  */
  267. Bitboard getCastlingMoves(const Color color, const BYTE castlingRights,
  268.                           const Bitboard obstacles)
  269. {
  270.    if (color == WHITE)
  271.    {
  272.       return castlings[WHITE][castlingRights][obstacles & 0xFF];
  273.    }
  274.    else
  275.    {
  276.       return castlings[BLACK][castlingRights][obstacles >> 56];
  277.    }
  278. }
  279.  
  280. /**
  281.  * Get the queen moves for the specified square.
  282.  */
  283. /*
  284.  Bitboard getQueenMoves(const Square square, const BYTE * obstacles)
  285. {
  286.    const ObstacleSquareInfo *_obsi = &obsi[square];
  287.  
  288.    return _obsi->hLane[obstacles[_obsi->hLaneNumber]] |
  289.       _obsi->vLane[obstacles[_obsi->vLaneNumber]] |
  290.       _obsi->uLane[obstacles[_obsi->uLaneNumber]] |
  291.       _obsi->dLane[obstacles[_obsi->dLaneNumber]];
  292. }
  293. */
  294.  
  295. int getWidth(const Bitboard set)
  296. {
  297.    if (set == EMPTY_BITBOARD)
  298.    {
  299.       return 0;
  300.    }
  301.    else
  302.    {
  303.       File leftMost = FILE_A, rightMost = FILE_H;
  304.  
  305.       while ((set & squaresOfFile[leftMost]) == EMPTY_BITBOARD)
  306.       {
  307.          leftMost++;
  308.       }
  309.  
  310.       while ((set & squaresOfFile[rightMost]) == EMPTY_BITBOARD)
  311.       {
  312.          rightMost--;
  313.       }
  314.  
  315.       return rightMost - leftMost;
  316.    }
  317. }
  318.  
  319. /**
  320.  * Get the queen moves for the specified square.
  321.  */
  322. Bitboard getMagicQueenMoves(const Square square, const Bitboard obstacles)
  323. {
  324.    MagicSquareInfoRook *msir = &magicSquareInfoRook[square];
  325.    MagicSquareInfoBishop *msib = &magicSquareInfoBishop[square];
  326.  
  327.    return
  328.       msir->moves[((obstacles & msir->preMask) * msir->magicNumber) >> 52] |
  329.       msib->moves[((obstacles & msib->preMask) * msib->magicNumber) >> 55];
  330. }
  331.  
  332. /**
  333.  * Get the rook moves for the specified square.
  334.  */
  335. Bitboard getRookMoves(const Square square, const BYTE * obstacles)
  336. {
  337.    const ObstacleSquareInfo *_obsi = &obsi[square];
  338.  
  339.    return _obsi->hLane[obstacles[_obsi->hLaneNumber]] |
  340.       _obsi->vLane[obstacles[_obsi->vLaneNumber]];
  341. }
  342.  
  343. /**
  344.  * Get the rook moves for the specified square.
  345.  */
  346. Bitboard getMagicRookMoves(const Square square, const Bitboard obstacles)
  347. {
  348.    MagicSquareInfoRook *msir = &magicSquareInfoRook[square];
  349.  
  350.    return
  351.       msir->moves[((obstacles & msir->preMask) * msir->magicNumber) >> 52];
  352. }
  353.  
  354. /**
  355.  * Get the bishop moves for the specified square.
  356.  */
  357. Bitboard getBishopMoves(const Square square, const BYTE * obstacles)
  358. {
  359.    const ObstacleSquareInfo *_obsi = &obsi[square];
  360.  
  361.    return _obsi->uLane[obstacles[_obsi->uLaneNumber]] |
  362.       _obsi->dLane[obstacles[_obsi->dLaneNumber]];
  363. }
  364.  
  365. /**
  366.  * Get the bishop moves for the specified square.
  367.  */
  368. Bitboard getMagicBishopMoves(const Square square, const Bitboard obstacles)
  369. {
  370.    MagicSquareInfoBishop *msib = &magicSquareInfoBishop[square];
  371.  
  372.    return
  373.       msib->moves[((obstacles & msib->preMask) * msib->magicNumber) >> 55];
  374. }
  375.  
  376. /**
  377.  * Get the knight moves for the specified square.
  378.  */
  379. Bitboard getKnightMoves(const Square square)
  380. {
  381.    return generalMoves[KNIGHT][square];
  382. }
  383.  
  384. /**
  385.  * Get the pawn captures for the specified square.
  386.  */
  387. Bitboard getPawnCaptures(const Piece piece, const Square square,
  388.                          const Bitboard allPieces)
  389. {
  390.    return generalMoves[piece][square] & allPieces;
  391. }
  392.  
  393. /**
  394.  * Get the pawn advances for the specified square.
  395.  */
  396. Bitboard getPawnAdvances(const Color color, const Square square,
  397.                          const Bitboard obstacles)
  398. {
  399.    Bitboard advances;
  400.  
  401.    if (color == WHITE)
  402.    {
  403.       advances = (minValue[square] << 8) & ~obstacles;
  404.  
  405.       if (rank(square) == RANK_2)
  406.       {
  407.          advances |= (advances << 8) & ~obstacles;
  408.       }
  409.    }
  410.    else
  411.    {
  412.       advances = (minValue[square] >> 8) & ~obstacles;
  413.  
  414.       if (rank(square) == RANK_7)
  415.       {
  416.          advances |= (advances >> 8) & ~obstacles;
  417.       }
  418.    }
  419.  
  420.    return advances;
  421. }
  422.  
  423. /**
  424.  * Get the pawns interested in advancing to the specified square.
  425.  */
  426. Bitboard getInterestedPawns(const Color color, const Square square,
  427.                             const Bitboard obstacles)
  428. {
  429.    Bitboard interestedPawns;
  430.  
  431.    if (color == WHITE)
  432.    {
  433.       interestedPawns = minValue[square] >> 8;
  434.  
  435.       if (rank(square) == RANK_4 &&
  436.           (interestedPawns & obstacles) == EMPTY_BITBOARD)
  437.       {
  438.          interestedPawns |= minValue[square] >> 16;
  439.       }
  440.    }
  441.    else
  442.    {
  443.       interestedPawns = minValue[square] << 8;
  444.  
  445.       if (rank(square) == RANK_5 &&
  446.           (interestedPawns & obstacles) == EMPTY_BITBOARD)
  447.       {
  448.          interestedPawns |= minValue[square] << 16;
  449.       }
  450.    }
  451.  
  452.    return interestedPawns;
  453. }
  454.  
  455. /**
  456.  * Get the squares between the two specified squares.
  457.  */
  458. Bitboard getSquaresBetween(const Square square1, const Square square2)
  459. {
  460.    return squaresBetween[square1][square2];
  461. }
  462.  
  463. /**
  464.  * Get the squares behind 'target', as seen from 'viewpoint'.
  465.  */
  466. Bitboard getSquaresBehind(const Square target, const Square viewpoint)
  467. {
  468.    return squaresBehind[target][viewpoint];
  469. }
  470.  
  471. /**
  472.  * Shift all set squares one file to the left.
  473.  */
  474. Bitboard shiftLeft(const Bitboard bitboard)
  475. {
  476.    return (bitboard & nonA) >> 1;
  477. }
  478.  
  479. /**
  480.  * Shift all set squares one file to the right.
  481.  */
  482. Bitboard shiftRight(const Bitboard bitboard)
  483. {
  484.    return (bitboard & nonH) << 1;
  485. }
  486.  
  487. /**
  488.  * Get all squares lateral to the specified squares.
  489.  */
  490. Bitboard getLateralSquares(const Bitboard squares)
  491. {
  492.    return ((squares & nonA) >> 1) | ((squares & nonH) << 1);
  493. }
  494.  
  495. /**
  496.  * Get the squares of the specified file.
  497.  */
  498. Bitboard getSquaresOfFile(const File file)
  499. {
  500.    return squaresOfFile[file];
  501. }
  502.  
  503. /**
  504.  * Get the squares of the specified rank.
  505.  */
  506. Bitboard getSquaresOfRank(const Rank rank)
  507. {
  508.    return squaresOfRank[rank];
  509. }
  510.  
  511. /**
  512.  * Get the number of set squares in the specified bitboard.
  513.  */
  514. int getNumberOfSetSquares(const Bitboard bitboard)
  515. {
  516.    return __builtin_popcountll(bitboard);
  517. }
  518.  
  519. /**
  520.  * Get the rank overlay of the specified bitboard.
  521.  */
  522. int getRankOverlay(const Bitboard bitboard)
  523. {
  524.    return rankOverlay[(bitboard) & UHEX_FFFF] |
  525.       rankOverlay[(bitboard >> 16) & UHEX_FFFF] |
  526.       rankOverlay[(bitboard >> 32) & UHEX_FFFF] |
  527.       rankOverlay[(bitboard >> 48) & UHEX_FFFF];
  528. }
  529.  
  530. /**
  531.  * Get the moves of the the specified piece.
  532.  */
  533. Bitboard getMoves(Square square, Piece piece, Bitboard allPieces)
  534. {
  535.    switch (pieceType(piece))
  536.    {
  537.    case PAWN:
  538.       return getPawnCaptures(piece, square, allPieces) |
  539.          getPawnAdvances(pieceColor(piece), square, allPieces);
  540.    case KING:
  541.       return getKingMoves(square);
  542.    case KNIGHT:
  543.       return getKnightMoves(square);
  544.    case ROOK:
  545.       return getMagicRookMoves(square, allPieces);
  546.    case BISHOP:
  547.       return getMagicBishopMoves(square, allPieces);
  548.    default:
  549.       return getMagicQueenMoves(square, allPieces);
  550.    }
  551. }
  552.  
  553. /**
  554.  * Get the capture moves of the the specified piece.
  555.  */
  556. Bitboard getCaptureMoves(Square square, Piece piece, Bitboard allPieces)
  557. {
  558.    switch (pieceType(piece))
  559.    {
  560.    case PAWN:
  561.       return getPawnCaptures(piece, square, allPieces);
  562.    case KING:
  563.       return getKingMoves(square);
  564.    case KNIGHT:
  565.       return getKnightMoves(square);
  566.    case ROOK:
  567.       return getMagicRookMoves(square, allPieces);
  568.    case BISHOP:
  569.       return getMagicBishopMoves(square, allPieces);
  570.    default:
  571.       return getMagicQueenMoves(square, allPieces);
  572.    }
  573. }
  574.  
  575. /**
  576.  * Set a square in the specified vector of obstacles.
  577.  */
  578. void setObstacleSquare(Square square, BYTE obstacles[NUM_LANES])
  579. {
  580.    SquareLaneInfo *sqi = &squareLaneInfo[square];
  581.  
  582.    obstacles[sqi->hLane] |= sqi->hLaneSetMask;
  583.    obstacles[sqi->vLane] |= sqi->vLaneSetMask;
  584.    obstacles[sqi->uLane] |= sqi->uLaneSetMask;
  585.    obstacles[sqi->dLane] |= sqi->dLaneSetMask;
  586. }
  587.  
  588. /**
  589.  * Clear a square in the specified vector of obstacles.
  590.  */
  591. void clearObstacleSquare(Square square, BYTE obstacles[NUM_LANES])
  592. {
  593.    SquareLaneInfo *sqi = &squareLaneInfo[square];
  594.  
  595.    obstacles[sqi->hLane] &= sqi->hLaneClearMask;
  596.    obstacles[sqi->vLane] &= sqi->vLaneClearMask;
  597.    obstacles[sqi->uLane] &= sqi->uLaneClearMask;
  598.    obstacles[sqi->dLane] &= sqi->dLaneClearMask;
  599. }
  600.  
  601. /**
  602.  * Calculate all obstacles according to the specified bitboard.
  603.  */
  604. void calculateObstacles(Bitboard board, BYTE obstacles[NUM_LANES])
  605. {
  606.    Square square;
  607.  
  608.    memset(obstacles, 0x00, NUM_LANES);
  609.  
  610.    ITERATE(square)
  611.    {
  612.       if (board & minValue[square])
  613.       {
  614.          setObstacleSquare(square, obstacles);
  615.       }
  616.    }
  617. }
  618.  
  619. /**
  620.  * Get the number of a set square and clear the corresponding bit.
  621.  *
  622.  * @return NO_SQUARE if no square was set.
  623.  */
  624. Square getLastSquare(Bitboard * vector);
  625.  
  626. /**
  627.  * Extend all set bits by one square into all directions.
  628.  */
  629. void floodBoard(Bitboard * board);
  630.  
  631. /**
  632.  * Get the targets of all pawns specified by 'whitePawns'.
  633.  */
  634. Bitboard getWhitePawnTargets(const Bitboard whitePawns)
  635. {
  636.    return ((whitePawns & nonA) << 7) | ((whitePawns & nonH) << 9);
  637. }
  638.  
  639. /**
  640.  * Get the targets of all pawns specified by 'blackPawns'.
  641.  */
  642. Bitboard getBlackPawnTargets(const Bitboard blackPawns)
  643. {
  644.    return ((blackPawns & nonA) >> 9) | ((blackPawns & nonH) >> 7);
  645. }
  646.  
  647. /**
  648.  * Iteration shortcuts
  649.  */
  650. #define ITERATE_BITBOARD(b,sq) while ( ( sq = getLastSquare(b) ) >= 0 )
  651.  
  652. void floodBoard(Bitboard * board)
  653. {
  654.    const Bitboard toLeft = *board & nonA, toRight = *board & nonH;
  655.  
  656.    *board = (toLeft >> 1) | (toLeft << 7) | (*board >> 8) | (toLeft >> 9) |
  657.       (toRight << 1) | (toRight >> 7) | (*board << 8) | (toRight << 9);
  658. }
  659.  
  660. Square getLastSquare(Bitboard * vector)
  661. {
  662.    if (*vector == EMPTY_BITBOARD)
  663.    {
  664.       return NO_SQUARE;
  665.    }
  666.    else
  667.    {
  668.       const int index = 63 - __builtin_clzll(*vector);
  669.  
  670.       *vector &= maxValue[index];
  671.  
  672.       return index;
  673.    }
  674. }
  675.  
  676. Square getFirstSquare(Bitboard * vector)
  677. {
  678.    if (*vector == EMPTY_BITBOARD)
  679.    {
  680.       return NO_SQUARE;
  681.    }
  682.    else
  683.    {
  684.       const int index = __builtin_ctzll(*vector);
  685.  
  686.       *vector &= maxValue[index];
  687.  
  688.       return index;
  689.    }
  690. }
  691.  
  692. int getSetSquares(const Bitboard board, UINT8 squares[_64_])
  693. {
  694.    int index;
  695.    UINT8 *currentSquare = &squares[0];
  696.  
  697.    if ((index = (int) (0xFFFF & board)) != 0)
  698.    {
  699.       const SetSquaresInfo *info = &setSquares[0][index];
  700.  
  701.       memcpy(currentSquare, info->setSquares, info->numSetSquares);
  702.       currentSquare += info->numSetSquares;
  703.    }
  704.  
  705.    if ((index = (int) (0xFFFF & (board >> 16))) != 0)
  706.    {
  707.       const SetSquaresInfo *info = &setSquares[1][index];
  708.  
  709.       memcpy(currentSquare, info->setSquares, info->numSetSquares);
  710.       currentSquare += info->numSetSquares;
  711.    }
  712.  
  713.    if ((index = (int) (0xFFFF & (board >> 32))) != 0)
  714.    {
  715.       const SetSquaresInfo *info = &setSquares[2][index];
  716.  
  717.       memcpy(currentSquare, info->setSquares, info->numSetSquares);
  718.       currentSquare += info->numSetSquares;
  719.    }
  720.  
  721.    if ((index = (int) (board >> 48)) != 0)
  722.    {
  723.       const SetSquaresInfo *info = &setSquares[3][index];
  724.  
  725.       memcpy(currentSquare, info->setSquares, info->numSetSquares);
  726.       currentSquare += info->numSetSquares;
  727.    }
  728.  
  729.    return (int) (currentSquare - &squares[0]);
  730. }
  731.  
  732. Bitboard getMultipleSquaresBetween(const Square origin, Bitboard targets)
  733. {
  734.    Bitboard squares = targets;
  735.    Square targetSquare;
  736.    Bitboard *sqb = &(squaresBetween[origin][0]);
  737.  
  738.    ITERATE_BITBOARD(&targets, targetSquare)
  739.    {
  740.       squares |= sqb[targetSquare];
  741.    }
  742.  
  743.    return squares;
  744. }
  745.  
  746. int getFloodValue(const Square origin, const Bitboard targets,
  747.                   const Bitboard permittedSquares)
  748. {
  749.    Bitboard floodedSquares = getKingMoves(origin) & permittedSquares;
  750.    Bitboard oldFloodedSquares = minValue[origin];
  751.    int numSteps = 1;
  752.  
  753.    while ((targets & floodedSquares) == EMPTY_BITBOARD &&
  754.           floodedSquares != oldFloodedSquares)
  755.    {
  756.       oldFloodedSquares = floodedSquares;
  757.       floodBoard(&floodedSquares);
  758.       floodedSquares |= oldFloodedSquares;
  759.       floodedSquares &= permittedSquares;
  760.       numSteps++;
  761.    }
  762.  
  763.    return numSteps;
  764. }
  765.  
  766. static void initializeKingMoves()
  767. {
  768.    int offset[] = { 1, -1, 7, -7, 8, -8, 9, -9 }, direction;
  769.    Square square;
  770.  
  771.    ITERATE(square)
  772.    {
  773.       for (direction = 0; direction < 8; direction++)
  774.       {
  775.          Square target = (Square) (square + offset[direction]);
  776.  
  777.          if (squareIsValid(target) && distance(square, target) == 1)
  778.          {
  779.             generalMoves[KING][square] |= minValue[target];
  780.          }
  781.       }
  782.    }
  783. }
  784.  
  785. static void initializeRookMoves()
  786. {
  787.    int offset[] = { 1, -1, 8, -8 }, direction, moveLength;
  788.    Square square;
  789.  
  790.    ITERATE(square)
  791.    {
  792.       for (direction = 0; direction < 4; direction++)
  793.       {
  794.          for (moveLength = 1; moveLength <= 7; moveLength++)
  795.          {
  796.             Square target =
  797.                (Square) (square + offset[direction] * moveLength);
  798.             bool sameFile = (bool) (file(square) == file(target));
  799.             bool sameRow = (bool) (rank(square) == rank(target));
  800.  
  801.             if (squareIsValid(target) && (sameFile || sameRow))
  802.             {
  803.                generalMoves[ROOK][square] |= minValue[target];
  804.             }
  805.             else
  806.             {
  807.                break;
  808.             }
  809.          }
  810.       }
  811.    }
  812. }
  813.  
  814. static void initializeBishopMoves()
  815. {
  816.    int offset[] = { 7, -7, 9, -9 }, direction, moveLength;
  817.    Square square;
  818.  
  819.    ITERATE(square)
  820.    {
  821.       for (direction = 0; direction < 4; direction++)
  822.       {
  823.          for (moveLength = 1; moveLength <= 7; moveLength++)
  824.          {
  825.             Square target =
  826.                (Square) (square + offset[direction] * moveLength);
  827.             int hDistance = horizontalDistance(square, target);
  828.             int vDistance = verticalDistance(square, target);
  829.  
  830.             if (squareIsValid(target) && hDistance == vDistance)
  831.             {
  832.                generalMoves[BISHOP][square] |= minValue[target];
  833.             }
  834.             else
  835.             {
  836.                break;
  837.             }
  838.          }
  839.       }
  840.    }
  841. }
  842.  
  843. static void initializeQueenMoves()
  844. {
  845.    Square square;
  846.  
  847.    ITERATE(square)
  848.    {
  849.       generalMoves[QUEEN][square] =
  850.          generalMoves[ROOK][square] | generalMoves[BISHOP][square];
  851.    }
  852. }
  853.  
  854. static void initializeKnightMoves()
  855. {
  856.    int offset[] = { 6, -6, 10, -10, 15, -15, 17, -17 }, direction;
  857.    Square square;
  858.  
  859.    ITERATE(square)
  860.    {
  861.       for (direction = 0; direction < 8; direction++)
  862.       {
  863.          Square target = (Square) (square + offset[direction]);
  864.  
  865.          if (squareIsValid(target) && distance(square, target) <= 2)
  866.          {
  867.             generalMoves[KNIGHT][square] |= minValue[target];
  868.          }
  869.       }
  870.    }
  871. }
  872.  
  873. static void initializePawnMoves()
  874. {
  875.    Square square;
  876.  
  877.    ITERATE(square)
  878.    {
  879.       if (file(square) != FILE_A)
  880.       {
  881.          if (square <= H8 - 7)
  882.          {
  883.             generalMoves[WHITE_PAWN][square] |= minValue[square + 7];
  884.          }
  885.  
  886.          if (square >= A1 + 9)
  887.          {
  888.             generalMoves[BLACK_PAWN][square] |= minValue[square - 9];
  889.          }
  890.       }
  891.  
  892.       if (file(square) != FILE_H)
  893.       {
  894.          if (square <= H8 - 9)
  895.          {
  896.             generalMoves[WHITE_PAWN][square] |= minValue[square + 9];
  897.          }
  898.  
  899.          if (square >= A1 + 7)
  900.          {
  901.             generalMoves[BLACK_PAWN][square] |= minValue[square - 7];
  902.          }
  903.       }
  904.    }
  905. }
  906.  
  907. static Bitboard calculateSquaresBehind(Square square, int offset)
  908. {
  909.    Bitboard squares = EMPTY_BITBOARD;
  910.  
  911.    for (square = (Square) (square + offset);
  912.         squareIsValid(square) &&
  913.         distance(square, (Square) (square - offset)) == 1;
  914.         square = (Square) (square + offset))
  915.    {
  916.       Bitboard mv = minValue[square];
  917.  
  918.       squares |= mv;
  919.    }
  920.  
  921.    return squares;
  922. }
  923.  
  924. static void initializeSquaresBehind()
  925. {
  926.    Square sq1, sq2;
  927.  
  928.    ITERATE(sq1)
  929.    {
  930.       Bitboard squares = generalMoves[QUEEN][sq1];
  931.  
  932.       ITERATE_BITBOARD(&squares, sq2)
  933.       {
  934.          int offset = offset(sq1, sq2);
  935.  
  936.          squaresBehind[sq2][sq1] = calculateSquaresBehind(sq2, offset);
  937.       }
  938.    }
  939. }
  940.  
  941. static Bitboard calculateSquaresBetween(Square sq1, Square sq2)
  942. {
  943.    Bitboard squares = EMPTY_BITBOARD;
  944.    int _offset = offset(sq1, sq2), square;
  945.  
  946.    for (square = sq1 + _offset; square != sq2; square += _offset)
  947.    {
  948.       squares |= minValue[square];
  949.    }
  950.  
  951.    return squares;
  952. }
  953.  
  954. static void initializeSquaresBetween()
  955. {
  956.    Square sq1, sq2;
  957.  
  958.    ITERATE(sq1)
  959.    {
  960.       Bitboard squares = generalMoves[QUEEN][sq1];
  961.  
  962.       ITERATE_BITBOARD(&squares, sq2)
  963.       {
  964.          squaresBetween[sq1][sq2] = calculateSquaresBetween(sq1, sq2);
  965.       }
  966.    }
  967. }
  968.  
  969. static void initializeSquareLaneInfo()
  970. {
  971.    Square square;
  972.  
  973.    ITERATE(square)
  974.    {
  975.       SquareLaneInfo *sqi = &squareLaneInfo[square];
  976.  
  977.       sqi->hLane = hLaneNumber[square] = HLANE(square);
  978.       sqi->hLaneSetMask = (BYTE) minValue[HLANEBIT(square)];
  979.       sqi->hLaneClearMask = (BYTE) ~ sqi->hLaneSetMask;
  980.  
  981.       sqi->vLane = vLaneNumber[square] = VLANE(square) + 8;
  982.       sqi->vLaneSetMask = (BYTE) minValue[VLANEBIT(square)];
  983.       sqi->vLaneClearMask = (BYTE) ~ sqi->vLaneSetMask;
  984.  
  985.       sqi->uLane = uLaneNumber[square] = ULANE(square) + 16;
  986.       sqi->uLaneSetMask = (BYTE) minValue[ULANEBIT(square)];
  987.       sqi->uLaneClearMask = (BYTE) ~ sqi->uLaneSetMask;
  988.  
  989.       sqi->dLane = dLaneNumber[square] = DLANE(square) + 31;
  990.       sqi->dLaneSetMask = (BYTE) minValue[DLANEBIT(square)];
  991.       sqi->dLaneClearMask = (BYTE) ~ sqi->dLaneSetMask;
  992.    }
  993. }
  994.  
  995. static Bitboard getHlaneVector(int lane, BYTE mask)
  996. {
  997.    int i;
  998.    Bitboard v = EMPTY_BITBOARD;
  999.  
  1000.    for (i = 0; i < 8; i++)
  1001.    {
  1002.       if (mask & minValue[i])
  1003.       {
  1004.          v |= minValue[7 - i];
  1005.       }
  1006.    }
  1007.  
  1008.    v <<= 8 * lane;
  1009.  
  1010.    return v;
  1011. }
  1012.  
  1013. static Bitboard getVlaneVector(int lane, BYTE mask)
  1014. {
  1015.    int i;
  1016.    Bitboard v = EMPTY_BITBOARD;
  1017.  
  1018.    for (i = 0; i < 8; i++)
  1019.    {
  1020.       if (mask & minValue[i])
  1021.       {
  1022.          v |= minValue[8 * (7 - i)];
  1023.       }
  1024.    }
  1025.  
  1026.    v <<= lane;
  1027.  
  1028.    return v;
  1029. }
  1030.  
  1031. static Bitboard getUlaneVector(int lane, BYTE mask)
  1032. {
  1033.    int i;
  1034.    Bitboard v = EMPTY_BITBOARD;
  1035.  
  1036.    for (i = 0; i < 8; i++)
  1037.    {
  1038.       v <<= 8;
  1039.  
  1040.       if (mask & minValue[i])
  1041.       {
  1042.          v |= minValue[7 - i];
  1043.       }
  1044.    }
  1045.  
  1046.    if (lane < 7)
  1047.    {
  1048.       for (i = lane; i < 7; i++)
  1049.       {
  1050.          v = (v & nonA) >> 1;
  1051.       }
  1052.    }
  1053.    else
  1054.    {
  1055.       for (i = lane; i > 7; i--)
  1056.       {
  1057.          v = (v & nonH) << 1;
  1058.       }
  1059.    }
  1060.  
  1061.    return v;
  1062. }
  1063.  
  1064. static Bitboard getDlaneVector(int lane, BYTE mask)
  1065. {
  1066.    int i;
  1067.    Bitboard v = EMPTY_BITBOARD;
  1068.  
  1069.    for (i = 0; i < 8; i++)
  1070.    {
  1071.       v <<= 8;
  1072.  
  1073.       if (mask & minValue[7 - i])
  1074.       {
  1075.          v |= minValue[i];
  1076.       }
  1077.    }
  1078.  
  1079.    if (lane < 7)
  1080.    {
  1081.       for (i = lane; i < 7; i++)
  1082.       {
  1083.          v = (v & nonA) >> 1;
  1084.       }
  1085.    }
  1086.    else
  1087.    {
  1088.       for (i = lane; i > 7; i--)
  1089.       {
  1090.          v = (v & nonH) << 1;
  1091.       }
  1092.    }
  1093.  
  1094.    return v;
  1095. }
  1096.  
  1097. static Bitboard getLaneMask(Square square, int offset,
  1098.                             Bitboard legalSquares, Bitboard obstacles)
  1099. {
  1100.    Bitboard laneMask = EMPTY_BITBOARD, mv = EMPTY_BITBOARD;
  1101.  
  1102.    while ((square = (Square) (square + offset)) >= A1 &&
  1103.           square <= H8 && ((mv = minValue[square]) & legalSquares))
  1104.    {
  1105.       laneMask |= mv;
  1106.  
  1107.       if (mv & obstacles)
  1108.       {
  1109.          break;
  1110.       }
  1111.    }
  1112.  
  1113.    return laneMask;
  1114. }
  1115.  
  1116. static Bitboard getHLaneMask(Square square, BYTE mask)
  1117. {
  1118.    int lane = HLANE(square);
  1119.    Bitboard legalSquares = getHlaneVector(lane, 255);
  1120.    Bitboard obstacles = getHlaneVector(lane, mask);
  1121.  
  1122.    Bitboard laneMask = getLaneMask(square, 1, legalSquares, obstacles);
  1123.  
  1124.    laneMask |= getLaneMask(square, -1, legalSquares, obstacles);
  1125.  
  1126.    return laneMask;
  1127. }
  1128.  
  1129. static Bitboard getVLaneMask(Square square, BYTE mask)
  1130. {
  1131.    int lane = VLANE(square);
  1132.    Bitboard legalSquares = getVlaneVector(lane, 255);
  1133.    Bitboard obstacles = getVlaneVector(lane, mask);
  1134.  
  1135.    Bitboard laneMask = getLaneMask(square, 8, legalSquares, obstacles);
  1136.  
  1137.    laneMask |= getLaneMask(square, -8, legalSquares, obstacles);
  1138.  
  1139.    return laneMask;
  1140. }
  1141.  
  1142. static Bitboard getULaneMask(Square square, BYTE mask)
  1143. {
  1144.    int lane = ULANE(square);
  1145.    Bitboard legalSquares = getUlaneVector(lane, 255);
  1146.    Bitboard obstacles = getUlaneVector(lane, mask);
  1147.  
  1148.    Bitboard laneMask = getLaneMask(square, 9, legalSquares, obstacles);
  1149.  
  1150.    laneMask |= getLaneMask(square, -9, legalSquares, obstacles);
  1151.  
  1152.    return laneMask;
  1153. }
  1154.  
  1155. static Bitboard getDLaneMask(Square square, BYTE mask)
  1156. {
  1157.    int lane = DLANE(square);
  1158.    Bitboard legalSquares = getDlaneVector(lane, 255);
  1159.    Bitboard obstacles = getDlaneVector(lane, mask);
  1160.  
  1161.    Bitboard laneMask = getLaneMask(square, 7, legalSquares, obstacles);
  1162.  
  1163.    laneMask |= getLaneMask(square, -7, legalSquares, obstacles);
  1164.  
  1165.    return laneMask;
  1166. }
  1167.  
  1168. static Bitboard getWhitePawnMoves(Square square, BYTE laneMask)
  1169. {
  1170.    int lane = VLANE(square);
  1171.    Bitboard moves = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
  1172.  
  1173.    if (square >= A2 && square <= H7 && (board & minValue[square + 8]) == 0)
  1174.    {
  1175.       moves |= minValue[square + 8];
  1176.  
  1177.       if (square <= H2 && (board & minValue[square + 16]) == 0)
  1178.       {
  1179.          moves |= minValue[square + 16];
  1180.       }
  1181.    }
  1182.  
  1183.    return moves;
  1184. }
  1185.  
  1186. static Bitboard getInterestedWhitePawns(Square square, BYTE laneMask)
  1187. {
  1188.    int lane = VLANE(square);
  1189.    Bitboard pawns = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
  1190.  
  1191.    if (square >= A3 && square <= H8 && (board & minValue[square]) == 0)
  1192.    {
  1193.       pawns |= minValue[square - 8];
  1194.  
  1195.       if (rank(square) == RANK_4 && (board & minValue[square - 8]) == 0)
  1196.       {
  1197.          pawns |= minValue[square - 16];
  1198.       }
  1199.    }
  1200.  
  1201.    return pawns;
  1202. }
  1203.  
  1204. static Bitboard getBlackPawnMoves(Square square, BYTE laneMask)
  1205. {
  1206.    int lane = VLANE(square);
  1207.    Bitboard moves = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
  1208.  
  1209.    if (square >= A2 && square <= H7 && (board & minValue[square - 8]) == 0)
  1210.    {
  1211.       moves |= minValue[square - 8];
  1212.  
  1213.       if (square >= A7 && (board & minValue[square - 16]) == 0)
  1214.       {
  1215.          moves |= minValue[square - 16];
  1216.       }
  1217.    }
  1218.  
  1219.    return moves;
  1220. }
  1221.  
  1222. static Bitboard getInterestedBlackPawns(Square square, BYTE laneMask)
  1223. {
  1224.    int lane = VLANE(square);
  1225.    Bitboard pawns = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
  1226.  
  1227.    if (square >= A1 && square <= H6 && (board & minValue[square]) == 0)
  1228.    {
  1229.       pawns |= minValue[square + 8];
  1230.  
  1231.       if (rank(square) == RANK_5 && (board & minValue[square + 8]) == 0)
  1232.       {
  1233.          pawns |= minValue[square + 16];
  1234.       }
  1235.    }
  1236.  
  1237.    return pawns;
  1238. }
  1239.  
  1240. static void initializeLaneMasks()
  1241. {
  1242.    Square square;
  1243.    int i;
  1244.  
  1245.    ITERATE(square)
  1246.    {
  1247.       for (i = 0; i <= 255; i++)
  1248.       {
  1249.          BYTE mask = (BYTE) i;
  1250.  
  1251.          hlane[square][i] = getHLaneMask(square, mask);
  1252.          vlane[square][i] = getVLaneMask(square, mask);
  1253.          ulane[square][i] = getULaneMask(square, mask);
  1254.          dlane[square][i] = getDLaneMask(square, mask);
  1255.          pawnMoves[WHITE][square][i] = getWhitePawnMoves(square, mask);
  1256.          pawnMoves[BLACK][square][i] = getBlackPawnMoves(square, mask);
  1257.          interestedPawns[WHITE][square][i] =
  1258.             getInterestedWhitePawns(square, mask);
  1259.          interestedPawns[BLACK][square][i] =
  1260.             getInterestedBlackPawns(square, mask);
  1261.       }
  1262.    }
  1263.  
  1264.    ITERATE(square)
  1265.    {
  1266.       int i;
  1267.  
  1268.       obsi[square].hLaneNumber = hLaneNumber[square];
  1269.       obsi[square].vLaneNumber = vLaneNumber[square];
  1270.       obsi[square].uLaneNumber = uLaneNumber[square];
  1271.       obsi[square].dLaneNumber = dLaneNumber[square];
  1272.  
  1273.       for (i = 0; i < 256; i++)
  1274.       {
  1275.          obsi[square].hLane[i] = hlane[square][i];
  1276.          obsi[square].vLane[i] = vlane[square][i];
  1277.          obsi[square].uLane[i] = ulane[square][i];
  1278.          obsi[square].dLane[i] = dlane[square][i];
  1279.       }
  1280.    }
  1281. }
  1282.  
  1283. static Bitboard getCastlings(const Bitboard obstacles)
  1284. {
  1285.    Bitboard castlings = EMPTY_BITBOARD;
  1286.  
  1287.    if ((obstacles & minValue[F1]) == EMPTY_BITBOARD &&
  1288.        (obstacles & minValue[G1]) == EMPTY_BITBOARD)
  1289.    {
  1290.       castlings |= minValue[G1];
  1291.    }
  1292.  
  1293.    if ((obstacles & minValue[B1]) == EMPTY_BITBOARD &&
  1294.        (obstacles & minValue[C1]) == EMPTY_BITBOARD &&
  1295.        (obstacles & minValue[D1]) == EMPTY_BITBOARD)
  1296.    {
  1297.       castlings |= minValue[C1];
  1298.    }
  1299.  
  1300.    return castlings;
  1301. }
  1302.  
  1303. static void initializeCastlings()
  1304. {
  1305.    int i, c;
  1306.  
  1307.    for (i = 0; i <= 255; i++)
  1308.    {
  1309.       BYTE mask = (BYTE) i;
  1310.       Bitboard moves = getCastlings((Bitboard) mask);
  1311.  
  1312.       for (c = 0; c <= 15; c++)
  1313.       {
  1314.          castlings[WHITE][c][mask] = castlings[BLACK][c][mask] = 0;
  1315.  
  1316.          if (moves & minValue[G1])
  1317.          {
  1318.             if (c & WHITE_00)
  1319.             {
  1320.                castlings[WHITE][c][mask] |= minValue[G1];
  1321.             }
  1322.  
  1323.             if (c & BLACK_00)
  1324.             {
  1325.                castlings[BLACK][c][mask] |= minValue[G8];
  1326.             }
  1327.          }
  1328.  
  1329.          if (moves & minValue[C1])
  1330.          {
  1331.             if (c & WHITE_000)
  1332.             {
  1333.                castlings[WHITE][c][mask] |= minValue[C1];
  1334.             }
  1335.  
  1336.             if (c & BLACK_000)
  1337.             {
  1338.                castlings[BLACK][c][mask] |= minValue[C8];
  1339.             }
  1340.          }
  1341.       }
  1342.    }
  1343. }
  1344.  
  1345. static INT8 _getNumberOfSetBits(INT32 v)
  1346. {
  1347.    int count = 0, i;
  1348.  
  1349.    for (i = 0; i < 16; i++)
  1350.    {
  1351.       count += (v >> i) & 1;
  1352.    }
  1353.  
  1354.    return (INT8) count;
  1355. }
  1356.  
  1357. static UINT8 _getRankOverlay(INT32 v)
  1358. {
  1359.    return (UINT8) ((v & 0xff) | ((v >> 8) & 0xff));
  1360. }
  1361.  
  1362. unsigned int getMinimumDistance(const Bitboard targets, const Square square)
  1363. {
  1364.    unsigned int distance;
  1365.  
  1366.    for (distance = 1; distance <= 7; distance++)
  1367.    {
  1368.       if ((squaresInDistance[distance][square] & targets) != EMPTY_BITBOARD)
  1369.       {
  1370.          return distance;
  1371.       }
  1372.    }
  1373.  
  1374.    return 0;
  1375. }
  1376.  
  1377. unsigned int getMaximumDistance(const Bitboard targets, const Square square)
  1378. {
  1379.    unsigned int distance;
  1380.  
  1381.    for (distance = 7; distance > 0; distance--)
  1382.    {
  1383.       if ((squaresInDistance[distance][square] & targets) != EMPTY_BITBOARD)
  1384.       {
  1385.          return distance;
  1386.       }
  1387.    }
  1388.  
  1389.    return 0;
  1390. }
  1391.  
  1392. static Bitboard getPremaskExclusions(const Square square)
  1393. {
  1394.    if (testSquare(border, square))
  1395.    {
  1396.       Bitboard exclusions = EMPTY_BITBOARD;
  1397.  
  1398.       if (testSquare(squaresOfFile[FILE_A], square) == FALSE)
  1399.       {
  1400.          exclusions |= squaresOfFile[FILE_A];
  1401.       }
  1402.  
  1403.       if (testSquare(squaresOfFile[FILE_H], square) == FALSE)
  1404.       {
  1405.          exclusions |= squaresOfFile[FILE_H];
  1406.       }
  1407.  
  1408.       if (testSquare(squaresOfRank[RANK_1], square) == FALSE)
  1409.       {
  1410.          exclusions |= squaresOfRank[RANK_1];
  1411.       }
  1412.  
  1413.       if (testSquare(squaresOfRank[RANK_8], square) == FALSE)
  1414.       {
  1415.          exclusions |= squaresOfRank[RANK_8];
  1416.       }
  1417.  
  1418.       return exclusions;
  1419.    }
  1420.    else
  1421.    {
  1422.       return border;
  1423.    }
  1424. }
  1425.  
  1426. static void initializePremasks()
  1427. {
  1428.    Square square;
  1429.  
  1430.    ITERATE(square)
  1431.    {
  1432.       preMaskRook[square] = generalMoves[WHITE_ROOK][square] &
  1433.          ~getPremaskExclusions(square);
  1434.       preMaskBishop[square] = generalMoves[WHITE_BISHOP][square] &
  1435.          ~getPremaskExclusions(square);
  1436.    }
  1437. }
  1438.  
  1439. static void initializeMagicRookMoves(const Square square)
  1440. {
  1441.    Square squareOfIndex[12];
  1442.    Bitboard allMoves = preMaskRook[square];
  1443.    const Bitboard premask = preMaskRook[square];
  1444.    int i, pieceSetup;
  1445.    Square sq1;
  1446.    BYTE obstacles[NUM_LANES];
  1447.    const Bitboard magicNumber = magicRookNumber[square];
  1448.  
  1449.    for (i = 0; i < IMAX_ROOK; i++)
  1450.    {
  1451.       magicRookMoves[square][i] = EMPTY_BITBOARD;
  1452.    }
  1453.  
  1454.    for (i = 0; i < 12; i++)
  1455.    {
  1456.       squareOfIndex[i] = NO_SQUARE;
  1457.    }
  1458.  
  1459.    i = 0;
  1460.  
  1461.    ITERATE_BITBOARD(&allMoves, sq1)
  1462.    {
  1463.       assert(i < 12);
  1464.  
  1465.       squareOfIndex[i++] = sq1;
  1466.    }
  1467.  
  1468.    for (pieceSetup = 0; pieceSetup < 4096; pieceSetup++)
  1469.    {
  1470.       Bitboard currentSetup = EMPTY_BITBOARD, effectiveMoves;
  1471.       int j = 1;
  1472.       Bitboard magicIndex;
  1473.  
  1474.       for (i = 0; i < 12 && squareOfIndex[i] != NO_SQUARE; i++)
  1475.       {
  1476.          if ((pieceSetup & j) != 0)
  1477.          {
  1478.             setSquare(currentSetup, squareOfIndex[i]);
  1479.          }
  1480.  
  1481.          j *= 2;
  1482.       }
  1483.  
  1484.       calculateObstacles(currentSetup, obstacles);
  1485.       effectiveMoves = getRookMoves(square, obstacles);
  1486.       magicIndex = ((currentSetup & premask) * magicNumber) >> 52;
  1487.       magicRookMoves[square][magicIndex] = effectiveMoves;
  1488.    }
  1489. }
  1490.  
  1491. static void initializeMagicBishopMoves(const Square square)
  1492. {
  1493.    Square squareOfIndex[12];
  1494.    Bitboard allMoves = preMaskBishop[square];
  1495.    const Bitboard premask = preMaskBishop[square];
  1496.    int i, pieceSetup;
  1497.    Square sq1;
  1498.    BYTE obstacles[NUM_LANES];
  1499.    const Bitboard magicNumber = magicBishopNumber[square];
  1500.  
  1501.    for (i = 0; i < IMAX_BISHOP; i++)
  1502.    {
  1503.       magicBishopMoves[square][i] = EMPTY_BITBOARD;
  1504.    }
  1505.  
  1506.    for (i = 0; i < 12; i++)
  1507.    {
  1508.       squareOfIndex[i] = NO_SQUARE;
  1509.    }
  1510.  
  1511.    i = 0;
  1512.  
  1513.    ITERATE_BITBOARD(&allMoves, sq1)
  1514.    {
  1515.       assert(i < 12);
  1516.  
  1517.       squareOfIndex[i++] = sq1;
  1518.    }
  1519.  
  1520.    for (pieceSetup = 0; pieceSetup < 4096; pieceSetup++)
  1521.    {
  1522.       Bitboard currentSetup = EMPTY_BITBOARD, effectiveMoves;
  1523.       int j = 1;
  1524.       Bitboard magicIndex;
  1525.  
  1526.       for (i = 0; i < 12 && squareOfIndex[i] != NO_SQUARE; i++)
  1527.       {
  1528.          if ((pieceSetup & j) != 0)
  1529.          {
  1530.             setSquare(currentSetup, squareOfIndex[i]);
  1531.          }
  1532.  
  1533.          j *= 2;
  1534.       }
  1535.  
  1536.       calculateObstacles(currentSetup, obstacles);
  1537.       effectiveMoves = getBishopMoves(square, obstacles);
  1538.       magicIndex = ((currentSetup & premask) * magicNumber) >> 55;
  1539.       magicBishopMoves[square][magicIndex] = effectiveMoves;
  1540.    }
  1541. }
  1542.  
  1543. /* #define GENERATE_MAGIC_NUMBERS */
  1544. #ifdef GENERATE_MAGIC_NUMBERS
  1545.  
  1546. #define IMAX 4096
  1547. #define BMAX 12
  1548. Bitboard collisions[IMAX];
  1549.  
  1550. static bool testMagicNumber(const Bitboard magicNumber, const Square square,
  1551.                             const bool rookMoves)
  1552. {
  1553.    Square squareOfIndex[BMAX];
  1554.    const Bitboard premask =
  1555.       (rookMoves ? preMaskRook[square] : preMaskBishop[square]);
  1556.    Bitboard allMoves = premask;
  1557.    int i, pieceSetup;
  1558.    Square sq1;
  1559.    BYTE obstacles[NUM_LANES];
  1560.  
  1561.    for (i = 0; i < IMAX; i++)
  1562.    {
  1563.       collisions[i] = EMPTY_BITBOARD;
  1564.    }
  1565.  
  1566.    for (i = 0; i < BMAX; i++)
  1567.    {
  1568.       squareOfIndex[i] = NO_SQUARE;
  1569.    }
  1570.  
  1571.    i = 0;
  1572.  
  1573.    ITERATE_BITBOARD(&allMoves, sq1)
  1574.    {
  1575.       assert(i < BMAX);
  1576.  
  1577.       squareOfIndex[i++] = sq1;
  1578.    }
  1579.  
  1580.    for (pieceSetup = 0; pieceSetup < IMAX; pieceSetup++)
  1581.    {
  1582.       Bitboard currentSetup = EMPTY_BITBOARD, effectiveMoves, calcBase;
  1583.       int j = 1;
  1584.       Bitboard magicIndex;
  1585.       const int shift = (rookMoves ? 64 - 12 : 64 - 9);
  1586.  
  1587.       for (i = 0; i < BMAX && squareOfIndex[i] != NO_SQUARE; i++)
  1588.       {
  1589.          if ((pieceSetup & j) != 0)
  1590.          {
  1591.             setSquare(currentSetup, squareOfIndex[i]);
  1592.          }
  1593.  
  1594.          j *= 2;
  1595.       }
  1596.  
  1597.       calculateObstacles(currentSetup, obstacles);
  1598.       effectiveMoves =
  1599.          (rookMoves ? getRookMoves(square, obstacles) :
  1600.           getBishopMoves(square, obstacles));
  1601.       calcBase = currentSetup & premask;
  1602.       magicIndex = (calcBase * magicNumber) >> shift;
  1603.  
  1604.       if (collisions[magicIndex] == EMPTY_BITBOARD)
  1605.       {
  1606.          collisions[magicIndex] = effectiveMoves;
  1607.       }
  1608.       else
  1609.       {
  1610.          if (effectiveMoves != collisions[magicIndex])
  1611.          {
  1612.             return FALSE;       /* severe collision -> magic number not suitable */
  1613.          }
  1614.       }
  1615.    }
  1616.  
  1617.    return TRUE;                 /* the given magic number is valid */
  1618. }
  1619.  
  1620. static UINT64 get64bitRandom()
  1621. {
  1622.    const UINT64 limit = (RAND_MAX * 13) / 100;
  1623.    UINT64 rn = 0, runningOne = 1;
  1624.    int i;
  1625.  
  1626.    for (i = 0; i < 64; i++)
  1627.    {
  1628.       if (rand() <= limit)
  1629.       {
  1630.          rn |= runningOne;
  1631.       }
  1632.  
  1633.       runningOne *= 2;
  1634.    }
  1635.  
  1636.    return rn;
  1637. }
  1638.  
  1639. static void calculateMagicNumbers()
  1640. {
  1641.    Square square;
  1642.  
  1643.    printf("{");
  1644.  
  1645.    ITERATE(square)
  1646.    {
  1647.       Bitboard magicNumber = get64bitRandom();
  1648.  
  1649.       while (testMagicNumber(magicNumber, square, TRUE) == FALSE)
  1650.       {
  1651.          magicNumber = get64bitRandom();
  1652.       }
  1653.  
  1654.       printf("%llu, ", magicNumber);
  1655.  
  1656.       if ((square % 2) == 1)
  1657.       {
  1658.          printf("\n");
  1659.       }
  1660.    }
  1661.  
  1662.    printf("};\n{");
  1663.  
  1664.    ITERATE(square)
  1665.    {
  1666.       Bitboard magicNumber = get64bitRandom();
  1667.  
  1668.       while (testMagicNumber(magicNumber, square, FALSE) == FALSE)
  1669.       {
  1670.          magicNumber = get64bitRandom();
  1671.       }
  1672.  
  1673.       printf("%llu, ", magicNumber);
  1674.  
  1675.       if ((square % 2) == 1)
  1676.       {
  1677.          printf("\n");
  1678.       }
  1679.    }
  1680.  
  1681.    printf("};\n");
  1682.    getKeyStroke();
  1683. }
  1684.  
  1685. #endif /* GENREATE_MAGIC_NUMBERS */
  1686.  
  1687. Bitboard getFlippedBitboard(Bitboard original)
  1688. {
  1689.    Bitboard flipped = EMPTY_BITBOARD;
  1690.    Square square;
  1691.  
  1692.    ITERATE_BITBOARD(&original, square)
  1693.    {
  1694.       setSquare(flipped, getFlippedSquare(square));
  1695.    }
  1696.  
  1697.    return flipped;
  1698. }
  1699.  
  1700. int initializeModuleBitboard()
  1701. {
  1702.    INT32 i;
  1703.    UINT32 j;
  1704.    INT8 k, indexLow, indexHigh;
  1705.    UINT64 min = 1;
  1706.    Square square;
  1707.  
  1708.    if (isInitialized)
  1709.    {
  1710.       return 0;
  1711.    }
  1712.    else
  1713.    {
  1714.       isInitialized = TRUE;
  1715.    }
  1716.  
  1717.    ITERATE(i)
  1718.    {
  1719.       minValue[i] = min;
  1720.       maxValue[i] = ~min;
  1721.  
  1722.       min *= 2;
  1723.    }
  1724.  
  1725.    lowestBit[0] = highestBit[0] = NO_SQUARE;
  1726.    numSetBits[0] = rankOverlay[0] = 0;
  1727.  
  1728.    for (i = 1; i <= 0xffffL; i++)
  1729.    {
  1730.       numSetBits[i] = _getNumberOfSetBits(i);
  1731.       rankOverlay[i] = _getRankOverlay(i);
  1732.  
  1733.       j = i;
  1734.       indexLow = indexHigh = NO_SQUARE;
  1735.  
  1736.       for (k = 0x00; k <= 0x0f; k++)
  1737.       {
  1738.          if ((j & 1) == 1)
  1739.          {
  1740.             if (indexLow == NO_SQUARE)
  1741.             {
  1742.                indexLow = k;
  1743.             }
  1744.  
  1745.             indexHigh = k;
  1746.          }
  1747.  
  1748.          j >>= 1;
  1749.       }
  1750.  
  1751.       lowestBit[i] = indexLow;
  1752.       highestBit[i] = indexHigh;
  1753.    }
  1754.  
  1755.    ITERATE(square)
  1756.    {
  1757.       int distance;
  1758.  
  1759.       if (squareColor(square) == DARK)
  1760.       {
  1761.          setSquare(darkSquares, square);
  1762.          clearSquare(lightSquares, square);
  1763.       }
  1764.       else
  1765.       {
  1766.          clearSquare(darkSquares, square);
  1767.          setSquare(lightSquares, square);
  1768.       }
  1769.  
  1770.       for (distance = 0; distance <= 7; distance++)
  1771.       {
  1772.          Square square2;
  1773.  
  1774.          squaresInDistance[distance][square] = EMPTY_BITBOARD;
  1775.  
  1776.          ITERATE(square2)
  1777.          {
  1778.             if (distance(square, square2) <= distance)
  1779.             {
  1780.                setSquare(squaresInDistance[distance][square], square2);
  1781.             }
  1782.          }
  1783.       }
  1784.  
  1785.       for (distance = 0; distance <= 14; distance++)
  1786.       {
  1787.          Square square2;
  1788.  
  1789.          squaresInTaxiDistance[distance][square] = EMPTY_BITBOARD;
  1790.  
  1791.          ITERATE(square2)
  1792.          {
  1793.             if (taxiDistance(square, square2) <= distance)
  1794.             {
  1795.                setSquare(squaresInTaxiDistance[distance][square], square2);
  1796.             }
  1797.          }
  1798.       }
  1799.    }
  1800.  
  1801.    for (i = FILE_A; i <= FILE_H; i++)
  1802.    {
  1803.       int j;
  1804.  
  1805.       for (j = FILE_A; j <= FILE_H; j++)
  1806.       {
  1807.          int k;
  1808.  
  1809.          squaresOfFileRange[i][j] = squaresOfRankRange[i][j] = EMPTY_BITBOARD;
  1810.  
  1811.          for (k = FILE_A; k <= FILE_H; k++)
  1812.          {
  1813.             if ((k >= i && k <= j) || (k >= j && k <= i))
  1814.             {
  1815.                squaresOfFileRange[i][j] |= squaresOfFile[k];
  1816.                squaresOfRankRange[i][j] |= squaresOfRank[k];
  1817.             }
  1818.          }
  1819.       }
  1820.    }
  1821.  
  1822.    nonA = ~squaresOfFile[FILE_A], nonH = ~squaresOfFile[FILE_H];
  1823.    center = minValue[D4] | minValue[D5] | minValue[E4] | minValue[E5];
  1824.    extendedCenter =
  1825.       (squaresOfFile[FILE_C] | squaresOfFile[FILE_D] |
  1826.        squaresOfFile[FILE_E] | squaresOfFile[FILE_F]) &
  1827.       (squaresOfRank[RANK_3] | squaresOfRank[RANK_4] |
  1828.        squaresOfRank[RANK_5] | squaresOfRank[RANK_6]);
  1829.    border = squaresOfFile[FILE_A] | squaresOfFile[FILE_H] |
  1830.       squaresOfRank[RANK_1] | squaresOfRank[RANK_8];
  1831.    queenSide =
  1832.       squaresOfFile[FILE_A] | squaresOfFile[FILE_B] | squaresOfFile[FILE_C];
  1833.    kingSide =
  1834.       squaresOfFile[FILE_F] | squaresOfFile[FILE_G] | squaresOfFile[FILE_H];
  1835.    centerFiles = squaresOfFile[FILE_D] | squaresOfFile[FILE_E];
  1836.    promotionCandidates[WHITE] = squaresOfRank[RANK_7];
  1837.    promotionCandidates[BLACK] = squaresOfRank[RANK_2];
  1838.  
  1839.    initializeKingMoves();
  1840.    initializeRookMoves();
  1841.    initializeBishopMoves();
  1842.    initializeQueenMoves();
  1843.    initializeKnightMoves();
  1844.    initializePawnMoves();
  1845.    initializeSquaresBehind();
  1846.    initializeSquaresBetween();
  1847.    initializeSquareLaneInfo();
  1848.    initializeLaneMasks();
  1849.    initializeCastlings();
  1850.  
  1851.    ITERATE(square)
  1852.    {
  1853.       const Bitboard corona = generalMoves[KING][square];
  1854.       Square square2;
  1855.  
  1856.       orthoKingAttackers[square] = diaKingAttackers[square] =
  1857.          knightKingAttackers[square] = pawnKingAttackers[WHITE][square] =
  1858.          pawnKingAttackers[BLACK][square] = EMPTY_BITBOARD;
  1859.       squaresAbove[WHITE][square] = squaresAbove[BLACK][square] =
  1860.          squaresBelow[WHITE][square] = squaresBelow[BLACK][square] =
  1861.          squaresLeftOf[square] = squaresRightOf[square] = EMPTY_BITBOARD;
  1862.  
  1863.       ITERATE(square2)
  1864.       {
  1865.          const Bitboard orthoSquares = generalMoves[ROOK][square2];
  1866.          const Bitboard diaSquares = generalMoves[BISHOP][square2];
  1867.          const Bitboard knightSquares = generalMoves[KNIGHT][square2];
  1868.          const Bitboard whitePawnSquares = generalMoves[WHITE_PAWN][square2];
  1869.          const Bitboard blackPawnSquares = generalMoves[BLACK_PAWN][square2];
  1870.  
  1871.          if (square != square2 && (corona & orthoSquares) != EMPTY_BITBOARD &&
  1872.              taxiDistance(square, square2) > 1)
  1873.          {
  1874.             setSquare(orthoKingAttackers[square], square2);
  1875.          }
  1876.  
  1877.          if (square != square2 && (corona & diaSquares) != EMPTY_BITBOARD &&
  1878.              (distance(square, square2) > 1 ||
  1879.               taxiDistance(square, square2) != 2))
  1880.          {
  1881.             setSquare(diaKingAttackers[square], square2);
  1882.          }
  1883.  
  1884.          if (square != square2 &&
  1885.              (corona & knightSquares) != EMPTY_BITBOARD &&
  1886.              testSquare(knightSquares, square) == EMPTY_BITBOARD)
  1887.          {
  1888.             setSquare(knightKingAttackers[square], square2);
  1889.          }
  1890.  
  1891.          if (square != square2 &&
  1892.              (corona & whitePawnSquares) != EMPTY_BITBOARD &&
  1893.              testSquare(whitePawnSquares, square) == EMPTY_BITBOARD)
  1894.          {
  1895.             setSquare(pawnKingAttackers[WHITE][square], square2);
  1896.          }
  1897.  
  1898.          if (square != square2 &&
  1899.              (corona & blackPawnSquares) != EMPTY_BITBOARD &&
  1900.              testSquare(blackPawnSquares, square) == EMPTY_BITBOARD)
  1901.          {
  1902.             setSquare(pawnKingAttackers[BLACK][square], square2);
  1903.          }
  1904.  
  1905.          if (rank(square2) < rank(square))
  1906.          {
  1907.             setSquare(squaresBelow[WHITE][square], square2);
  1908.             setSquare(squaresAbove[BLACK][square], square2);
  1909.          }
  1910.  
  1911.          if (rank(square2) > rank(square))
  1912.          {
  1913.             setSquare(squaresAbove[WHITE][square], square2);
  1914.             setSquare(squaresBelow[BLACK][square], square2);
  1915.          }
  1916.  
  1917.          if (file(square2) < file(square))
  1918.          {
  1919.             setSquare(squaresLeftOf[square], square2);
  1920.          }
  1921.  
  1922.          if (file(square2) > file(square))
  1923.          {
  1924.             setSquare(squaresRightOf[square], square2);
  1925.          }
  1926.       }
  1927.    }
  1928.  
  1929.    for (i = 0; i < 256; i++)
  1930.    {
  1931.       for (j = 0; j < 8; j++)
  1932.       {
  1933.          bitshiftGap[j][i] = (i == 0 ? 0 : 8);
  1934.  
  1935.          for (k = 0; k < 8; k++)
  1936.          {
  1937.             if ((minValue[(int) k] & i) != 0
  1938.                 && abs(j - k) < bitshiftGap[j][i])
  1939.             {
  1940.                bitshiftGap[j][i] = (UINT8) abs(j - k);
  1941.             }
  1942.          }
  1943.       }
  1944.    }
  1945.  
  1946.    for (i = 0; i < 4; i++)
  1947.    {
  1948.       UINT64 bitMask;
  1949.  
  1950.       for (bitMask = 0; bitMask < 0x10000; bitMask++)
  1951.       {
  1952.          SetSquaresInfo *info = &setSquares[i][bitMask];
  1953.          Bitboard board = bitMask << (16 * i);
  1954.          Square square;
  1955.  
  1956.          info->numSetSquares = 0;
  1957.  
  1958.          ITERATE_BITBOARD(&board, square)
  1959.          {
  1960.             info->setSquares[info->numSetSquares++] = (UINT8) square;
  1961.          }
  1962.       }
  1963.    }
  1964.  
  1965.    initializePremasks();
  1966.  
  1967.    ITERATE(square)
  1968.    {
  1969.       initializeMagicRookMoves(square);
  1970.       initializeMagicBishopMoves(square);
  1971.    }
  1972.  
  1973.    ITERATE(square)
  1974.    {
  1975.       int i;
  1976.  
  1977.       magicSquareInfoRook[square].preMask = preMaskRook[square];
  1978.       magicSquareInfoRook[square].magicNumber = magicRookNumber[square];
  1979.  
  1980.       for (i = 0; i < IMAX_ROOK; i++)
  1981.       {
  1982.          magicSquareInfoRook[square].moves[i] = magicRookMoves[square][i];
  1983.       }
  1984.  
  1985.       magicSquareInfoBishop[square].preMask = preMaskBishop[square];
  1986.       magicSquareInfoBishop[square].magicNumber = magicBishopNumber[square];
  1987.  
  1988.       for (i = 0; i < IMAX_BISHOP; i++)
  1989.       {
  1990.          magicSquareInfoBishop[square].moves[i] = magicBishopMoves[square][i];
  1991.       }
  1992.    }
  1993.  
  1994.    /*
  1995.       for (i = 0; i < 8; i++)
  1996.       {
  1997.       logDebug("0x%016llx,\n", squaresOfLateralFiles[i]);
  1998.       }
  1999.  
  2000.       getKeyStroke();
  2001.     */
  2002.  
  2003. #ifdef GENERATE_MAGIC_NUMBERS
  2004.    calculateMagicNumbers();
  2005. #endif
  2006.  
  2007.    return 0;
  2008. }
  2009.  
  2010. #ifndef NDEBUG
  2011.  
  2012. static int testBitOperations()
  2013. {
  2014.    Bitboard b = EMPTY_BITBOARD;
  2015.  
  2016.    assert(testSquare(lightSquares, A1) == 0);
  2017.    assert(testSquare(lightSquares, B1));
  2018.    assert(testSquare(lightSquares, G8));
  2019.    assert(testSquare(lightSquares, H8) == 0);
  2020.  
  2021.    assert(testSquare(darkSquares, A1));
  2022.    assert(testSquare(darkSquares, B1) == 0);
  2023.    assert(testSquare(darkSquares, G8) == 0);
  2024.    assert(testSquare(darkSquares, H8));
  2025.  
  2026.    assert(highestBit[0x0f] == 3);
  2027.    assert(highestBit[0xffff] == 15);
  2028.    assert(numSetBits[0] == 0);
  2029.    assert(numSetBits[0x5555] == 8);
  2030.    assert(numSetBits[0xaaaa] == 8);
  2031.    assert(numSetBits[0xffff] == 16);
  2032.  
  2033.    assert(testSquare(b, D4) == 0);
  2034.    setSquare(b, D4);
  2035.    assert(testSquare(b, D4) != 0);
  2036.    clearSquare(b, D4);
  2037.    assert(testSquare(b, D4) == 0);
  2038.  
  2039.    assert(testSquare(b, H8) == 0);
  2040.    setSquare(b, H8);
  2041.    assert(testSquare(b, H8) != 0);
  2042.    clearSquare(b, H8);
  2043.    assert(testSquare(b, H8) == 0);
  2044.  
  2045.    assert(getLastSquare(&b) == NO_SQUARE);
  2046.    setSquare(b, H8);
  2047.    assert(getLastSquare(&b) == H8);
  2048.    assert(getLastSquare(&b) == NO_SQUARE);
  2049.  
  2050.    assert(testSquare(squaresBehind[D4][C3], E5));
  2051.    assert(testSquare(squaresBehind[D4][C3], F6));
  2052.    assert(testSquare(squaresBehind[D4][C3], G7));
  2053.    assert(testSquare(squaresBehind[D4][C3], H8));
  2054.    assert(getNumberOfSetSquares(squaresBehind[D4][C3]) == 4);
  2055.  
  2056.    assert(testSquare(squaresBetween[B3][F7], C4));
  2057.    assert(testSquare(squaresBetween[B3][F7], D5));
  2058.    assert(testSquare(squaresBetween[B3][F7], E6));
  2059.    assert(getNumberOfSetSquares(squaresBetween[B3][F7]) == 3);
  2060.  
  2061.    assert(rankOverlay[0x8143] == 0xC3);
  2062.  
  2063.    b = EMPTY_BITBOARD;
  2064.    setSquare(b, A4);
  2065.    setSquare(b, E1);
  2066.    setSquare(b, E8);
  2067.    setSquare(b, H7);
  2068.    assert(getRankOverlay(b) == 0x91);
  2069.  
  2070.    assert(testSquare(squaresInDistance[1][C3], C4) != FALSE);
  2071.    assert(testSquare(squaresInDistance[1][C3], C5) == FALSE);
  2072.    assert(testSquare(squaresInDistance[3][E5], E2) != FALSE);
  2073.    assert(testSquare(squaresInDistance[3][E5], E1) == FALSE);
  2074.    assert(testSquare(squaresInDistance[5][H8], C3) != FALSE);
  2075.    assert(testSquare(squaresInDistance[5][H8], B2) == FALSE);
  2076.  
  2077.    assert(bitshiftGap[5][0] == 0);
  2078.    assert(bitshiftGap[1][129] == 1);
  2079.    assert(bitshiftGap[4][129] == 3);
  2080.  
  2081.    return 0;
  2082. }
  2083.  
  2084. static int testGeneralMoves()
  2085. {
  2086.    assert(testSquare(generalMoves[KING][C3], C4));
  2087.    assert(testSquare(generalMoves[KING][C3], D4));
  2088.    assert(testSquare(generalMoves[KING][C3], D3));
  2089.    assert(testSquare(generalMoves[KING][C3], D2));
  2090.    assert(testSquare(generalMoves[KING][C3], C2));
  2091.    assert(testSquare(generalMoves[KING][C3], B2));
  2092.    assert(testSquare(generalMoves[KING][C3], B3));
  2093.    assert(testSquare(generalMoves[KING][C3], B4));
  2094.    assert(getNumberOfSetSquares(generalMoves[KING][C3]) == 8);
  2095.  
  2096.    assert(testSquare(generalMoves[ROOK][C3], C8));
  2097.    assert(testSquare(generalMoves[ROOK][C3], H3));
  2098.    assert(testSquare(generalMoves[ROOK][C3], C1));
  2099.    assert(testSquare(generalMoves[ROOK][C3], A3));
  2100.    assert(getNumberOfSetSquares(generalMoves[ROOK][C3]) == 14);
  2101.  
  2102.    assert(testSquare(generalMoves[BISHOP][C3], H8));
  2103.    assert(testSquare(generalMoves[BISHOP][C3], E1));
  2104.    assert(testSquare(generalMoves[BISHOP][C3], A1));
  2105.    assert(testSquare(generalMoves[BISHOP][C3], A5));
  2106.    assert(getNumberOfSetSquares(generalMoves[BISHOP][C3]) == 11);
  2107.  
  2108.    assert(testSquare(generalMoves[QUEEN][C3], C8));
  2109.    assert(testSquare(generalMoves[QUEEN][C3], H8));
  2110.    assert(testSquare(generalMoves[QUEEN][C3], H3));
  2111.    assert(testSquare(generalMoves[QUEEN][C3], E1));
  2112.    assert(testSquare(generalMoves[QUEEN][C3], C1));
  2113.    assert(testSquare(generalMoves[QUEEN][C3], A1));
  2114.    assert(testSquare(generalMoves[QUEEN][C3], A3));
  2115.    assert(testSquare(generalMoves[QUEEN][C3], A5));
  2116.    assert(getNumberOfSetSquares(generalMoves[QUEEN][C3]) == 25);
  2117.  
  2118.    assert(testSquare(generalMoves[KNIGHT][C3], A2));
  2119.    assert(testSquare(generalMoves[KNIGHT][C3], A4));
  2120.    assert(testSquare(generalMoves[KNIGHT][C3], B5));
  2121.    assert(testSquare(generalMoves[KNIGHT][C3], D5));
  2122.    assert(testSquare(generalMoves[KNIGHT][C3], E4));
  2123.    assert(testSquare(generalMoves[KNIGHT][C3], E2));
  2124.    assert(testSquare(generalMoves[KNIGHT][C3], D1));
  2125.    assert(testSquare(generalMoves[KNIGHT][C3], B1));
  2126.    assert(getNumberOfSetSquares(generalMoves[KNIGHT][C3]) == 8);
  2127.    assert(getNumberOfSetSquares(generalMoves[KNIGHT][A1]) == 2);
  2128.    assert(getNumberOfSetSquares(generalMoves[KNIGHT][H8]) == 2);
  2129.  
  2130.    assert(testSquare(generalMoves[WHITE_PAWN][A2], B3));
  2131.    assert(getNumberOfSetSquares(generalMoves[WHITE_PAWN][A2]) == 1);
  2132.    assert(testSquare(generalMoves[WHITE_PAWN][B2], A3));
  2133.    assert(testSquare(generalMoves[WHITE_PAWN][B2], C3));
  2134.    assert(getNumberOfSetSquares(generalMoves[WHITE_PAWN][B2]) == 2);
  2135.    assert(testSquare(generalMoves[WHITE_PAWN][H2], G3));
  2136.    assert(getNumberOfSetSquares(generalMoves[WHITE_PAWN][H2]) == 1);
  2137.  
  2138.    assert(testSquare(generalMoves[BLACK_PAWN][A7], B6));
  2139.    assert(getNumberOfSetSquares(generalMoves[BLACK_PAWN][A7]) == 1);
  2140.    assert(testSquare(generalMoves[BLACK_PAWN][B7], A6));
  2141.    assert(testSquare(generalMoves[BLACK_PAWN][B7], C6));
  2142.    assert(getNumberOfSetSquares(generalMoves[BLACK_PAWN][B7]) == 2);
  2143.    assert(testSquare(generalMoves[BLACK_PAWN][H7], G6));
  2144.    assert(getNumberOfSetSquares(generalMoves[BLACK_PAWN][H7]) == 1);
  2145.  
  2146.    return 0;
  2147. }
  2148.  
  2149. static int testPieces()
  2150. {
  2151.    Bitboard b = EMPTY_BITBOARD, moves;
  2152.    BYTE obstacles[NUM_LANES];
  2153.  
  2154.    setSquare(b, C3);
  2155.    setSquare(b, C6);
  2156.    setSquare(b, F6);
  2157.  
  2158.    calculateObstacles(b, obstacles);
  2159.  
  2160.    moves = getMagicRookMoves(C4, b);
  2161.    assert(testSquare(moves, C3));
  2162.    assert(testSquare(moves, C5));
  2163.    assert(testSquare(moves, C6));
  2164.    assert(testSquare(moves, A4));
  2165.    assert(testSquare(moves, B4));
  2166.    assert(testSquare(moves, D4));
  2167.    assert(testSquare(moves, E4));
  2168.    assert(testSquare(moves, F4));
  2169.    assert(testSquare(moves, G4));
  2170.    assert(testSquare(moves, H4));
  2171.    assert(getNumberOfSetSquares(moves) == 10);
  2172.  
  2173.    moves = getMagicBishopMoves(E5, b);
  2174.    assert(testSquare(moves, D4));
  2175.    assert(testSquare(moves, C3));
  2176.    assert(testSquare(moves, D6));
  2177.    assert(testSquare(moves, C7));
  2178.    assert(testSquare(moves, B8));
  2179.    assert(testSquare(moves, F6));
  2180.    assert(testSquare(moves, F4));
  2181.    assert(testSquare(moves, G3));
  2182.    assert(testSquare(moves, H2));
  2183.    assert(getNumberOfSetSquares(moves) == 9);
  2184.  
  2185.    moves = getMagicQueenMoves(F3, b);
  2186.    assert(testSquare(moves, F2));
  2187.    assert(testSquare(moves, F1));
  2188.    assert(testSquare(moves, F4));
  2189.    assert(testSquare(moves, F5));
  2190.    assert(testSquare(moves, F6));
  2191.    assert(testSquare(moves, E3));
  2192.    assert(testSquare(moves, D3));
  2193.    assert(testSquare(moves, C3));
  2194.    assert(testSquare(moves, G3));
  2195.    assert(testSquare(moves, H3));
  2196.    assert(testSquare(moves, E4));
  2197.    assert(testSquare(moves, D5));
  2198.    assert(testSquare(moves, C6));
  2199.    assert(testSquare(moves, G4));
  2200.    assert(testSquare(moves, H5));
  2201.    assert(testSquare(moves, G2));
  2202.    assert(testSquare(moves, H1));
  2203.    assert(testSquare(moves, E2));
  2204.    assert(testSquare(moves, D1));
  2205.    assert(getNumberOfSetSquares(moves) == 19);
  2206.  
  2207.    moves = getKnightMoves(A8);
  2208.    assert(testSquare(moves, B6));
  2209.    assert(testSquare(moves, C7));
  2210.    assert(getNumberOfSetSquares(moves) == 2);
  2211.  
  2212.    moves = getKnightMoves(E5);
  2213.    assert(testSquare(moves, F7));
  2214.    assert(testSquare(moves, G6));
  2215.    assert(testSquare(moves, G4));
  2216.    assert(testSquare(moves, F3));
  2217.    assert(testSquare(moves, D3));
  2218.    assert(testSquare(moves, C4));
  2219.    assert(testSquare(moves, C6));
  2220.    assert(testSquare(moves, D7));
  2221.    assert(getNumberOfSetSquares(moves) == 8);
  2222.  
  2223.    return 0;
  2224. }
  2225.  
  2226. static int testPawns()
  2227. {
  2228.    Bitboard b = EMPTY_BITBOARD, moves, pawns;
  2229.    BYTE obstacles[NUM_LANES];
  2230.  
  2231.    setSquare(b, B3);
  2232.    setSquare(b, C4);
  2233.    setSquare(b, E4);
  2234.    setSquare(b, F6);
  2235.    setSquare(b, E5);
  2236.    setSquare(b, D6);
  2237.    setSquare(b, G2);
  2238.    setSquare(b, G3);
  2239.    setSquare(b, H2);
  2240.    setSquare(b, H7);
  2241.  
  2242.    calculateObstacles(b, obstacles);
  2243.  
  2244.    moves = getPawnAdvances(WHITE, A2, b);
  2245.    assert(testSquare(moves, A3));
  2246.    assert(testSquare(moves, A4));
  2247.    assert(getNumberOfSetSquares(moves) == 2);
  2248.  
  2249.    moves = getPawnAdvances(WHITE, B2, b);
  2250.    assert(getNumberOfSetSquares(moves) == 0);
  2251.  
  2252.    moves = getPawnAdvances(WHITE, C2, b);
  2253.    assert(testSquare(moves, C3));
  2254.    assert(getNumberOfSetSquares(moves) == 1);
  2255.  
  2256.    moves = getPawnAdvances(BLACK, H7, b);
  2257.    assert(testSquare(moves, H6));
  2258.    assert(testSquare(moves, H5));
  2259.    assert(getNumberOfSetSquares(moves) == 2);
  2260.  
  2261.    moves = getPawnAdvances(BLACK, F7, b);
  2262.    assert(getNumberOfSetSquares(moves) == 0);
  2263.  
  2264.    moves = getPawnAdvances(BLACK, E7, b);
  2265.    assert(testSquare(moves, E6));
  2266.    assert(getNumberOfSetSquares(moves) == 1);
  2267.  
  2268.    moves = getPawnCaptures(WHITE_PAWN, A2, b);
  2269.    assert(testSquare(moves, B3));
  2270.    assert(getNumberOfSetSquares(moves) == 1);
  2271.  
  2272.    moves = getPawnCaptures(WHITE_PAWN, D3, b);
  2273.    assert(testSquare(moves, C4));
  2274.    assert(testSquare(moves, E4));
  2275.    assert(getNumberOfSetSquares(moves) == 2);
  2276.  
  2277.    moves = getPawnCaptures(BLACK_PAWN, G7, b);
  2278.    assert(testSquare(moves, F6));
  2279.    assert(getNumberOfSetSquares(moves) == 1);
  2280.  
  2281.    moves = getPawnCaptures(BLACK_PAWN, E7, b);
  2282.    assert(testSquare(moves, D6));
  2283.    assert(testSquare(moves, F6));
  2284.    assert(getNumberOfSetSquares(moves) == 2);
  2285.  
  2286.    pawns = getInterestedPawns(BLACK, D5, b);
  2287.    assert(testSquare(pawns, D6));
  2288.    assert(getNumberOfSetSquares(pawns) == 1);
  2289.  
  2290.    pawns = getInterestedPawns(BLACK, H5, b);
  2291.    assert(testSquare(pawns, H7));
  2292.    assert(testSquare(pawns, H6));
  2293.    assert(getNumberOfSetSquares(pawns) == 2);
  2294.  
  2295.    pawns = getInterestedPawns(WHITE, H4, b);
  2296.    assert(testSquare(pawns, H2));
  2297.    assert(testSquare(pawns, H3));
  2298.    assert(getNumberOfSetSquares(pawns) == 2);
  2299.  
  2300.    pawns = getInterestedPawns(WHITE, G4, b);
  2301.    assert(testSquare(pawns, G3));
  2302.    assert(getNumberOfSetSquares(pawns) == 1);
  2303.  
  2304.    return 0;
  2305. }
  2306.  
  2307. static int testKings()
  2308. {
  2309.    Bitboard obstacles = EMPTY_BITBOARD, moves;
  2310.    BYTE castlingRights = WHITE_00 | WHITE_000 | BLACK_000 | BLACK_00;
  2311.  
  2312.    moves = getKingMoves(A1);
  2313.    assert(testSquare(moves, B1));
  2314.    assert(testSquare(moves, B2));
  2315.    assert(testSquare(moves, A2));
  2316.    assert(getNumberOfSetSquares(moves) == 3);
  2317.  
  2318.    moves = getKingMoves(D5);
  2319.    assert(testSquare(moves, D6));
  2320.    assert(testSquare(moves, E6));
  2321.    assert(testSquare(moves, E5));
  2322.    assert(testSquare(moves, E4));
  2323.    assert(testSquare(moves, D4));
  2324.    assert(testSquare(moves, C4));
  2325.    assert(testSquare(moves, C5));
  2326.    assert(testSquare(moves, C6));
  2327.    assert(getNumberOfSetSquares(moves) == 8);
  2328.  
  2329.    moves = getKingMoves(D5);
  2330.    assert(testSquare(moves, D6));
  2331.    assert(testSquare(moves, E6));
  2332.    assert(testSquare(moves, E5));
  2333.    assert(testSquare(moves, E4));
  2334.    assert(testSquare(moves, D4));
  2335.    assert(testSquare(moves, C4));
  2336.    assert(testSquare(moves, C5));
  2337.    assert(testSquare(moves, C6));
  2338.    assert(getNumberOfSetSquares(moves) == 8);
  2339.  
  2340.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2341.    assert(testSquare(moves, G1));
  2342.    assert(testSquare(moves, C1));
  2343.    assert(getNumberOfSetSquares(moves) == 2);
  2344.  
  2345.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2346.    assert(testSquare(moves, G8));
  2347.    assert(testSquare(moves, C8));
  2348.    assert(getNumberOfSetSquares(moves) == 2);
  2349.  
  2350.    castlingRights = WHITE_00 | BLACK_00;
  2351.  
  2352.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2353.    assert(testSquare(moves, G1));
  2354.    assert(getNumberOfSetSquares(moves) == 1);
  2355.  
  2356.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2357.    assert(testSquare(moves, G8));
  2358.    assert(getNumberOfSetSquares(moves) == 1);
  2359.  
  2360.    castlingRights = WHITE_000 | BLACK_000;
  2361.  
  2362.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2363.    assert(testSquare(moves, C1));
  2364.    assert(getNumberOfSetSquares(moves) == 1);
  2365.  
  2366.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2367.    assert(testSquare(moves, C8));
  2368.    assert(getNumberOfSetSquares(moves) == 1);
  2369.  
  2370.    castlingRights = WHITE_00 | WHITE_000 | BLACK_000 | BLACK_00;
  2371.    setSquare(obstacles, D1);
  2372.    setSquare(obstacles, D8);
  2373.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2374.    assert(testSquare(moves, G1));
  2375.    assert(getNumberOfSetSquares(moves) == 1);
  2376.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2377.    assert(testSquare(moves, G8));
  2378.    assert(getNumberOfSetSquares(moves) == 1);
  2379.    clearSquare(obstacles, D1);
  2380.    clearSquare(obstacles, D8);
  2381.  
  2382.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2383.    assert(testSquare(moves, G1));
  2384.    assert(testSquare(moves, C1));
  2385.    assert(getNumberOfSetSquares(moves) == 2);
  2386.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2387.    assert(testSquare(moves, G8));
  2388.    assert(testSquare(moves, C8));
  2389.    assert(getNumberOfSetSquares(moves) == 2);
  2390.  
  2391.    setSquare(obstacles, C1);
  2392.    setSquare(obstacles, C8);
  2393.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2394.    assert(testSquare(moves, G1));
  2395.    assert(getNumberOfSetSquares(moves) == 1);
  2396.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2397.    assert(testSquare(moves, G8));
  2398.    assert(getNumberOfSetSquares(moves) == 1);
  2399.    clearSquare(obstacles, C1);
  2400.    clearSquare(obstacles, C8);
  2401.  
  2402.    setSquare(obstacles, F1);
  2403.    setSquare(obstacles, F8);
  2404.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2405.    assert(testSquare(moves, C1));
  2406.    assert(getNumberOfSetSquares(moves) == 1);
  2407.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2408.    assert(testSquare(moves, C8));
  2409.    assert(getNumberOfSetSquares(moves) == 1);
  2410.    clearSquare(obstacles, F1);
  2411.    clearSquare(obstacles, F8);
  2412.  
  2413.    setSquare(obstacles, G1);
  2414.    setSquare(obstacles, G8);
  2415.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2416.    assert(testSquare(moves, C1));
  2417.    assert(getNumberOfSetSquares(moves) == 1);
  2418.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2419.    assert(testSquare(moves, C8));
  2420.    assert(getNumberOfSetSquares(moves) == 1);
  2421.    clearSquare(obstacles, G1);
  2422.    clearSquare(obstacles, G8);
  2423.  
  2424.    setSquare(obstacles, G1);
  2425.    setSquare(obstacles, G8);
  2426.    setSquare(obstacles, C1);
  2427.    setSquare(obstacles, C8);
  2428.    moves = getCastlingMoves(WHITE, castlingRights, obstacles);
  2429.    assert(getNumberOfSetSquares(moves) == 0);
  2430.    moves = getCastlingMoves(BLACK, castlingRights, obstacles);
  2431.    assert(getNumberOfSetSquares(moves) == 0);
  2432.    clearSquare(obstacles, G1);
  2433.    clearSquare(obstacles, G8);
  2434.    clearSquare(obstacles, C1);
  2435.    clearSquare(obstacles, C8);
  2436.  
  2437.    return 0;
  2438. }
  2439.  
  2440. static int testFlooding()
  2441. {
  2442.    Bitboard kingMoves = getKingMoves(D4);
  2443.    Bitboard expected;
  2444.  
  2445.    floodBoard(&kingMoves);
  2446.    expected = squaresBetween[A6][G6] | squaresBetween[A5][G5] |
  2447.       squaresBetween[A4][G4] | squaresBetween[A3][G3] |
  2448.       squaresBetween[A2][G2];
  2449.    assert(kingMoves == expected);
  2450.  
  2451.    kingMoves = getKingMoves(H1);
  2452.    floodBoard(&kingMoves);
  2453.    expected = squaresBehind[E3][A3] | squaresBehind[E2][A2] |
  2454.       squaresBehind[E1][A1];
  2455.    assert(kingMoves == expected);
  2456.  
  2457.    kingMoves = getKingMoves(A8);
  2458.    floodBoard(&kingMoves);
  2459.    expected = squaresBehind[D8][H8] | squaresBehind[D7][H7] |
  2460.       squaresBehind[D6][H6];
  2461.    assert(kingMoves == expected);
  2462.  
  2463.    return 0;
  2464. }
  2465.  
  2466. static int testGetSetSquares()
  2467. {
  2468.    UINT8 moveSquares[_64_];
  2469.    Bitboard kingMoves = getKingMoves(D4);
  2470.    int numMoves = getSetSquares(kingMoves, moveSquares), i;
  2471.  
  2472.    assert(numMoves == 8);
  2473.  
  2474.    for (i = 0; i < numMoves; i++)
  2475.    {
  2476.       const Square square = (Square) moveSquares[i];
  2477.  
  2478.       assert(testSquare(kingMoves, square) == TRUE);
  2479.    }
  2480.  
  2481.    return 0;
  2482. }
  2483.  
  2484. #endif
  2485.  
  2486. int testModuleBitboard()
  2487. {
  2488. #ifndef NDEBUG
  2489.    int result;
  2490.  
  2491.    if ((result = testBitOperations()) != 0)
  2492.    {
  2493.       return result;
  2494.    }
  2495.  
  2496.    if ((result = testGeneralMoves()) != 0)
  2497.    {
  2498.       return result;
  2499.    }
  2500.  
  2501.    if ((result = testPieces()) != 0)
  2502.    {
  2503.       return result;
  2504.    }
  2505.  
  2506.    if ((result = testPawns()) != 0)
  2507.    {
  2508.       return result;
  2509.    }
  2510.  
  2511.    if ((result = testKings()) != 0)
  2512.    {
  2513.       return result;
  2514.    }
  2515.  
  2516.    if ((result = testFlooding()) != 0)
  2517.    {
  2518.       return result;
  2519.    }
  2520.  
  2521.    if ((result = testGetSetSquares()) != 0)
  2522.    {
  2523.       return result;
  2524.    }
  2525. #endif
  2526.  
  2527.    return 0;
  2528. }
  2529.