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. #include <stdio.h>
  22. #include <string.h>
  23. #include <assert.h>
  24. #include <math.h>
  25. #include "position.h"
  26. #include "fen.h"
  27. #include "io.h"
  28. #include "keytable.h"
  29. #include "hash.h"
  30. #include "evaluation.h"
  31.  
  32. /* #define TRACE_POSITIONS 1 */
  33.  
  34. #ifdef TRACE_POSITIONS
  35. const int POSITION_TRACE_START = 4711;
  36. const int POSITION_TRACE_QUANTITY = 100;
  37. #endif
  38.  
  39. int VALUE_QUEEN_OPENING = DEFAULTVALUE_QUEEN_OPENING;
  40. int VALUE_QUEEN_ENDGAME = DEFAULTVALUE_QUEEN_ENDGAME;
  41. int VALUE_ROOK_OPENING = DEFAULTVALUE_ROOK_OPENING;
  42. int VALUE_ROOK_ENDGAME = DEFAULTVALUE_ROOK_ENDGAME;
  43. int VALUE_BISHOP_OPENING = DEFAULTVALUE_BISHOP_OPENING;
  44. int VALUE_BISHOP_ENDGAME = DEFAULTVALUE_BISHOP_ENDGAME;
  45. int VALUE_KNIGHT_OPENING = DEFAULTVALUE_KNIGHT_OPENING;
  46. int VALUE_KNIGHT_ENDGAME = DEFAULTVALUE_KNIGHT_ENDGAME;
  47. int VALUE_PAWN_OPENING = DEFAULTVALUE_PAWN_OPENING;
  48. int VALUE_PAWN_ENDGAME = DEFAULTVALUE_PAWN_ENDGAME;
  49. int VALUE_BISHOP_PAIR_OPENING = DEFAULTVALUE_BISHOP_PAIR_OPENING;
  50. int VALUE_BISHOP_PAIR_ENDGAME = DEFAULTVALUE_BISHOP_PAIR_ENDGAME;
  51.  
  52. int basicValue[16];
  53. INT32 pieceSquareBonus[16][_64_];
  54. BYTE remainingCastlings[_64_];
  55. Square rookOrigin[_64_];
  56. int pieceCountShift[16];
  57. UINT64 pieceCountWeight[16];
  58. UINT64 bishopPieceCountWeight[2][_64_];
  59. UINT32 matSigOfPieceCount[0xFFff];
  60. int krqIndexWhite[4096], bbpIndexWhite[4096];
  61. int krqIndexBlack[4096], bbpIndexBlack[4096];
  62.  
  63. Square relativeSquare(const Square square, const Color color)
  64. {
  65.    return (color == WHITE ? square : getFlippedSquare(square));
  66. }
  67.  
  68. INT32 evalBonus(INT32 openingBonus, INT32 endgameBonus)
  69. {
  70.    return V(openingBonus, endgameBonus);
  71. }
  72.  
  73. int getOpeningValue(INT32 value)
  74. {
  75.    return (int) ((INT16) (value & 0xFFFF));
  76. }
  77.  
  78. int getEndgameValue(INT32 value)
  79. {
  80.    return (int) ((value + 0x8000) >> 16);
  81. }
  82.  
  83. void addBonusForColor(const INT32 bonus, Position * position,
  84.                       const Color color)
  85. {
  86.    if (color == WHITE)
  87.    {
  88.       position->balance += bonus;
  89.    }
  90.    else
  91.    {
  92.       position->balance -= bonus;
  93.    }
  94. }
  95.  
  96. /**
  97.  * Pack the specified move into a 16-bit-uint.
  98.  */
  99. UINT16 packedMove(const Move move)
  100. {
  101.    return (UINT16) (move & 0xFFFF);
  102. }
  103.  
  104. /**
  105.  * Construct the specified move.
  106.  */
  107. Move getMove(const Square from, const Square to,
  108.              const Piece newPiece, const INT16 value)
  109. {
  110.    return (value << 16) | (newPiece << 12) | (to << 6) | from;
  111. }
  112.  
  113. /**
  114.  * Construct the specified ordinary move.
  115.  */
  116. Move getOrdinaryMove(const Square from, const Square to)
  117. {
  118.    return (to << 6) | from;
  119. }
  120.  
  121. /**
  122.  * Construct the specified packed move.
  123.  */
  124. Move getPackedMove(const Square from, const Square to, const Piece newPiece)
  125. {
  126.    return (newPiece << 12) | (to << 6) | from;
  127. }
  128.  
  129. /**
  130.  * Get the from square of the specified move.
  131.  */
  132. Square getFromSquare(const Move move)
  133. {
  134.    return (Square) (move & 0x3F);
  135. }
  136.  
  137. /**
  138.  * Get the to square of the specified move.
  139.  */
  140. Square getToSquare(const Move move)
  141. {
  142.    return (Square) ((move >> 6) & 0x3F);
  143. }
  144.  
  145. /**
  146.  * Get the new piece of the specified move.
  147.  */
  148. Piece getNewPiece(const Move move)
  149. {
  150.    return (Piece) ((move >> 12) & 0x0F);
  151. }
  152.  
  153. /**
  154.  * Get the value of the specified move.
  155.  */
  156. INT16 getMoveValue(const Move move)
  157. {
  158.    return (INT16) (move >> 16);
  159. }
  160.  
  161. /**
  162.  * Set the value of the specified move.
  163.  */
  164. void setMoveValue(Move * move, const int value)
  165. {
  166.    *move = (*move & 0xFFFF) | (value << 16);
  167. }
  168.  
  169. /**
  170.  * Get the opponent color of the specified color.
  171.  */
  172. Color opponent(Color color)
  173. {
  174.    return (Color) (1 - color);
  175. }
  176.  
  177. /**
  178.  * Get the direct attackers of 'attackerColor' on 'square'.
  179.  */
  180. Bitboard getDirectAttackers(const Position * position,
  181.                             const Square square,
  182.                             const Color attackerColor,
  183.                             const Bitboard obstacles)
  184. {
  185.    const Bitboard king = getKingMoves(square) &
  186.       minValue[position->king[attackerColor]];
  187.    Bitboard dia = getMagicBishopMoves(square, obstacles);
  188.    Bitboard ortho = getMagicRookMoves(square, obstacles);
  189.    Bitboard knights = getKnightMoves(square);
  190.    const Bitboard pawns =
  191.       getPawnCaptures((Piece) (PAWN | opponent(attackerColor)),
  192.                       square, position->piecesOfType[PAWN | attackerColor]);
  193.  
  194.    ortho &= (position->piecesOfType[QUEEN | attackerColor] |
  195.              position->piecesOfType[ROOK | attackerColor]);
  196.    dia &= (position->piecesOfType[QUEEN | attackerColor] |
  197.            position->piecesOfType[BISHOP | attackerColor]);
  198.    knights &= position->piecesOfType[KNIGHT | attackerColor];
  199.  
  200.    return king | ortho | dia | knights | pawns;
  201. }
  202.  
  203. /**
  204.  * Get the squares behind targetSquare, seen from 'viewPoint'.
  205.  */
  206. Bitboard getDiaSquaresBehind(const Position * position,
  207.                              const Square targetSquare,
  208.                              const Square viewPoint)
  209. {
  210.    return squaresBehind[targetSquare][viewPoint] &
  211.       getMagicBishopMoves(targetSquare, position->allPieces);
  212. }
  213.  
  214. /**
  215.  * Get the squares behind targetSquare, seen from 'viewPoint'.
  216.  */
  217. Bitboard getOrthoSquaresBehind(const Position * position,
  218.                                const Square targetSquare,
  219.                                const Square viewPoint)
  220. {
  221.    return squaresBehind[targetSquare][viewPoint] &
  222.       getMagicRookMoves(targetSquare, position->allPieces);
  223. }
  224.  
  225. /**
  226.  * Initialize the current plyInfo data structure.
  227.  */
  228. void initializePlyInfo(Variation * variation)
  229. {
  230.    const Position *position = &variation->singlePosition;
  231.    PlyInfo *plyInfo = &variation->plyInfo[variation->ply];
  232.    const Color activeColor = position->activeColor;
  233.  
  234.    plyInfo->pawnHashKey = position->pawnHashKey;
  235.    plyInfo->enPassantSquare = position->enPassantSquare;
  236.    plyInfo->kingSquare = position->king[activeColor];
  237.    plyInfo->castlingRights = position->castlingRights;
  238.    plyInfo->halfMoveClock = position->halfMoveClock;
  239.    plyInfo->allPieces = position->allPieces;
  240.    plyInfo->whitePieces = position->piecesOfColor[WHITE];
  241.    plyInfo->blackPieces = position->piecesOfColor[BLACK];
  242.    plyInfo->balance = 0;
  243. }
  244.  
  245. /**
  246.  * Initialize the current pv.
  247.  */
  248. void initializePv(PrincipalVariation * pv)
  249. {
  250.    int i;
  251.  
  252.    pv->length = 0;
  253.    pv->score = VALUE_MATED;
  254.    pv->scoreType = HASHVALUE_LOWER_LIMIT;
  255.  
  256.    for (i = 0; i < MAX_DEPTH_ARRAY_SIZE; i++)
  257.    {
  258.       pv->move[i] = (UINT16) NO_MOVE;
  259.    }
  260. }
  261.  
  262. /**
  263.  * Initialize the pvs of the current variation.
  264.  */
  265. void initializePvsOfVariation(Variation * variation)
  266. {
  267.    int i;
  268.  
  269.    initializePv(&variation->completePv);
  270.  
  271.    for (i = 0; i < MAX_NUM_PV; i++)
  272.    {
  273.       initializePv(&variation->pv[i]);
  274.    }
  275.  
  276.    variation->pvId = 0;
  277. }
  278.  
  279. /**
  280.  * Initialize the pvs of the current variation.
  281.  */
  282. void resetPvsOfVariation(Variation * variation)
  283. {
  284.    int i;
  285.  
  286.    for (i = 0; i < MAX_NUM_PV; i++)
  287.    {
  288.       variation->pv[i].score = VALUE_MATED;
  289.       variation->pv[i].scoreType = HASHVALUE_LOWER_LIMIT;
  290.    }
  291.  
  292.    variation->pvId = 0;
  293. }
  294.  
  295. int getPvlistMoveCount(Variation * variation, PrincipalVariation * pv)
  296. {
  297.    int i, count = 0;
  298.  
  299.    for (i = 0; i < MAX_NUM_PV; i++)
  300.    {
  301.       if (movesAreEqual(pv->move[0], variation->pv[i].move[0]))
  302.       {
  303.          count++;
  304.       }
  305.    }
  306.  
  307.    return count;
  308. }
  309.  
  310. bool pvListContainsMove(Variation * variation, PrincipalVariation * pv)
  311. {
  312.    int i;
  313.  
  314.    for (i = 0; i < MAX_NUM_PV; i++)
  315.    {
  316.       if (movesAreEqual(pv->move[0], variation->pv[i].move[0]))
  317.       {
  318.          return TRUE;
  319.       }
  320.    }
  321.  
  322.    return FALSE;
  323. }
  324.  
  325. void clearPvList(Variation * variation, PrincipalVariation * pv)
  326. {
  327.    int i;
  328.  
  329.    for (i = 0; i < MAX_NUM_PV; i++)
  330.    {
  331.       if (movesAreEqual(pv->move[0], variation->pv[i].move[0]))
  332.       {
  333.          int j;
  334.  
  335.          for (j = i; j < MAX_NUM_PV - 1; j++)
  336.          {
  337.             variation->pv[j] = variation->pv[j + 1];
  338.          }
  339.  
  340.          initializePv(&variation->pv[MAX_NUM_PV - 1]);
  341.       }
  342.    }
  343. }
  344.  
  345. void addPvByScore(Variation * variation, PrincipalVariation * pv)
  346. {
  347.    int i;
  348.  
  349.    /* Delete previous pv entries for the same root move */
  350.    while (pvListContainsMove(variation, pv))
  351.    {
  352.       clearPvList(variation, pv);
  353.    }
  354.  
  355.    for (i = 0; i < MAX_NUM_PV; i++)
  356.    {
  357.       if (pv->score > variation->pv[i].score)
  358.       {
  359.          int j;
  360.  
  361.          for (j = MAX_NUM_PV - 1; j > i; j--)
  362.          {
  363.             variation->pv[j] = variation->pv[j - 1];
  364.          }
  365.  
  366.          variation->pv[i] = *pv;
  367.          break;
  368.       }
  369.    }
  370.  
  371.    /* logDebug("move count on exit = %d\n", getPvlistMoveCount(variation, pv)); */
  372. }
  373.  
  374. void resetPlyInfo(Variation * variation)
  375. {
  376.    int i;
  377.  
  378.    for (i = 0; i < MAX_DEPTH_ARRAY_SIZE; i++)
  379.    {
  380.       variation->plyInfo[i].staticValueAvailable =
  381.          variation->plyInfo[i].gainsUpdated = FALSE;
  382.       variation->plyInfo[i].pv.length = 0;
  383.       variation->plyInfo[i].pv.move[0] = NO_MOVE;
  384.    }
  385. }
  386.  
  387. /**
  388.  * Get the number of non-pawn pieces for the specified color.
  389.  */
  390. int numberOfNonPawnPieces(const Position * position, const Color color)
  391. {
  392.    return position->numberOfPieces[color] - position->numberOfPawns[color];
  393. }
  394.  
  395. /**
  396.  * Check if the specified color has a rook or a queen.
  397.  */
  398. bool hasOrthoPieces(const Position * position, const Color color)
  399. {
  400.    return (bool) (position->piecesOfType[ROOK | color] != EMPTY_BITBOARD ||
  401.                   position->piecesOfType[QUEEN | color] != EMPTY_BITBOARD);
  402. }
  403.  
  404. /**
  405.  * Check if the specified color has a queen.
  406.  */
  407. bool hasQueen(const Position * position, const Color color)
  408. {
  409.    return (bool) (position->piecesOfType[QUEEN | color] != EMPTY_BITBOARD);
  410. }
  411.  
  412. /**
  413.  * Append the given move to the old pv and copy the new pv to 'new'.
  414.  */
  415. void appendMoveToPv(const PrincipalVariation * oldPv,
  416.                     PrincipalVariation * newPv, const Move move)
  417. {
  418.    newPv->move[0] = packedMove(move);
  419.    newPv->length = oldPv->length + 1;
  420.    memmove((void *) &newPv->move[1], (void *) &oldPv->move[0],
  421.            oldPv->length * sizeof(UINT16));
  422. }
  423.  
  424. /**
  425.  * Calculate the value to be stored in the hashtable.
  426.  */
  427. INT16 calcHashtableValue(const int value, const int ply)
  428. {
  429.    if (value >= -VALUE_ALMOST_MATED)
  430.    {
  431.       return (INT16) (value + ply);
  432.    }
  433.    else if (value <= VALUE_ALMOST_MATED)
  434.    {
  435.       return (INT16) (value - ply);
  436.    }
  437.  
  438.    return (INT16) value;
  439. }
  440.  
  441. /**
  442.  * Calculate the effective value from the specified hashtable value.
  443.  */
  444. int calcEffectiveValue(const int value, const int ply)
  445. {
  446.    if (value >= -VALUE_ALMOST_MATED)
  447.    {
  448.       return value - ply;
  449.    }
  450.    else if (value <= VALUE_ALMOST_MATED)
  451.    {
  452.       return value + ply;
  453.    }
  454.  
  455.    return value;
  456. }
  457.  
  458. /**
  459.  * Get all ordinary pieces (queens, rooks, bishops, knights)
  460.  * of the specified color.
  461.  */
  462. Bitboard getOrdinaryPieces(const Position * position, const Color color)
  463. {
  464.    return position->piecesOfColor[color] &
  465.       ~(position->piecesOfType[PAWN | color] |
  466.         minValue[position->king[color]]);
  467. }
  468.  
  469. /**
  470.  * Get all non pawn pieces of the specified color.
  471.  */
  472. Bitboard getNonPawnPieces(const Position * position, const Color color)
  473. {
  474.    return position->piecesOfColor[color] &
  475.       ~position->piecesOfType[PAWN | color];
  476. }
  477.  
  478. /**
  479.  * Get all ortho pieces (queens, rooks)
  480.  * of the specified color.
  481.  */
  482. Bitboard getOrthoPieces(const Position * position, const Color color)
  483. {
  484.    return position->piecesOfType[ROOK | color] |
  485.       position->piecesOfType[QUEEN | color];
  486. }
  487.  
  488. /**
  489.  * Check if the given moves are equal by ignoring their respective values.
  490.  */
  491. bool movesAreEqual(const Move m1, const Move m2)
  492. {
  493.    return (bool) ((m1 & 0xFFFF) == (m2 & 0xFFFF));
  494. }
  495.  
  496. /**
  497.  * Get the population count for the specified piece in the specified position.
  498.  */
  499. int getPieceCount(const Position * position, const Piece piece)
  500. {
  501.    return (int) ((position->pieceCount >> pieceCountShift[piece]) & 0x0F);
  502. }
  503.  
  504. /**
  505.  * Check if the specified piece is present in the specified position.
  506.  */
  507. bool pieceIsPresent(const Position * position, const Piece piece)
  508. {
  509.    return (bool) (position->piecesOfType[piece] != EMPTY_BITBOARD);
  510. }
  511.  
  512. /**
  513.  * Get the history index of the specified move.
  514.  */
  515. int historyIndex(const Move move, const Position * position)
  516. {
  517.    return (position->piece[getFromSquare(move)] << 6) + getToSquare(move);
  518. }
  519.  
  520. /**
  521.  * Calculate the distance to the next piece of a given type.
  522.  *
  523.  * @return the distance or 8 if no piece was found
  524.  */
  525. int getMinimalDistance(const Position * position,
  526.                        const Square origin, const Piece piece)
  527. {
  528.    int distance;
  529.  
  530.    for (distance = 1; distance <= 7; distance++)
  531.    {
  532.       if ((squaresInDistance[distance][origin] &
  533.            position->piecesOfType[piece]) != EMPTY_BITBOARD)
  534.       {
  535.          return distance;
  536.       }
  537.    }
  538.  
  539.    return 8;
  540. }
  541.  
  542. /**
  543.  * Calculate the distance to the next piece of a given type.
  544.  *
  545.  * @return the taxidistance or 15 if no piece was found
  546.  */
  547. int getMinimalTaxiDistance(const Position * position,
  548.                            const Square origin, const Piece piece)
  549. {
  550.    int distance;
  551.  
  552.    for (distance = 1; distance <= 14; distance++)
  553.    {
  554.       if ((squaresInTaxiDistance[distance][origin] &
  555.            position->piecesOfType[piece]) != EMPTY_BITBOARD)
  556.       {
  557.          return distance;
  558.       }
  559.    }
  560.  
  561.    return 15;
  562. }
  563.  
  564. /**
  565.  * Calculate the weight of the non-pawn-pieces of the specified color.
  566.  *
  567.  * @return a value in the range [0-103]
  568.  */
  569. int getPieceWeight(const Position * position, const Color color)
  570. {
  571.    const int numNonPawnPieces = numberOfNonPawnPieces(position, color) - 1;
  572.    const int numRooks = getPieceCount(position, (Piece) (ROOK | color));
  573.    const int numQueens = getPieceCount(position, (Piece) (QUEEN | color));
  574.  
  575.    return 6 * numQueens + 2 * numRooks + 3 * numNonPawnPieces;  /* q=9, r=5, b,n=3 */
  576. }
  577.  
  578. /**
  579.  * Calculate the phase index of the specified position.
  580.  *
  581.  * @return a value in the range [0(initial position)-256(endgame)]
  582.  */
  583. int phaseIndex(const Position * position)
  584. {
  585.    const int weightWhite = getPieceWeight(position, WHITE);
  586.    const int weightBlack = getPieceWeight(position, BLACK);
  587.    const int basicPhase = (weightWhite + weightBlack <= PIECE_WEIGHT_ENDGAME ?
  588.                            PHASE_MAX :
  589.                            max(0, PHASE_MAX - weightWhite - weightBlack));
  590.  
  591.    assert(getPieceWeight(position, WHITE) >= 0);
  592.    assert(getPieceWeight(position, WHITE) <= 103);
  593.    assert(getPieceWeight(position, BLACK) >= 0);
  594.    assert(getPieceWeight(position, BLACK) <= 103);
  595.    assert(basicPhase >= 0);
  596.    assert(basicPhase <= PHASE_MAX);
  597.  
  598.    return (basicPhase * 256 + (PHASE_MAX / 2)) / PHASE_MAX;
  599. }
  600.  
  601. /**
  602.  * Get the piece counters from a material signature.
  603.  */
  604. void getPieceCounters(UINT32 materialSignature,
  605.                       int *numWhiteQueens, int *numWhiteRooks,
  606.                       int *numWhiteLightSquareBishops,
  607.                       int *numWhiteDarkSquareBishops,
  608.                       int *numWhiteKnights, int *numWhitePawns,
  609.                       int *numBlackQueens, int *numBlackRooks,
  610.                       int *numBlackLightSquareBishops,
  611.                       int *numBlackDarkSquareBishops,
  612.                       int *numBlackKnights, int *numBlackPawns)
  613. {
  614.    *numWhitePawns = materialSignature % 9;
  615.    materialSignature /= 9;
  616.    *numWhiteLightSquareBishops = materialSignature % 2;
  617.    materialSignature /= 2;
  618.    *numWhiteDarkSquareBishops = materialSignature % 2;
  619.    materialSignature /= 2;
  620.    *numWhiteQueens = materialSignature % 2;
  621.    materialSignature /= 2;
  622.    *numWhiteRooks = materialSignature % 3;
  623.    materialSignature /= 3;
  624.    *numWhiteKnights = materialSignature % 3;
  625.    materialSignature /= 3;
  626.  
  627.    *numBlackPawns = materialSignature % 9;
  628.    materialSignature /= 9;
  629.    *numBlackLightSquareBishops = materialSignature % 2;
  630.    materialSignature /= 2;
  631.    *numBlackDarkSquareBishops = materialSignature % 2;
  632.    materialSignature /= 2;
  633.    *numBlackQueens = materialSignature % 2;
  634.    materialSignature /= 2;
  635.    *numBlackRooks = materialSignature % 3;
  636.    materialSignature /= 3;
  637.    *numBlackKnights = materialSignature % 3;
  638. }
  639.  
  640. /**
  641.  * Calculate a material signature from a white and a black signature.
  642.  */
  643. UINT32 bilateralSignature(const UINT32 signatureWhite,
  644.                           const UINT32 signatureBlack)
  645. {
  646.    return signatureWhite + 648 * signatureBlack;
  647. }
  648.  
  649. /**
  650.  * Get the piece counters from a material signature.
  651.  */
  652. UINT32 getMaterialSignature(const int numWhiteQueens,
  653.                             const int numWhiteRooks,
  654.                             const int numWhiteLightSquareBishops,
  655.                             const int numWhiteDarkSquareBishops,
  656.                             const int numWhiteKnights,
  657.                             const int numWhitePawns,
  658.                             const int numBlackQueens,
  659.                             const int numBlackRooks,
  660.                             const int numBlackLightSquareBishops,
  661.                             const int numBlackDarkSquareBishops,
  662.                             const int numBlackKnights,
  663.                             const int numBlackPawns)
  664. {
  665.    const int blackFactor = (3 * 3 * 2 * 2 * 2 * 9);
  666.  
  667.    return numWhitePawns +
  668.       min(1, numWhiteLightSquareBishops) * 9 +
  669.       min(1, numWhiteDarkSquareBishops) * (2 * 9) +
  670.       min(1, numWhiteQueens) * (2 * 2 * 9) +
  671.       min(2, numWhiteRooks) * (2 * 2 * 2 * 9) +
  672.       min(2, numWhiteKnights) * (3 * 2 * 2 * 2 * 9) +
  673.       numBlackPawns * blackFactor +
  674.       min(1, numBlackLightSquareBishops) * 9 * blackFactor +
  675.       min(1, numBlackDarkSquareBishops) * (2 * 9) * blackFactor +
  676.       min(1, numBlackQueens) * (2 * 2 * 9) * blackFactor +
  677.       min(2, numBlackRooks) * (2 * 2 * 2 * 9) * blackFactor +
  678.       min(2, numBlackKnights) * (3 * 2 * 2 * 2 * 9) * blackFactor;
  679. }
  680.  
  681. /**
  682.  * Get the piece counters from a material signature.
  683.  */
  684. UINT32 getSingleMaterialSignature(const int numQueens,
  685.                                   const int numRooks,
  686.                                   const int numLightSquareBishops,
  687.                                   const int numDarkSquareBishops,
  688.                                   const int numKnights, const int numPawns)
  689. {
  690.    return getMaterialSignature(numQueens, numRooks,
  691.                                numLightSquareBishops, numDarkSquareBishops,
  692.                                numKnights, numPawns, 0, 0, 0, 0, 0, 0);
  693. }
  694.  
  695. /**
  696.  * Get the material signature for the specific position.
  697.  */
  698. UINT32 getMaterialSignatureFromPieceCount(const Position * position)
  699. {
  700.    return getMaterialSignature(getPieceCount(position, WHITE_QUEEN),
  701.                                getPieceCount(position, WHITE_ROOK),
  702.                                getPieceCount(position,
  703.                                              (Piece) (WHITE_BISHOP_LIGHT)),
  704.                                getPieceCount(position,
  705.                                              (Piece) (WHITE_BISHOP_DARK)),
  706.                                getPieceCount(position, WHITE_KNIGHT),
  707.                                position->numberOfPawns[WHITE],
  708.                                getPieceCount(position, BLACK_QUEEN),
  709.                                getPieceCount(position, BLACK_ROOK),
  710.                                getPieceCount(position,
  711.                                              (Piece) (BLACK_BISHOP_LIGHT)),
  712.                                getPieceCount(position,
  713.                                              (Piece) (BLACK_BISHOP_DARK)),
  714.                                getPieceCount(position, BLACK_KNIGHT),
  715.                                position->numberOfPawns[BLACK]);
  716. }
  717.  
  718. UINT32 calculateMaterialSignature(const Position * position)
  719. {
  720.    const UINT64 bbpWhite = ((position->pieceCount >> 8) & 0x0ff0) +
  721.       position->numberOfPawns[WHITE];
  722.    const UINT64 indexWhite = krqIndexWhite[position->pieceCount & 0x0Fff] +
  723.       bbpIndexWhite[bbpWhite];
  724.    const UINT64 bbpBlack = ((position->pieceCount >> 28) & 0x0ff0) +
  725.       position->numberOfPawns[BLACK];
  726.    const UINT64 indexBlack =
  727.       krqIndexBlack[(position->pieceCount >> 20) & 0x0Fff] +
  728.       bbpIndexBlack[bbpBlack];
  729.  
  730.    assert(bbpWhite < 4096);
  731.    assert(bbpBlack < 4096);
  732.    assert(indexWhite < 648);
  733.    assert(indexBlack < 648 * 648);
  734.  
  735.    return (UINT32) (indexWhite + indexBlack);
  736. }
  737.  
  738. static UINT64 calculateHashKey(const Position * position)
  739. {
  740.    UINT64 hashKey = ULONG_ZERO;
  741.    Square square;
  742.    Piece piece;
  743.  
  744.    ITERATE(square)
  745.    {
  746.       piece = position->piece[square];
  747.  
  748.       if (piece != NO_PIECE)
  749.       {
  750.          hashKey ^= GENERATED_KEYTABLE[piece][square];
  751.       }
  752.    }
  753.  
  754.    if (position->activeColor == BLACK)
  755.    {
  756.       hashKey = ~hashKey;
  757.    }
  758.  
  759.    hashKey ^= GENERATED_KEYTABLE[0][position->castlingRights];
  760.  
  761.    if (position->enPassantSquare != NO_SQUARE)
  762.    {
  763.       hashKey ^= GENERATED_KEYTABLE[0][position->enPassantSquare];
  764.    }
  765.  
  766.    return hashKey;
  767. }
  768.  
  769. static UINT64 calculatePawnHashKey(const Position * position)
  770. {
  771.    UINT64 hashKey = ULONG_ZERO;
  772.    Square square;
  773.    Piece piece;
  774.  
  775.    ITERATE(square)
  776.    {
  777.       piece = position->piece[square];
  778.  
  779.       if (pieceType(piece) == PAWN)
  780.       {
  781.          hashKey ^= GENERATED_KEYTABLE[piece][square];
  782.       }
  783.    }
  784.  
  785.    return hashKey;
  786. }
  787.  
  788. void clearPosition(Position * position)
  789. {
  790.    Square square;
  791.  
  792.    ITERATE(square)
  793.    {
  794.       position->piece[square] = NO_PIECE;
  795.    }
  796.  
  797.    position->activeColor = WHITE;
  798.    position->castlingRights = 0;
  799.    position->enPassantSquare = NO_SQUARE;
  800.    position->moveNumber = 1;
  801.    position->halfMoveClock = 0;
  802. }
  803.  
  804. void initializePosition(Position * position)
  805. {
  806.    int i;
  807.    Square square;
  808.  
  809.    position->allPieces = EMPTY_BITBOARD;
  810.    position->piecesOfColor[WHITE] = EMPTY_BITBOARD;
  811.    position->piecesOfColor[BLACK] = EMPTY_BITBOARD;
  812.    position->balance = 0;
  813.    position->pieceCount = 0;
  814.  
  815.    for (i = 0x00; i <= 0x0F; i++)
  816.    {
  817.       position->piecesOfType[i] = EMPTY_BITBOARD;
  818.    }
  819.  
  820.    if ((position->castlingRights & WHITE_00) &&
  821.        (position->piece[E1] != WHITE_KING ||
  822.         position->piece[H1] != WHITE_ROOK))
  823.    {
  824.       position->castlingRights -= WHITE_00;
  825.    }
  826.  
  827.    if ((position->castlingRights & WHITE_000) &&
  828.        (position->piece[E1] != WHITE_KING ||
  829.         position->piece[A1] != WHITE_ROOK))
  830.    {
  831.       position->castlingRights -= WHITE_000;
  832.    }
  833.  
  834.    if ((position->castlingRights & BLACK_00) &&
  835.        (position->piece[E8] != BLACK_KING ||
  836.         position->piece[H8] != BLACK_ROOK))
  837.    {
  838.       position->castlingRights -= BLACK_00;
  839.    }
  840.  
  841.    if ((position->castlingRights & BLACK_000) &&
  842.        (position->piece[E8] != BLACK_KING ||
  843.         position->piece[A8] != BLACK_ROOK))
  844.    {
  845.       position->castlingRights -= BLACK_000;
  846.    }
  847.  
  848.    if (position->enPassantSquare != NO_SQUARE)
  849.    {
  850.       if (position->activeColor == WHITE)
  851.       {
  852.          if (rank(position->enPassantSquare) != RANK_6 ||
  853.              position->piece[position->enPassantSquare - 8] != BLACK_PAWN)
  854.          {
  855.             position->enPassantSquare = NO_SQUARE;
  856.          }
  857.       }
  858.       else
  859.       {
  860.          if (rank(position->enPassantSquare) != RANK_3 ||
  861.              position->piece[position->enPassantSquare + 8] != WHITE_PAWN)
  862.          {
  863.             position->enPassantSquare = NO_SQUARE;
  864.          }
  865.       }
  866.    }
  867.  
  868.    ITERATE(square)
  869.    {
  870.       Piece piece = position->piece[square];
  871.       Color color = pieceColor(piece);
  872.  
  873.       if (piece != NO_PIECE)
  874.       {
  875.          setSquare(position->allPieces, square);
  876.          setSquare(position->piecesOfColor[color], square);
  877.          setSquare(position->piecesOfType[piece], square);
  878.  
  879.          if (pieceType(piece) == KING)
  880.          {
  881.             position->king[color] = square;
  882.          }
  883.  
  884.          addBonusForColor(pieceSquareBonus[piece][square], position, color);
  885.  
  886.          if (pieceType(piece) == BISHOP)
  887.          {
  888.             position->pieceCount += bishopPieceCountWeight[color][square];
  889.          }
  890.          else
  891.          {
  892.             position->pieceCount += pieceCountWeight[piece];
  893.          }
  894.       }
  895.    }
  896.  
  897.    position->numberOfPieces[WHITE] =
  898.       getNumberOfSetSquares(position->piecesOfColor[WHITE]);
  899.    position->numberOfPieces[BLACK] =
  900.       getNumberOfSetSquares(position->piecesOfColor[BLACK]);
  901.    position->numberOfPawns[WHITE] =
  902.       getNumberOfSetSquares(position->piecesOfType[WHITE_PAWN]);
  903.    position->numberOfPawns[BLACK] =
  904.       getNumberOfSetSquares(position->piecesOfType[BLACK_PAWN]);
  905.  
  906.    position->hashKey = calculateHashKey(position);
  907.    position->pawnHashKey = calculatePawnHashKey(position);
  908. }
  909.  
  910. void flipPosition(Position * position)
  911. {
  912.    Square square;
  913.    BYTE castlingRights = 0;
  914.  
  915.    position->activeColor = opponent(position->activeColor);
  916.  
  917.    if (position->castlingRights & WHITE_00)
  918.    {
  919.       castlingRights += BLACK_00;
  920.    }
  921.  
  922.    if (position->castlingRights & WHITE_000)
  923.    {
  924.       castlingRights += BLACK_000;
  925.    }
  926.  
  927.    if (position->castlingRights & BLACK_00)
  928.    {
  929.       castlingRights += WHITE_00;
  930.    }
  931.  
  932.    if (position->castlingRights & BLACK_000)
  933.    {
  934.       castlingRights += WHITE_000;
  935.    }
  936.  
  937.    position->castlingRights = castlingRights;
  938.  
  939.    if (position->enPassantSquare != NO_SQUARE)
  940.    {
  941.       position->enPassantSquare = getFlippedSquare(position->enPassantSquare);
  942.    }
  943.  
  944.    for (square = A1; square <= H4; square++)
  945.    {
  946.       const Square flippedSquare = getFlippedSquare(square);
  947.       const Piece piece = position->piece[square];
  948.  
  949.       position->piece[square] =
  950.          (position->piece[flippedSquare] == NO_PIECE ? NO_PIECE :
  951.           (Piece) (position->piece[flippedSquare] ^ BLACK));
  952.       position->piece[flippedSquare] =
  953.          (piece == NO_PIECE ? NO_PIECE : (Piece) (piece ^ BLACK));
  954.    }
  955. }
  956.  
  957. void resetHistoryValues(Variation * variation)
  958. {
  959.    int i;
  960.  
  961.    for (i = 0; i < HISTORY_SIZE; i++)
  962.    {
  963.       variation->historyValue[i] = 0;
  964.       variation->counterMove1[i] = variation->counterMove2[i] = NO_MOVE;
  965.       variation->followupMove1[i] = variation->followupMove2[i] = NO_MOVE;
  966.    }
  967. }
  968.  
  969. void resetGainValues(Variation * variation)
  970. {
  971.    int i;
  972.  
  973.    for (i = 0; i < HISTORY_SIZE; i++)
  974.    {
  975.       variation->positionalGain[i] = 0;
  976.    }
  977. }
  978.  
  979. void prepareSearch(Variation * variation)
  980. {
  981.    int i;
  982.  
  983.    variation->nodes = variation->nodesAtTimeCheck = 0;
  984.    variation->nodesBetweenTimecheck = NODES_BETWEEN_TIMECHECK_DEFAULT;
  985.    initializePosition(&variation->singlePosition);
  986.    variation->drawScore[WHITE] = variation->drawScore[BLACK] = 0;
  987.    variation->bestMoveChangeCount = 0;
  988.  
  989.    for (i = 0; i < MAX_DEPTH_ARRAY_SIZE; i++)
  990.    {
  991.       PlyInfo *pi = &(variation->plyInfo[i]);
  992.  
  993.       pi->killerMove1 = pi->killerMove2 =
  994.          pi->killerMove3 = pi->killerMove4 =
  995.          pi->killerMove5 = pi->killerMove6 = NO_MOVE;
  996.    }
  997. }
  998.  
  999. void shrinkHistoryValues(Variation * variation)
  1000. {
  1001.    int i;
  1002.  
  1003.    for (i = 0; i < HISTORY_SIZE; i++)
  1004.    {
  1005.       variation->historyValue[i] = (variation->historyValue[i] + 1) / 2;
  1006.    }
  1007. }
  1008.  
  1009. void initializeVariation(Variation * variation, const char *fen)
  1010. {
  1011.    variation->ply = 0;
  1012.    readFen(fen, &variation->singlePosition);
  1013.    prepareSearch(variation);
  1014.    variation->startPosition = variation->singlePosition;
  1015. }
  1016.  
  1017. void setBasePosition(Variation * variation, const Position * position)
  1018. {
  1019.    variation->ply = 0;
  1020.    variation->singlePosition = *position;
  1021.    variation->startPosition = variation->singlePosition;
  1022. }
  1023.  
  1024. void setDrawScore(Variation * variation, int score, Color color)
  1025. {
  1026.    variation->drawScore[color] = score;
  1027.    variation->drawScore[opponent(color)] = -score;
  1028. }
  1029.  
  1030. Bitboard getInterestedPieces(const Position * position, const Square square,
  1031.                              const Color attackerColor)
  1032. {
  1033.    Bitboard king = getKingMoves(square);
  1034.    Bitboard dia = getMagicBishopMoves(square, position->allPieces);
  1035.    Bitboard ortho = getMagicRookMoves(square, position->allPieces);
  1036.    Bitboard knights = getKnightMoves(square);
  1037.    Bitboard pawns = getInterestedPawns(attackerColor, square,
  1038.                                        position->allPieces);
  1039.  
  1040.    king &= position->piecesOfType[KING | attackerColor];
  1041.    ortho &= (position->piecesOfType[QUEEN | attackerColor] |
  1042.              position->piecesOfType[ROOK | attackerColor]);
  1043.    dia &= (position->piecesOfType[QUEEN | attackerColor] |
  1044.            position->piecesOfType[BISHOP | attackerColor]);
  1045.    knights &= position->piecesOfType[KNIGHT | attackerColor];
  1046.    pawns &= position->piecesOfType[PAWN | attackerColor];
  1047.  
  1048.    return king | ortho | dia | knights | pawns;
  1049. }
  1050.  
  1051. int checkVariation(Variation * variation)
  1052. {
  1053.    if (checkConsistency(&variation->singlePosition) != 0)
  1054.    {
  1055.       logDebug("consistency check failed!\n");
  1056.  
  1057.       dumpVariation(variation);
  1058.    }
  1059.  
  1060.    return 0;
  1061. }
  1062.  
  1063. int makeMove(Variation * variation, const Move move)
  1064. {
  1065.    Position *position = &variation->singlePosition;
  1066.    PlyInfo *plyInfo = &variation->plyInfo[variation->ply++];
  1067.    const Square from = getFromSquare(move);
  1068.    const Square to = getToSquare(move);
  1069.    const Piece newPiece = getNewPiece(move);
  1070.    const Piece movingPiece = position->piece[from];
  1071.    const Piece capturedPiece = position->piece[to];
  1072.    const Color activeColor = position->activeColor;
  1073.    const Color passiveColor = opponent(activeColor);
  1074.    const Bitboard minTo = minValue[to];
  1075.    const Bitboard maxFrom = maxValue[from];
  1076.    int result = 0;
  1077.  
  1078.    assert(to == from || pieceType(capturedPiece) != KING);
  1079.  
  1080.    variation->positionHistory[POSITION_HISTORY_OFFSET - 1 + variation->ply] =
  1081.       plyInfo->hashKey = position->hashKey;
  1082.    plyInfo->currentMove = move;
  1083.    plyInfo->balance = position->balance;
  1084.    position->hashKey = ~position->hashKey;
  1085.  
  1086.    if (position->enPassantSquare != NO_SQUARE)
  1087.    {
  1088.       position->hashKey ^= GENERATED_KEYTABLE[0][position->enPassantSquare];
  1089.    }
  1090.  
  1091.    plyInfo->pawnHashKey = position->pawnHashKey;
  1092.    plyInfo->enPassantSquare = position->enPassantSquare;
  1093.    position->enPassantSquare = NO_SQUARE;
  1094.    position->activeColor = passiveColor;
  1095.  
  1096.    if (to == from)
  1097.    {
  1098.       assert(checkVariation(variation) == 0);
  1099.  
  1100.       return result;            /* Nullmove */
  1101.    }
  1102.  
  1103.    plyInfo->captured = capturedPiece;
  1104.    plyInfo->kingSquare = position->king[activeColor];
  1105.    plyInfo->castlingRights = position->castlingRights;
  1106.    plyInfo->halfMoveClock = position->halfMoveClock;
  1107.    plyInfo->allPieces = position->allPieces;
  1108.    plyInfo->whitePieces = position->piecesOfColor[WHITE];
  1109.    plyInfo->blackPieces = position->piecesOfColor[BLACK];
  1110.    plyInfo->pieceCount = position->pieceCount;
  1111.    variation->plyInfo[variation->ply].staticValueAvailable = FALSE;
  1112.    variation->plyInfo[variation->ply].gainsUpdated = FALSE;
  1113.    position->piecesOfColor[activeColor] &= maxFrom;
  1114.    position->piecesOfColor[activeColor] |= minTo;
  1115.    position->piecesOfType[movingPiece] &= maxFrom;
  1116.    position->hashKey ^=
  1117.       GENERATED_KEYTABLE[movingPiece][from] ^
  1118.       GENERATED_KEYTABLE[movingPiece][to];
  1119.    position->castlingRights &=
  1120.       remainingCastlings[to] & remainingCastlings[from];
  1121.  
  1122.    if (position->castlingRights != plyInfo->castlingRights)
  1123.    {
  1124.       position->hashKey ^=
  1125.          GENERATED_KEYTABLE[0][plyInfo->castlingRights] ^
  1126.          GENERATED_KEYTABLE[0][position->castlingRights];
  1127.    }
  1128.  
  1129.    position->halfMoveClock++;
  1130.    position->piece[to] = movingPiece;
  1131.    position->piece[from] = NO_PIECE;
  1132.    addBonusForColor(pieceSquareBonus[movingPiece][to] -
  1133.                     pieceSquareBonus[movingPiece][from], position,
  1134.                     activeColor);
  1135.  
  1136.    if (capturedPiece != NO_PIECE)
  1137.    {
  1138.       position->halfMoveClock = 0;
  1139.       position->piecesOfColor[passiveColor] &= ~minTo;
  1140.       position->piecesOfType[capturedPiece] &= ~minTo;
  1141.       position->numberOfPieces[passiveColor]--;
  1142.  
  1143.       if (pieceType(capturedPiece) == PAWN)
  1144.       {
  1145.          position->numberOfPawns[passiveColor]--;
  1146.          position->pawnHashKey ^= GENERATED_KEYTABLE[capturedPiece][to];
  1147.       }
  1148.       else
  1149.       {
  1150.          position->pieceCount -= (capturedPiece == (BISHOP | passiveColor) ?
  1151.                                   bishopPieceCountWeight[passiveColor][to] :
  1152.                                   pieceCountWeight[capturedPiece]);
  1153.       }
  1154.  
  1155.       position->hashKey ^= GENERATED_KEYTABLE[capturedPiece][to];
  1156.       addBonusForColor(pieceSquareBonus[capturedPiece][to], position,
  1157.                        activeColor);
  1158.    }
  1159.  
  1160.    if (pieceType(movingPiece) == PAWN)
  1161.    {
  1162.       position->halfMoveClock = 0;
  1163.       position->pawnHashKey ^=
  1164.          GENERATED_KEYTABLE[movingPiece][from] ^
  1165.          GENERATED_KEYTABLE[movingPiece][to];
  1166.  
  1167.       if (distance(from, to) == 2)
  1168.       {
  1169.          position->enPassantSquare = (Square) ((from + to) >> 1);
  1170.          position->hashKey ^=
  1171.             GENERATED_KEYTABLE[0][position->enPassantSquare];
  1172.       }
  1173.       else if (to == plyInfo->enPassantSquare)
  1174.       {
  1175.          const Square captureSquare =
  1176.             (Square) (to + (rank(from) - rank(to)) * 8);
  1177.          const Piece capturedPawn = position->piece[captureSquare];
  1178.  
  1179.          clearSquare(position->piecesOfColor[passiveColor], captureSquare);
  1180.          clearSquare(position->piecesOfType[capturedPawn], captureSquare);
  1181.          position->hashKey ^= GENERATED_KEYTABLE[capturedPawn][captureSquare];
  1182.          position->pawnHashKey ^=
  1183.             GENERATED_KEYTABLE[capturedPawn][captureSquare];
  1184.          addBonusForColor(pieceSquareBonus[capturedPawn][captureSquare],
  1185.                           position, activeColor);
  1186.  
  1187.          plyInfo->restoreSquare1 = captureSquare;
  1188.          plyInfo->restorePiece1 = capturedPawn;
  1189.          position->piece[captureSquare] = NO_PIECE;
  1190.          position->numberOfPieces[passiveColor]--;
  1191.          position->numberOfPawns[passiveColor]--;
  1192.       }
  1193.       else if (newPiece != NO_PIECE)
  1194.       {
  1195.          const Piece effectiveNewPiece = (Piece) (newPiece | activeColor);
  1196.  
  1197.          plyInfo->restoreSquare1 = from;
  1198.          plyInfo->restorePiece1 = movingPiece;
  1199.          position->piece[to] = effectiveNewPiece;
  1200.          position->numberOfPawns[activeColor]--;
  1201.          position->pieceCount +=
  1202.             (newPiece == (Piece) BISHOP ?
  1203.              bishopPieceCountWeight[activeColor][to] :
  1204.              pieceCountWeight[effectiveNewPiece]);
  1205.          position->hashKey ^=
  1206.             GENERATED_KEYTABLE[movingPiece][to] ^
  1207.             GENERATED_KEYTABLE[effectiveNewPiece][to];
  1208.          position->pawnHashKey ^= GENERATED_KEYTABLE[movingPiece][to];
  1209.          addBonusForColor(pieceSquareBonus[effectiveNewPiece][to] -
  1210.                           pieceSquareBonus[movingPiece][to],
  1211.                           position, activeColor);
  1212.          setSquare(position->piecesOfType[position->piece[to]], to);
  1213.       }
  1214.    }
  1215.  
  1216.    else if (pieceType(movingPiece) == KING)
  1217.    {
  1218.       position->king[activeColor] = to;
  1219.  
  1220.       if (distance(from, to) == 2)
  1221.       {
  1222.          const Square rookFrom = rookOrigin[to];
  1223.          const Square rookTo = (Square) ((from + to) >> 1);
  1224.          const Piece movingRook = position->piece[rookFrom];
  1225.  
  1226.          plyInfo->restoreSquare1 = rookFrom;
  1227.          plyInfo->restorePiece1 = movingRook;
  1228.          plyInfo->restoreSquare2 = rookTo;
  1229.          plyInfo->restorePiece2 = position->piece[rookTo];
  1230.          position->piece[rookFrom] = NO_PIECE;
  1231.          position->piece[rookTo] = movingRook;
  1232.          position->halfMoveClock = 0;
  1233.  
  1234.          setSquare(position->piecesOfColor[activeColor], rookTo);
  1235.          clearSquare(position->piecesOfColor[activeColor], rookFrom);
  1236.          setSquare(position->piecesOfType[movingRook], rookTo);
  1237.          clearSquare(position->piecesOfType[movingRook], rookFrom);
  1238.          position->hashKey ^=
  1239.             GENERATED_KEYTABLE[movingRook][rookFrom] ^
  1240.             GENERATED_KEYTABLE[movingRook][rookTo];
  1241.          addBonusForColor(pieceSquareBonus[movingRook][rookTo] -
  1242.                           pieceSquareBonus[movingRook][rookFrom],
  1243.                           position, activeColor);
  1244.  
  1245.          if (getDirectAttackers(position, from, passiveColor,
  1246.                                 position->allPieces) != EMPTY_BITBOARD ||
  1247.              getDirectAttackers(position, rookTo, passiveColor,
  1248.                                 position->allPieces) != EMPTY_BITBOARD)
  1249.          {
  1250.             result = 1;         /* castling move was not legal */
  1251.          }
  1252.       }
  1253.    }
  1254.  
  1255.    setSquare(position->piecesOfType[position->piece[to]], to);
  1256.    position->allPieces =
  1257.       position->piecesOfColor[WHITE] | position->piecesOfColor[BLACK];
  1258.  
  1259.    assert(checkVariation(variation) == 0);
  1260.  
  1261.    return result;
  1262. }
  1263.  
  1264. #define PERSPECTIVE_WHITE
  1265. #include "positionc.c"
  1266. #undef PERSPECTIVE_WHITE
  1267. #include "positionc.c"
  1268.  
  1269. int makeMoveFast(Variation * variation, const Move move)
  1270. {
  1271.    if (variation->singlePosition.activeColor == WHITE)
  1272.    {
  1273.       return makeWhiteMove(variation, move);
  1274.    }
  1275.    else
  1276.    {
  1277.       return makeBlackMove(variation, move);
  1278.    }
  1279. }
  1280.  
  1281. void unmakeLastMove(Variation * variation)
  1282. {
  1283.    Position *position = &variation->singlePosition;
  1284.    const PlyInfo *plyInfo = &variation->plyInfo[--variation->ply];
  1285.    const Move move = plyInfo->currentMove;
  1286.    const Square from = getFromSquare(move);
  1287.    const Square to = getToSquare(move);
  1288.    const Piece newPiece = getNewPiece(move);
  1289.    const Color activeColor = position->activeColor =
  1290.       opponent(position->activeColor);
  1291.  
  1292.    position->enPassantSquare = plyInfo->enPassantSquare;
  1293.    position->hashKey = plyInfo->hashKey;
  1294.  
  1295.    if (from == to)
  1296.    {
  1297.       assert(checkVariation(variation) == 0);
  1298.  
  1299.       return;                   /* Nullmove */
  1300.    }
  1301.  
  1302.    position->pawnHashKey = plyInfo->pawnHashKey;
  1303.    clearSquare(position->piecesOfType[position->piece[to]], to);
  1304.    position->king[activeColor] = plyInfo->kingSquare;
  1305.    position->piece[from] = position->piece[to];
  1306.    position->piece[to] = plyInfo->captured;
  1307.    position->pieceCount = plyInfo->pieceCount;
  1308.  
  1309.    if (newPiece != NO_PIECE)
  1310.    {
  1311.       position->numberOfPawns[activeColor]++;
  1312.       position->piece[plyInfo->restoreSquare1] = plyInfo->restorePiece1;
  1313.    }
  1314.  
  1315.    setSquare(position->piecesOfType[position->piece[from]], from);
  1316.    position->halfMoveClock = plyInfo->halfMoveClock;
  1317.    position->castlingRights = plyInfo->castlingRights;
  1318.    position->piecesOfColor[WHITE] = plyInfo->whitePieces;
  1319.    position->piecesOfColor[BLACK] = plyInfo->blackPieces;
  1320.    position->allPieces = plyInfo->allPieces;
  1321.    position->balance = plyInfo->balance;
  1322.  
  1323.    if (plyInfo->captured != NO_PIECE)
  1324.    {
  1325.       const Color passiveColor = opponent(activeColor);
  1326.  
  1327.       setSquare(position->piecesOfType[plyInfo->captured], to);
  1328.       position->numberOfPieces[passiveColor]++;
  1329.  
  1330.       if (pieceType(plyInfo->captured) == PAWN)
  1331.       {
  1332.          position->numberOfPawns[passiveColor]++;
  1333.       }
  1334.    }
  1335.    else if (to == plyInfo->enPassantSquare &&
  1336.             pieceType(position->piece[from]) == PAWN)
  1337.    {
  1338.       const Color passiveColor = opponent(activeColor);
  1339.  
  1340.       position->piece[plyInfo->restoreSquare1] = plyInfo->restorePiece1;
  1341.       setSquare(position->piecesOfType[plyInfo->restorePiece1],
  1342.                 plyInfo->restoreSquare1);
  1343.       position->numberOfPieces[passiveColor]++;
  1344.       position->numberOfPawns[passiveColor]++;
  1345.    }
  1346.    else if (distance(from, to) == 2 &&
  1347.             pieceType(position->piece[from]) == KING)
  1348.    {
  1349.       position->piece[plyInfo->restoreSquare1] = plyInfo->restorePiece1;
  1350.       position->piece[plyInfo->restoreSquare2] = plyInfo->restorePiece2;
  1351.       setSquare(position->piecesOfType[plyInfo->restorePiece1],
  1352.                 plyInfo->restoreSquare1);
  1353.       clearSquare(position->piecesOfType[plyInfo->restorePiece1],
  1354.                   plyInfo->restoreSquare2);
  1355.    }
  1356.  
  1357.    assert(checkVariation(variation) == 0);
  1358. }
  1359.  
  1360. bool moveIsCheck(const Move move, const Position * position)
  1361. {
  1362.    const Square kingSquare = position->king[opponent(position->activeColor)];
  1363.    const Square from = getFromSquare(move);
  1364.    const Square to = getToSquare(move);
  1365.    const Piece piece = position->piece[from];
  1366.  
  1367.    if (testSquare(generalMoves[QUEEN][kingSquare], from) &&
  1368.        (position->allPieces & squaresBetween[kingSquare][from]) ==
  1369.        EMPTY_BITBOARD &&
  1370.        testSquare(squaresBetween[kingSquare][from], to) == FALSE &&
  1371.        testSquare(squaresBehind[from][kingSquare], to) == FALSE)
  1372.    {
  1373.       /* Detect undiscovered check: */
  1374.  
  1375.       const Color color = position->activeColor;
  1376.       Bitboard batteryPieces;
  1377.       Square square;
  1378.  
  1379.       if (rank(from) == rank(kingSquare) || file(from) == file(kingSquare))
  1380.       {
  1381.          batteryPieces = squaresBehind[from][kingSquare] &
  1382.             (position->piecesOfType[ROOK | color] |
  1383.              position->piecesOfType[QUEEN | color]);
  1384.       }
  1385.       else
  1386.       {
  1387.          batteryPieces = squaresBehind[from][kingSquare] &
  1388.             (position->piecesOfType[BISHOP | color] |
  1389.              position->piecesOfType[QUEEN | color]);
  1390.       }
  1391.  
  1392.       ITERATE_BITBOARD(&batteryPieces, square)
  1393.       {
  1394.          if ((squaresBetween[square][kingSquare] & position->allPieces) ==
  1395.              minValue[from])
  1396.          {
  1397.             return TRUE;
  1398.          }
  1399.       }
  1400.    }
  1401.  
  1402.    /* No undiscovered check: */
  1403.  
  1404.    if (piece & PP_SLIDING_PIECE)
  1405.    {
  1406.       return (bool)
  1407.          (testSquare(generalMoves[pieceType(piece)][to], kingSquare) &&
  1408.           (position->allPieces & squaresBetween[kingSquare][to]) ==
  1409.           EMPTY_BITBOARD);
  1410.    }
  1411.    else if (pieceType(piece) == KNIGHT)
  1412.    {
  1413.       return (testSquare(generalMoves[KNIGHT][kingSquare], to) !=
  1414.               EMPTY_BITBOARD);
  1415.    }
  1416.    else if (pieceType(piece) == PAWN)
  1417.    {
  1418.       const Piece newPiece = getNewPiece(move);
  1419.  
  1420.       if (newPiece == NO_PIECE)
  1421.       {
  1422.          if (testSquare(generalMoves[piece][to], kingSquare) != FALSE)
  1423.          {
  1424.             return TRUE;
  1425.          }
  1426.  
  1427.          if (to == position->enPassantSquare)
  1428.          {
  1429.             const Square captureSquare =
  1430.                (Square) (to + (rank(from) - rank(to)) * 8);
  1431.  
  1432.             if (testSquare(generalMoves[QUEEN][kingSquare], captureSquare) &&
  1433.                 (squaresBetween[captureSquare][kingSquare] &
  1434.                  position->allPieces) == EMPTY_BITBOARD)
  1435.             {
  1436.                const Color color = position->activeColor;
  1437.                Bitboard batteryPieces;
  1438.                const Bitboard blockers = minValue[to] |
  1439.                   (position->allPieces & maxValue[captureSquare] &
  1440.                    maxValue[from]);
  1441.                Square square;
  1442.  
  1443.                if (rank(captureSquare) == rank(kingSquare) ||
  1444.                    file(captureSquare) == file(kingSquare))
  1445.                {
  1446.                   batteryPieces = squaresBehind[captureSquare][kingSquare] &
  1447.                      (position->piecesOfType[ROOK | color] |
  1448.                       position->piecesOfType[QUEEN | color]);
  1449.                }
  1450.                else
  1451.                {
  1452.                   batteryPieces = squaresBehind[captureSquare][kingSquare] &
  1453.                      (position->piecesOfType[BISHOP | color] |
  1454.                       position->piecesOfType[QUEEN | color]);
  1455.                }
  1456.  
  1457.                ITERATE_BITBOARD(&batteryPieces, square)
  1458.                {
  1459.                   if ((squaresBetween[kingSquare][square] & blockers) ==
  1460.                       EMPTY_BITBOARD)
  1461.                   {
  1462.                      return TRUE;
  1463.                   }
  1464.                }
  1465.             }
  1466.          }
  1467.       }
  1468.       else
  1469.       {
  1470.          if (newPiece & PP_SLIDING_PIECE)
  1471.          {
  1472.             const Bitboard blockers = position->allPieces & maxValue[from];
  1473.  
  1474.             return (bool)
  1475.                (testSquare(generalMoves[newPiece][to], kingSquare) &&
  1476.                 (blockers & squaresBetween[kingSquare][to]) ==
  1477.                 EMPTY_BITBOARD);
  1478.          }
  1479.          else
  1480.          {
  1481.             return (testSquare(generalMoves[KNIGHT][kingSquare], to) !=
  1482.                     EMPTY_BITBOARD);
  1483.          }
  1484.       }
  1485.    }
  1486.    else if (pieceType(piece) == KING && abs(to - from) == 2)
  1487.    {
  1488.       const Bitboard blockers = position->allPieces & maxValue[from];
  1489.       const int rookSquare = (to + from) / 2;
  1490.  
  1491.       return (bool)
  1492.          (testSquare(generalMoves[ROOK][rookSquare], kingSquare) &&
  1493.           (blockers & squaresBetween[kingSquare][rookSquare]) ==
  1494.           EMPTY_BITBOARD);
  1495.    }
  1496.  
  1497.    return FALSE;
  1498. }
  1499.  
  1500. int checkConsistency(const Position * position)
  1501. {
  1502.    Square square;
  1503.    int numPieces[2], numPawns[2], value[2], i;
  1504.    int openingValue[2], endgameValue[2];
  1505.    INT32 balance = 0;
  1506.    Bitboard temp;
  1507.    BYTE obstacles[NUM_LANES];
  1508.    UINT32 materialSignature = calculateMaterialSignature(position);
  1509.  
  1510.    numPieces[WHITE] = numPieces[BLACK] = 0;
  1511.    numPawns[WHITE] = numPawns[BLACK] = 0;
  1512.    memset(obstacles, 0x00, NUM_LANES);
  1513.    value[WHITE] = value[BLACK] = 0;
  1514.    openingValue[WHITE] = openingValue[BLACK] = 0;
  1515.    endgameValue[WHITE] = endgameValue[BLACK] = 0;
  1516.  
  1517.    assert(position->activeColor == WHITE || position->activeColor == BLACK);
  1518.    assert(getMaterialSignatureFromPieceCount(position) == materialSignature);
  1519.  
  1520.    {
  1521.       int calculatedNumWhiteQueens;
  1522.       int calculatedNumWhiteRooks;
  1523.       int calculatedNumWhiteLightSquareBishops;
  1524.       int calculatedNumWhiteDarkSquareBishops;
  1525.       int calculatedNumWhiteKnights;
  1526.       int calculatedNumWhitePawns;
  1527.       int calculatedNumBlackQueens;
  1528.       int calculatedNumBlackRooks;
  1529.       int calculatedNumBlackLightSquareBishops;
  1530.       int calculatedNumBlackDarkSquareBishops;
  1531.       int calculatedNumBlackKnights;
  1532.       int calculatedNumBlackPawns;
  1533.  
  1534.       getPieceCounters(materialSignature,
  1535.                        &calculatedNumWhiteQueens, &calculatedNumWhiteRooks,
  1536.                        &calculatedNumWhiteLightSquareBishops,
  1537.                        &calculatedNumWhiteDarkSquareBishops,
  1538.                        &calculatedNumWhiteKnights,
  1539.                        &calculatedNumWhitePawns, &calculatedNumBlackQueens,
  1540.                        &calculatedNumBlackRooks,
  1541.                        &calculatedNumBlackLightSquareBishops,
  1542.                        &calculatedNumBlackDarkSquareBishops,
  1543.                        &calculatedNumBlackKnights, &calculatedNumBlackPawns);
  1544.  
  1545.       assert(getPieceCount(position, WHITE_QUEEN) > 1 ||
  1546.              getPieceCount(position, WHITE_QUEEN) ==
  1547.              calculatedNumWhiteQueens);
  1548.       assert(getPieceCount(position, WHITE_ROOK) > 2 ||
  1549.              getPieceCount(position, WHITE_ROOK) == calculatedNumWhiteRooks);
  1550.       assert(getPieceCount(position, WHITE_BISHOP_LIGHT) > 1 ||
  1551.              getPieceCount(position, WHITE_BISHOP_LIGHT) ==
  1552.              calculatedNumWhiteLightSquareBishops);
  1553.       assert(getPieceCount(position, WHITE_BISHOP_DARK) > 1 ||
  1554.              getPieceCount(position, WHITE_BISHOP_DARK) ==
  1555.              calculatedNumWhiteDarkSquareBishops);
  1556.       assert(getPieceCount(position, WHITE_KNIGHT) > 2 ||
  1557.              getPieceCount(position, WHITE_KNIGHT) ==
  1558.              calculatedNumWhiteKnights);
  1559.       assert(position->numberOfPawns[WHITE] == calculatedNumWhitePawns);
  1560.       assert(getPieceCount(position, BLACK_QUEEN) > 1 ||
  1561.              getPieceCount(position, BLACK_QUEEN) ==
  1562.              calculatedNumBlackQueens);
  1563.       assert(getPieceCount(position, BLACK_ROOK) > 2 ||
  1564.              getPieceCount(position, BLACK_ROOK) == calculatedNumBlackRooks);
  1565.       assert(getPieceCount(position, BLACK_BISHOP_LIGHT) > 1 ||
  1566.              getPieceCount(position, BLACK_BISHOP_LIGHT) ==
  1567.              calculatedNumBlackLightSquareBishops);
  1568.       assert(getPieceCount(position, BLACK_BISHOP_DARK) > 1 ||
  1569.              getPieceCount(position, BLACK_BISHOP_DARK) ==
  1570.              calculatedNumBlackDarkSquareBishops);
  1571.       assert(getPieceCount(position, BLACK_KNIGHT) > 2 ||
  1572.              getPieceCount(position, BLACK_KNIGHT) ==
  1573.              calculatedNumBlackKnights);
  1574.       assert(position->numberOfPawns[BLACK] == calculatedNumBlackPawns);
  1575.  
  1576.       if (getPieceCount(position, WHITE_QUEEN) <= 1 &&
  1577.           getPieceCount(position, WHITE_ROOK) <= 2 &&
  1578.           getPieceCount(position, WHITE_BISHOP_LIGHT) <= 1 &&
  1579.           getPieceCount(position, WHITE_BISHOP_DARK) <= 1 &&
  1580.           getPieceCount(position, WHITE_KNIGHT) <= 2 &&
  1581.           getPieceCount(position, BLACK_QUEEN) <= 1 &&
  1582.           getPieceCount(position, BLACK_ROOK) <= 2 &&
  1583.           getPieceCount(position, BLACK_BISHOP_LIGHT) <= 1 &&
  1584.           getPieceCount(position, BLACK_BISHOP_DARK) <= 1 &&
  1585.           getPieceCount(position, BLACK_KNIGHT) <= 2)
  1586.       {
  1587.          const MaterialInfo *mi = &materialInfo[materialSignature];
  1588.  
  1589.          if (mi->materialBalance != materialBalance(position))
  1590.          {
  1591.             logDebug("mimb=%d cmb=%d\n", mi->materialBalance,
  1592.                      materialBalance(position));
  1593.             dumpPosition(position);
  1594.          }
  1595.  
  1596.          assert(mi->materialBalance == materialBalance(position));
  1597.          assert(mi->phaseIndex == phaseIndex(position));
  1598.       }
  1599.    }
  1600.  
  1601.    if (position->castlingRights & WHITE_00)
  1602.    {
  1603.       assert(position->piece[E1] == WHITE_KING);
  1604.       assert(position->piece[H1] == WHITE_ROOK);
  1605.    }
  1606.  
  1607.    if (position->castlingRights & WHITE_000)
  1608.    {
  1609.       assert(position->piece[E1] == WHITE_KING);
  1610.       assert(position->piece[A1] == WHITE_ROOK);
  1611.    }
  1612.  
  1613.    if (position->castlingRights & BLACK_00)
  1614.    {
  1615.       assert(position->piece[E8] == BLACK_KING);
  1616.       assert(position->piece[H8] == BLACK_ROOK);
  1617.    }
  1618.  
  1619.    if (position->castlingRights & BLACK_000)
  1620.    {
  1621.       assert(position->piece[E8] == BLACK_KING);
  1622.       assert(position->piece[A8] == BLACK_ROOK);
  1623.    }
  1624.  
  1625.    assert(position->enPassantSquare == NO_SQUARE ||
  1626.           squareIsValid(position->enPassantSquare));
  1627.  
  1628.    if (position->enPassantSquare != NO_SQUARE)
  1629.    {
  1630.       if (position->activeColor == WHITE)
  1631.       {
  1632.          assert(rank(position->enPassantSquare) == RANK_6);
  1633.          assert(position->piece[position->enPassantSquare - 8] == BLACK_PAWN);
  1634.       }
  1635.       else
  1636.       {
  1637.          assert(rank(position->enPassantSquare) == RANK_3);
  1638.          assert(position->piece[position->enPassantSquare + 8] == WHITE_PAWN);
  1639.       }
  1640.    }
  1641.  
  1642.    assert((position->piecesOfColor[WHITE] ^ position->piecesOfColor[BLACK]) ==
  1643.           position->allPieces);
  1644.  
  1645.    temp = EMPTY_BITBOARD;
  1646.  
  1647.    for (i = 1; i <= 0x0F; i++)
  1648.    {
  1649.       temp ^= position->piecesOfType[i];
  1650.    }
  1651.  
  1652.    assert(temp == position->allPieces);
  1653.  
  1654.    assert(squareIsValid(position->king[WHITE]));
  1655.    assert(position->piece[position->king[WHITE]] == WHITE_KING);
  1656.    assert(squareIsValid(position->king[BLACK]));
  1657.    assert(position->piece[position->king[BLACK]] == BLACK_KING);
  1658.    assert(testSquare
  1659.           (position->piecesOfType[WHITE_KING], position->king[WHITE]));
  1660.    assert(getNumberOfSetSquares(position->piecesOfType[WHITE_KING]) == 1);
  1661.    assert(testSquare
  1662.           (position->piecesOfType[BLACK_KING], position->king[BLACK]));
  1663.    assert(getNumberOfSetSquares(position->piecesOfType[BLACK_KING]) == 1);
  1664.  
  1665.    assert(getNumberOfSetSquares(position->piecesOfType[WHITE_QUEEN]) ==
  1666.           getPieceCount(position, WHITE_QUEEN));
  1667.    assert(getNumberOfSetSquares(position->piecesOfType[WHITE_ROOK]) ==
  1668.           getPieceCount(position, WHITE_ROOK));
  1669.    assert(getNumberOfSetSquares
  1670.           (position->piecesOfType[WHITE_BISHOP] & lightSquares) ==
  1671.           getPieceCount(position, WHITE_BISHOP_LIGHT));
  1672.    assert(getNumberOfSetSquares
  1673.           (position->piecesOfType[WHITE_BISHOP] & darkSquares) ==
  1674.           getPieceCount(position, WHITE_BISHOP_DARK));
  1675.    assert(getNumberOfSetSquares(position->piecesOfType[WHITE_KNIGHT]) ==
  1676.           getPieceCount(position, WHITE_KNIGHT));
  1677.    assert(getNumberOfSetSquares(position->piecesOfType[BLACK_QUEEN]) ==
  1678.           getPieceCount(position, BLACK_QUEEN));
  1679.    assert(getNumberOfSetSquares(position->piecesOfType[BLACK_ROOK]) ==
  1680.           getPieceCount(position, BLACK_ROOK));
  1681.    assert(getNumberOfSetSquares
  1682.           (position->piecesOfType[BLACK_BISHOP] & lightSquares) ==
  1683.           getPieceCount(position, BLACK_BISHOP_LIGHT));
  1684.    assert(getNumberOfSetSquares
  1685.           (position->piecesOfType[BLACK_BISHOP] & darkSquares) ==
  1686.           getPieceCount(position, BLACK_BISHOP_DARK));
  1687.    assert(getNumberOfSetSquares(position->piecesOfType[BLACK_KNIGHT]) ==
  1688.           getPieceCount(position, BLACK_KNIGHT));
  1689.  
  1690.    ITERATE(square)
  1691.    {
  1692.       Piece piece = position->piece[square];
  1693.       PieceType pieceType = pieceType(piece);
  1694.       Color color = pieceColor(piece);
  1695.  
  1696.       assert(piece >= 0 && piece <= 15);
  1697.  
  1698.       if (piece != NO_PIECE)
  1699.       {
  1700.          numPieces[color]++;
  1701.          setObstacleSquare(square, obstacles);
  1702.  
  1703.          assert(testSquare(position->allPieces, square));
  1704.          assert(testSquare(position->piecesOfColor[color], square));
  1705.          assert(testSquare(position->piecesOfType[piece], square));
  1706.  
  1707.          if (pieceType == PAWN)
  1708.          {
  1709.             numPawns[color]++;
  1710.          }
  1711.  
  1712.          if (pieceType != KING)
  1713.          {
  1714.             value[color] += basicValue[piece];
  1715.          }
  1716.  
  1717.          openingValue[color] +=
  1718.             getOpeningValue(pieceSquareBonus[piece][square]);
  1719.          endgameValue[color] +=
  1720.             getEndgameValue(pieceSquareBonus[piece][square]);
  1721.  
  1722.          if (color == WHITE)
  1723.          {
  1724.             balance += pieceSquareBonus[piece][square];
  1725.          }
  1726.          else
  1727.          {
  1728.             balance -= pieceSquareBonus[piece][square];
  1729.          }
  1730.       }
  1731.       else
  1732.       {
  1733.          assert(testSquare(position->allPieces, square) == FALSE);
  1734.          assert(testSquare(position->piecesOfColor[WHITE], square) == FALSE);
  1735.          assert(testSquare(position->piecesOfColor[BLACK], square) == FALSE);
  1736.       }
  1737.    }
  1738.  
  1739.    assert(numPieces[WHITE] == position->numberOfPieces[WHITE]);
  1740.    assert(numPieces[WHITE] >= 1);
  1741.    assert(numPieces[WHITE] <= 16);
  1742.    assert(numPieces[WHITE] ==
  1743.           getNumberOfSetSquares(position->piecesOfColor[WHITE]));
  1744.    assert(numPieces[BLACK] == position->numberOfPieces[BLACK]);
  1745.    assert(numPieces[BLACK] >= 1);
  1746.    assert(numPieces[BLACK] <= 16);
  1747.    assert(numPieces[BLACK] ==
  1748.           getNumberOfSetSquares(position->piecesOfColor[BLACK]));
  1749.  
  1750.    assert(numPawns[WHITE] == position->numberOfPawns[WHITE]);
  1751.    assert(numPawns[WHITE] >= 0);
  1752.    assert(numPawns[WHITE] <= 8);
  1753.    assert(numPawns[WHITE] ==
  1754.           getNumberOfSetSquares(position->piecesOfType[WHITE_PAWN]));
  1755.    assert(numPawns[BLACK] == position->numberOfPawns[BLACK]);
  1756.    assert(numPawns[BLACK] >= 0);
  1757.    assert(numPawns[BLACK] <= 8);
  1758.    assert(numPawns[BLACK] ==
  1759.           getNumberOfSetSquares(position->piecesOfType[BLACK_PAWN]));
  1760.    assert(balance == position->balance);
  1761.  
  1762.    assert(calculateHashKey(position) == position->hashKey);
  1763.    assert(calculatePawnHashKey(position) == position->pawnHashKey);
  1764.  
  1765.    return 0;
  1766. }
  1767.  
  1768. bool positionIsLegal(const Position * position)
  1769. {
  1770.    Square square;
  1771.    int numPieces[2], numPawns[2], value[2], i;
  1772.    Bitboard temp;
  1773.    BYTE obstacles[NUM_LANES];
  1774.  
  1775.    numPieces[WHITE] = numPieces[BLACK] = 0;
  1776.    numPawns[WHITE] = numPawns[BLACK] = 0;
  1777.    memset(obstacles, 0x00, NUM_LANES);
  1778.    value[WHITE] = value[BLACK] = 0;
  1779.  
  1780.    if (position->activeColor != WHITE && position->activeColor != BLACK)
  1781.    {
  1782.       return FALSE;
  1783.    }
  1784.  
  1785.    if (position->castlingRights & WHITE_00)
  1786.    {
  1787.       if (position->piece[E1] != WHITE_KING)
  1788.       {
  1789.          return FALSE;
  1790.       }
  1791.  
  1792.       if (position->piece[H1] != WHITE_ROOK)
  1793.       {
  1794.          return FALSE;
  1795.       }
  1796.    }
  1797.  
  1798.    if (position->castlingRights & WHITE_000)
  1799.    {
  1800.       if (position->piece[E1] != WHITE_KING)
  1801.       {
  1802.          return FALSE;
  1803.       }
  1804.  
  1805.       if (position->piece[A1] != WHITE_ROOK)
  1806.       {
  1807.          return FALSE;
  1808.       }
  1809.    }
  1810.  
  1811.    if (position->castlingRights & BLACK_00)
  1812.    {
  1813.       if (position->piece[E8] != BLACK_KING)
  1814.       {
  1815.          return FALSE;
  1816.       }
  1817.  
  1818.       if (position->piece[H8] != BLACK_ROOK)
  1819.       {
  1820.          return FALSE;
  1821.       }
  1822.    }
  1823.  
  1824.    if (position->castlingRights & BLACK_000)
  1825.    {
  1826.       if (position->piece[E8] != BLACK_KING)
  1827.       {
  1828.          return FALSE;
  1829.       }
  1830.  
  1831.       if (position->piece[A8] != BLACK_ROOK)
  1832.       {
  1833.          return FALSE;
  1834.       }
  1835.    }
  1836.  
  1837.    if (position->enPassantSquare != NO_SQUARE)
  1838.    {
  1839.       if (squareIsValid(position->enPassantSquare) == FALSE)
  1840.       {
  1841.          return FALSE;
  1842.       }
  1843.  
  1844.       if (position->activeColor == WHITE)
  1845.       {
  1846.          if (rank(position->enPassantSquare) != RANK_6)
  1847.          {
  1848.             return FALSE;
  1849.          }
  1850.  
  1851.          if (position->piece[position->enPassantSquare - 8] != BLACK_PAWN)
  1852.          {
  1853.             return FALSE;
  1854.          }
  1855.       }
  1856.       else
  1857.       {
  1858.          if (rank(position->enPassantSquare) != RANK_3)
  1859.          {
  1860.             return FALSE;
  1861.          }
  1862.  
  1863.          if (position->piece[position->enPassantSquare + 8] != WHITE_PAWN)
  1864.          {
  1865.             return FALSE;
  1866.          }
  1867.       }
  1868.    }
  1869.  
  1870.    if ((position->piecesOfColor[WHITE] ^ position->piecesOfColor[BLACK]) !=
  1871.        position->allPieces)
  1872.    {
  1873.       return FALSE;
  1874.    }
  1875.  
  1876.    temp = EMPTY_BITBOARD;
  1877.  
  1878.    for (i = 1; i <= 0x0F; i++)
  1879.    {
  1880.       temp ^= position->piecesOfType[i];
  1881.    }
  1882.  
  1883.    /*
  1884.       dumpBitboard(temp, "temp");
  1885.       dumpBitboard(position->allPieces, "allPieces");
  1886.     */
  1887.  
  1888.    if (temp != position->allPieces)
  1889.    {
  1890.       return FALSE;
  1891.    }
  1892.  
  1893.    if (squareIsValid(position->king[WHITE]) == FALSE)
  1894.    {
  1895.       return FALSE;
  1896.    }
  1897.  
  1898.    if (position->piece[position->king[WHITE]] != WHITE_KING)
  1899.    {
  1900.       return FALSE;
  1901.    }
  1902.  
  1903.    if (squareIsValid(position->king[BLACK]) == FALSE)
  1904.    {
  1905.       return FALSE;
  1906.    }
  1907.  
  1908.    if (position->piece[position->king[BLACK]] != BLACK_KING)
  1909.    {
  1910.       return FALSE;
  1911.    }
  1912.  
  1913.    if (distance(position->king[WHITE], position->king[BLACK]) < 2)
  1914.    {
  1915.       return FALSE;
  1916.    }
  1917.  
  1918.    if (testSquare(position->piecesOfType[WHITE_KING],
  1919.                   position->king[WHITE]) == FALSE)
  1920.    {
  1921.       return FALSE;
  1922.    }
  1923.  
  1924.    if (getNumberOfSetSquares(position->piecesOfType[WHITE_KING]) != 1)
  1925.    {
  1926.       return FALSE;
  1927.    }
  1928.  
  1929.    if (testSquare(position->piecesOfType[BLACK_KING],
  1930.                   position->king[BLACK]) == FALSE)
  1931.    {
  1932.       return FALSE;
  1933.    }
  1934.  
  1935.    if (getNumberOfSetSquares(position->piecesOfType[BLACK_KING]) != 1)
  1936.    {
  1937.       return FALSE;
  1938.    }
  1939.  
  1940.    ITERATE(square)
  1941.    {
  1942.       Piece piece = position->piece[square];
  1943.       PieceType pieceType = pieceType(piece);
  1944.       Color color = pieceColor(piece);
  1945.  
  1946.       if (piece < 0 || piece > 15)
  1947.       {
  1948.          return FALSE;
  1949.       }
  1950.  
  1951.       if (piece != NO_PIECE)
  1952.       {
  1953.          numPieces[color]++;
  1954.          setObstacleSquare(square, obstacles);
  1955.  
  1956.          if (testSquare(position->allPieces, square) == FALSE)
  1957.          {
  1958.             return FALSE;
  1959.          }
  1960.  
  1961.          if (testSquare(position->piecesOfColor[color], square) == FALSE)
  1962.          {
  1963.             return FALSE;
  1964.          }
  1965.  
  1966.          if (testSquare(position->piecesOfType[piece], square) == FALSE)
  1967.          {
  1968.             return FALSE;
  1969.          }
  1970.  
  1971.          if (pieceType == PAWN)
  1972.          {
  1973.             numPawns[color]++;
  1974.          }
  1975.  
  1976.          if (pieceType != KING)
  1977.          {
  1978.             value[color] += basicValue[piece];
  1979.          }
  1980.       }
  1981.       else
  1982.       {
  1983.          if (testSquare(position->allPieces, square))
  1984.          {
  1985.             return FALSE;
  1986.          }
  1987.  
  1988.          if (testSquare(position->piecesOfColor[WHITE], square))
  1989.          {
  1990.             return FALSE;
  1991.          }
  1992.  
  1993.          if (testSquare(position->piecesOfColor[BLACK], square))
  1994.          {
  1995.             return FALSE;
  1996.          }
  1997.       }
  1998.    }
  1999.  
  2000.    if (numPieces[WHITE] < 1)
  2001.    {
  2002.       return FALSE;
  2003.    }
  2004.  
  2005.    if (numPieces[WHITE] > 16)
  2006.    {
  2007.       return FALSE;
  2008.    }
  2009.  
  2010.    if (numPieces[BLACK] < 1)
  2011.    {
  2012.       return FALSE;
  2013.    }
  2014.  
  2015.    if (numPieces[BLACK] > 16)
  2016.    {
  2017.       return FALSE;
  2018.    }
  2019.  
  2020.    if (numPawns[WHITE] < 0)
  2021.    {
  2022.       return FALSE;
  2023.    }
  2024.  
  2025.    if (numPawns[WHITE] > 8)
  2026.    {
  2027.       return FALSE;
  2028.    }
  2029.  
  2030.    if (numPawns[BLACK] < 0)
  2031.    {
  2032.       return FALSE;
  2033.    }
  2034.  
  2035.    if (numPawns[BLACK] > 8)
  2036.    {
  2037.       return FALSE;
  2038.    }
  2039.  
  2040.    return TRUE;
  2041. }
  2042.  
  2043. bool positionsAreIdentical(const Position * position1,
  2044.                            const Position * position2)
  2045. {
  2046.    Square square;
  2047.  
  2048.    if (position1->activeColor != position2->activeColor ||
  2049.        position1->castlingRights != position2->castlingRights ||
  2050.        position1->enPassantSquare != position2->enPassantSquare)
  2051.    {
  2052.       logDebug("activeColor1=%d activeColor2=%d\n",
  2053.                position1->activeColor, position2->activeColor);
  2054.       logDebug("castlingRights1=%d castlingRights2=%d\n",
  2055.                position1->castlingRights, position2->castlingRights);
  2056.       logDebug("enPassantSquare1=%d enPassantSquare2=%d\n",
  2057.                position1->enPassantSquare, position2->enPassantSquare);
  2058.  
  2059.       return FALSE;
  2060.    }
  2061.  
  2062.    if (position1->halfMoveClock != position2->halfMoveClock ||
  2063.        position1->moveNumber != position2->moveNumber)
  2064.    {
  2065.       logDebug("halfMoveClock1=%d halfMoveClock2=%d\n",
  2066.                position1->halfMoveClock, position2->halfMoveClock);
  2067.       logDebug("moveNumber1=%d moveNumber2=%d\n",
  2068.                position1->moveNumber, position2->moveNumber);
  2069.  
  2070.       return FALSE;
  2071.    }
  2072.  
  2073.    ITERATE(square)
  2074.    {
  2075.       if (position1->piece[square] != position2->piece[square])
  2076.       {
  2077.          logDebug("piece diff!\n");
  2078.          dumpSquare(square);
  2079.  
  2080.          return FALSE;
  2081.       }
  2082.    }
  2083.  
  2084.    return (bool) (checkConsistency(position1) == 0);
  2085. }
  2086.  
  2087. static void initializeKrqSignatureTable()
  2088. {
  2089.    UINT32 qc, rc, kc;
  2090.  
  2091.    for (qc = 0; qc <= 9; qc++)
  2092.    {
  2093.       for (rc = 0; rc <= 10; rc++)
  2094.       {
  2095.          for (kc = 0; kc <= 10; kc++)
  2096.          {
  2097.             const int index = (qc << pieceCountShift[WHITE_QUEEN]) +
  2098.                (rc << pieceCountShift[WHITE_ROOK]) +
  2099.                (kc << pieceCountShift[WHITE_KNIGHT]);
  2100.  
  2101.             assert(index >= 0 && index < 4096);
  2102.  
  2103.             krqIndexWhite[index] =
  2104.                getMaterialSignature(qc, rc, 0, 0, kc, 0, 0, 0, 0, 0, 0, 0);
  2105.             krqIndexBlack[index] =
  2106.                getMaterialSignature(0, 0, 0, 0, 0, 0, qc, rc, 0, 0, kc, 0);
  2107.          }
  2108.       }
  2109.    }
  2110. }
  2111.  
  2112. static void initializeBbpSignatureTable()
  2113. {
  2114.    UINT32 pc, dc, lc;
  2115.  
  2116.    for (pc = 0; pc <= 8; pc++)
  2117.    {
  2118.       for (dc = 0; dc <= 9; dc++)
  2119.       {
  2120.          for (lc = 0; lc <= 9; lc++)
  2121.          {
  2122.             const int index =
  2123.                (lc << (pieceCountShift[WHITE_BISHOP_LIGHT] - 8)) +
  2124.                (dc << (pieceCountShift[WHITE_BISHOP_DARK] - 8)) + pc;
  2125.  
  2126.             assert(index >= 0 && index < 4096);
  2127.  
  2128.             bbpIndexWhite[index] =
  2129.                getMaterialSignature(0, 0, lc, dc, 0, pc, 0, 0, 0, 0, 0, 0);
  2130.             bbpIndexBlack[index] =
  2131.                getMaterialSignature(0, 0, 0, 0, 0, 0, 0, 0, lc, dc, 0, pc);
  2132.          }
  2133.       }
  2134.    }
  2135. }
  2136.  
  2137. int initializeModulePosition()
  2138. {
  2139.    Square square;
  2140.    int i;
  2141.  
  2142.    ITERATE(square)
  2143.    {
  2144.       remainingCastlings[square] = (WHITE_00 | WHITE_000 |
  2145.                                     BLACK_00 | BLACK_000);
  2146.  
  2147.       switch (square)
  2148.       {
  2149.       case A1:
  2150.          remainingCastlings[square] -= WHITE_000;
  2151.          break;
  2152.  
  2153.       case E1:
  2154.          remainingCastlings[square] -= WHITE_000;
  2155.          remainingCastlings[square] -= WHITE_00;
  2156.          break;
  2157.  
  2158.       case H1:
  2159.          remainingCastlings[square] -= WHITE_00;
  2160.          break;
  2161.  
  2162.       case A8:
  2163.          remainingCastlings[square] -= BLACK_000;
  2164.          break;
  2165.  
  2166.       case E8:
  2167.          remainingCastlings[square] -= BLACK_000;
  2168.          remainingCastlings[square] -= BLACK_00;
  2169.          break;
  2170.  
  2171.       case H8:
  2172.          remainingCastlings[square] -= BLACK_00;
  2173.          break;
  2174.  
  2175.       default:
  2176.          break;
  2177.       }
  2178.    }
  2179.  
  2180.    rookOrigin[C1] = A1;
  2181.    rookOrigin[G1] = H1;
  2182.    rookOrigin[C8] = A8;
  2183.    rookOrigin[G8] = H8;
  2184.  
  2185.    basicValue[NO_PIECE] = 0;
  2186.    basicValue[WHITE_KING] = basicValue[BLACK_KING] = -VALUE_MATED;
  2187.    basicValue[WHITE_QUEEN] = basicValue[BLACK_QUEEN] =
  2188.       max(VALUE_QUEEN_OPENING, VALUE_QUEEN_ENDGAME);
  2189.    basicValue[WHITE_ROOK] = basicValue[BLACK_ROOK] =
  2190.       max(VALUE_ROOK_OPENING, VALUE_ROOK_ENDGAME);
  2191.    basicValue[WHITE_BISHOP] = basicValue[BLACK_BISHOP] =
  2192.       max(VALUE_BISHOP_OPENING, VALUE_BISHOP_ENDGAME);
  2193.    basicValue[WHITE_KNIGHT] = basicValue[BLACK_KNIGHT] =
  2194.       max(VALUE_KNIGHT_OPENING, VALUE_KNIGHT_ENDGAME);
  2195.    basicValue[WHITE_PAWN] = basicValue[BLACK_PAWN] =
  2196.       max(VALUE_PAWN_OPENING, VALUE_PAWN_ENDGAME);
  2197.  
  2198.    /*logDebug("size of Variation: %d bytes\n", sizeof(Variation)); */
  2199.  
  2200.    pieceCountShift[WHITE_KING] = 40;
  2201.    pieceCountShift[WHITE_QUEEN] = 0;
  2202.    pieceCountShift[WHITE_ROOK] = 4;
  2203.    pieceCountShift[WHITE_KNIGHT] = 8;
  2204.    pieceCountShift[WHITE_BISHOP_LIGHT] = 12;
  2205.    pieceCountShift[WHITE_BISHOP_DARK] = 16;
  2206.    pieceCountShift[WHITE_PAWN] = 40;
  2207.    pieceCountShift[BLACK_KING] = 40;
  2208.    pieceCountShift[BLACK_QUEEN] = 20;
  2209.    pieceCountShift[BLACK_ROOK] = 24;
  2210.    pieceCountShift[BLACK_KNIGHT] = 28;
  2211.    pieceCountShift[BLACK_BISHOP_LIGHT] = 32;
  2212.    pieceCountShift[BLACK_BISHOP_DARK] = 36;
  2213.    pieceCountShift[BLACK_PAWN] = 40;
  2214.  
  2215.    for (i = 0; i < 16; i++)
  2216.    {
  2217.       pieceCountWeight[i] =
  2218.          (pieceCountShift[i] < 40 ? ((UINT64) (1)) << pieceCountShift[i] : 0);
  2219.  
  2220.       /* logDebug("pcw(%d) = %lu (%d)\n", i, pieceCountWeight[i], pieceCountShift[i]); */
  2221.    }
  2222.  
  2223.    ITERATE(square)
  2224.    {
  2225.       if (testSquare(darkSquares, square))
  2226.       {
  2227.          bishopPieceCountWeight[WHITE][square] =
  2228.             pieceCountWeight[WHITE_BISHOP_DARK];
  2229.          bishopPieceCountWeight[BLACK][square] =
  2230.             pieceCountWeight[BLACK_BISHOP_DARK];
  2231.       }
  2232.       else
  2233.       {
  2234.          bishopPieceCountWeight[WHITE][square] =
  2235.             pieceCountWeight[WHITE_BISHOP_LIGHT];
  2236.          bishopPieceCountWeight[BLACK][square] =
  2237.             pieceCountWeight[BLACK_BISHOP_LIGHT];
  2238.       }
  2239.    }
  2240.  
  2241.    initializeKrqSignatureTable();
  2242.    initializeBbpSignatureTable();
  2243.  
  2244.    return 0;
  2245. }
  2246.  
  2247. static int checkMove(Square from, Square to, Piece newPiece,
  2248.                      Variation * variation)
  2249. {
  2250.    Move move = getPackedMove(from, to, newPiece);
  2251.  
  2252.    makeMove(variation, move);
  2253.    assert(checkConsistency(&variation->singlePosition) == 0);
  2254.  
  2255.    return 0;
  2256. }
  2257.  
  2258. static int testPawnMoves()
  2259. {
  2260.    Variation variation;
  2261.  
  2262.    initializeVariation(&variation, FEN_GAMESTART);
  2263.    assert(checkConsistency(&variation.singlePosition) == 0);
  2264.  
  2265.    checkMove(E2, E4, NO_PIECE, &variation);
  2266.    assert(variation.singlePosition.enPassantSquare == E3);
  2267.    checkMove(D7, D5, NO_PIECE, &variation);
  2268.    assert(variation.singlePosition.enPassantSquare == D6);
  2269.  
  2270.    checkMove(E4, D5, NO_PIECE, &variation);
  2271.    assert(variation.singlePosition.enPassantSquare == NO_SQUARE);
  2272.    checkMove(D8, D5, NO_PIECE, &variation);
  2273.  
  2274.    checkMove(D2, D4, NO_PIECE, &variation);
  2275.    checkMove(D5, D8, NO_PIECE, &variation);
  2276.  
  2277.    checkMove(D4, D5, NO_PIECE, &variation);
  2278.    checkMove(C7, C5, NO_PIECE, &variation);
  2279.    assert(variation.singlePosition.enPassantSquare == C6);
  2280.  
  2281.    checkMove(D5, C6, NO_PIECE, &variation);
  2282.    checkMove(E7, E5, NO_PIECE, &variation);
  2283.  
  2284.    checkMove(C6, B7, NO_PIECE, &variation);
  2285.    checkMove(E5, E4, NO_PIECE, &variation);
  2286.  
  2287.    checkMove(F2, F4, NO_PIECE, &variation);
  2288.    assert(variation.singlePosition.enPassantSquare == F3);
  2289.    checkMove(E4, F3, NO_PIECE, &variation);
  2290.  
  2291.    checkMove(B7, C8, WHITE_ROOK, &variation);
  2292.    checkMove(F3, G2, NO_PIECE, &variation);
  2293.  
  2294.    checkMove(C8, B8, NO_PIECE, &variation);
  2295.    checkMove(G2, H1, WHITE_QUEEN, &variation);
  2296.  
  2297.    checkMove(D1, D8, WHITE_QUEEN, &variation);  /* checkmate; what a game! */
  2298.  
  2299.    return 0;
  2300. }
  2301.  
  2302. static int testShortCastlings()
  2303. {
  2304.    Variation variation;
  2305.  
  2306.    initializeVariation(&variation, FEN_GAMESTART);
  2307.    assert(checkConsistency(&variation.singlePosition) == 0);
  2308.  
  2309.    checkMove(E2, E4, NO_PIECE, &variation);
  2310.    checkMove(E7, E5, NO_PIECE, &variation);
  2311.  
  2312.    checkMove(G1, F3, NO_PIECE, &variation);
  2313.    checkMove(G8, F6, NO_PIECE, &variation);
  2314.  
  2315.    checkMove(F1, C4, NO_PIECE, &variation);
  2316.    checkMove(F8, C5, NO_PIECE, &variation);
  2317.  
  2318.    checkMove(E1, G1, NO_PIECE, &variation);
  2319.    assert(variation.singlePosition.piece[F1] == WHITE_ROOK);
  2320.    checkMove(E8, G8, NO_PIECE, &variation);
  2321.    assert(variation.singlePosition.piece[F8] == BLACK_ROOK);
  2322.  
  2323.    return 0;
  2324. }
  2325.  
  2326. static int testLongCastlings()
  2327. {
  2328.    Variation variation;
  2329.  
  2330.    initializeVariation(&variation, FEN_GAMESTART);
  2331.    assert(checkConsistency(&variation.singlePosition) == 0);
  2332.  
  2333.    checkMove(D2, D4, NO_PIECE, &variation);
  2334.    checkMove(D7, D5, NO_PIECE, &variation);
  2335.  
  2336.    checkMove(B1, C3, NO_PIECE, &variation);
  2337.    checkMove(B8, C6, NO_PIECE, &variation);
  2338.  
  2339.    checkMove(C1, F4, NO_PIECE, &variation);
  2340.    checkMove(C8, F5, NO_PIECE, &variation);
  2341.  
  2342.    checkMove(D1, D2, NO_PIECE, &variation);
  2343.    checkMove(D8, D7, NO_PIECE, &variation);
  2344.  
  2345.    checkMove(E1, C1, NO_PIECE, &variation);
  2346.    assert(variation.singlePosition.piece[D1] == WHITE_ROOK);
  2347.    checkMove(E8, C8, NO_PIECE, &variation);
  2348.    assert(variation.singlePosition.piece[D8] == BLACK_ROOK);
  2349.  
  2350.    return 0;
  2351. }
  2352.  
  2353. static int testCastlingLegality()
  2354. {
  2355.    Variation variation, *p_variation = &variation;
  2356.  
  2357.    initializeVariation(&variation, FEN_GAMESTART);
  2358.    assert(checkConsistency(&variation.singlePosition) == 0);
  2359.  
  2360.    checkMove(E2, E4, NO_PIECE, &variation);
  2361.    checkMove(E7, E5, NO_PIECE, &variation);
  2362.  
  2363.    checkMove(G1, F3, NO_PIECE, &variation);
  2364.    checkMove(G8, F6, NO_PIECE, &variation);
  2365.  
  2366.    checkMove(F3, E5, NO_PIECE, &variation);
  2367.    checkMove(F6, E4, NO_PIECE, &variation);
  2368.  
  2369.    checkMove(E5, G6, NO_PIECE, &variation);
  2370.    checkMove(E4, G3, NO_PIECE, &variation);
  2371.  
  2372.    checkMove(F1, C4, NO_PIECE, &variation);
  2373.    checkMove(F8, C5, NO_PIECE, &variation);
  2374.  
  2375.    assert(makeMove(&variation, getPackedMove(E1, G1, NO_PIECE)) == 1);
  2376.    unmakeLastMove(p_variation);
  2377.  
  2378.    checkMove(H2, G3, NO_PIECE, &variation);
  2379.  
  2380.    assert(makeMove(&variation, getPackedMove(E8, G8, NO_PIECE)) == 1);
  2381.    unmakeLastMove(p_variation);
  2382.  
  2383.    checkMove(H7, G6, NO_PIECE, &variation);
  2384.  
  2385.    assert(makeMove(&variation, getPackedMove(E1, G1, NO_PIECE)) == 0);
  2386.  
  2387.    assert(makeMove(&variation, getPackedMove(E8, G8, NO_PIECE)) == 0);
  2388.  
  2389.    initializeVariation(&variation, FEN_GAMESTART);
  2390.    assert(checkConsistency(&variation.singlePosition) == 0);
  2391.  
  2392.    checkMove(E2, E4, NO_PIECE, &variation);
  2393.    checkMove(E7, E5, NO_PIECE, &variation);
  2394.  
  2395.    checkMove(G1, F3, NO_PIECE, &variation);
  2396.    checkMove(G8, F6, NO_PIECE, &variation);
  2397.  
  2398.    checkMove(F3, E5, NO_PIECE, &variation);
  2399.    checkMove(F6, E4, NO_PIECE, &variation);
  2400.  
  2401.    checkMove(E5, F3, NO_PIECE, &variation);
  2402.    checkMove(E4, F6, NO_PIECE, &variation);
  2403.  
  2404.    checkMove(F1, C4, NO_PIECE, &variation);
  2405.    checkMove(F8, C5, NO_PIECE, &variation);
  2406.  
  2407.    checkMove(D1, E2, NO_PIECE, &variation);
  2408.  
  2409.    assert(makeMove(&variation, getPackedMove(E8, G8, NO_PIECE)) == 1);
  2410.    unmakeLastMove(p_variation); /* 0-0 */
  2411.    unmakeLastMove(p_variation); /* Qe2+ */
  2412.  
  2413.    assert(makeMove(&variation, getPackedMove(E1, G1, NO_PIECE)) == 0);
  2414.    unmakeLastMove(p_variation); /* 0-0 */
  2415.  
  2416.    checkMove(D2, D3, NO_PIECE, &variation);
  2417.  
  2418.    assert(makeMove(&variation, getPackedMove(E8, G8, NO_PIECE)) == 0);
  2419.    unmakeLastMove(p_variation); /* 0-0 */
  2420.  
  2421.    checkMove(D8, E7, NO_PIECE, &variation);
  2422.  
  2423.    assert(makeMove(&variation, getPackedMove(E1, G1, NO_PIECE)) == 1);
  2424.    unmakeLastMove(p_variation); /* 0-0 */
  2425.    unmakeLastMove(p_variation); /* Qe7+ */
  2426.  
  2427.    checkMove(D7, D6, NO_PIECE, &variation);
  2428.  
  2429.    assert(makeMove(&variation, getPackedMove(E1, G1, NO_PIECE)) == 0);
  2430.  
  2431.    return 0;
  2432. }
  2433.  
  2434. static int testMove()
  2435. {
  2436. #ifndef NDEBUG
  2437.    Move move;
  2438.  
  2439.    move = getMove(A1, C3, NO_PIECE, -17);
  2440.  
  2441.    assert(getFromSquare(move) == A1);
  2442.    assert(getToSquare(move) == C3);
  2443.    assert(getNewPiece(move) == NO_PIECE);
  2444.    assert(getMoveValue(move) == -17);
  2445. #endif
  2446.  
  2447.    return 0;
  2448. }
  2449.  
  2450. int testModulePosition()
  2451. {
  2452.    int result;
  2453.  
  2454.    if ((result = testPawnMoves()) != 0)
  2455.    {
  2456.       return result;
  2457.    }
  2458.  
  2459.    if ((result = testShortCastlings()) != 0)
  2460.    {
  2461.       return result;
  2462.    }
  2463.  
  2464.    if ((result = testLongCastlings()) != 0)
  2465.    {
  2466.       return result;
  2467.    }
  2468.  
  2469.    if ((result = testCastlingLegality()) != 0)
  2470.    {
  2471.       return result;
  2472.    }
  2473.  
  2474.    if ((result = testMove()) != 0)
  2475.    {
  2476.       return result;
  2477.    }
  2478.  
  2479.    return 0;
  2480. }
  2481.