Subversion Repositories Games.Chess Giants

Rev

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

  1. #undef addBonus
  2. #undef COLOR
  3. #undef OPPCOLOR
  4.  
  5. #ifdef PERSPECTIVE_WHITE
  6. #define COLOR WHITE
  7. #define OPPCOLOR BLACK
  8. #define addBonus(position, bonus) (position->balance += bonus);
  9. #else
  10. #define COLOR BLACK
  11. #define OPPCOLOR WHITE
  12. #define addBonus(position, bonus) (position->balance -= bonus);
  13. #endif
  14.  
  15. #ifdef PERSPECTIVE_WHITE
  16. int makeWhiteMove(Variation * variation, const Move move)
  17. #else
  18. int makeBlackMove(Variation * variation, const Move move)
  19. #endif
  20. {
  21.    Position *position = &variation->singlePosition;
  22.    PlyInfo *plyInfo = &variation->plyInfo[variation->ply++];
  23.    const Square from = getFromSquare(move);
  24.    const Square to = getToSquare(move);
  25.    const Piece newPiece = getNewPiece(move);
  26.    const Piece movingPiece = position->piece[from];
  27.    const Piece capturedPiece = position->piece[to];
  28.    const Bitboard minTo = minValue[to];
  29.    const Bitboard maxFrom = maxValue[from];
  30.    int result = 0;
  31.  
  32.    assert(to == from || pieceType(capturedPiece) != KING);
  33.  
  34.    variation->positionHistory[POSITION_HISTORY_OFFSET - 1 + variation->ply] =
  35.       plyInfo->hashKey = position->hashKey;
  36.    plyInfo->currentMove = move;
  37.    plyInfo->balance = position->balance;
  38.    plyInfo->pieceCount = position->pieceCount;
  39.    variation->plyInfo[variation->ply].staticValueAvailable = FALSE;
  40.    variation->plyInfo[variation->ply].gainsUpdated = FALSE;
  41.    position->hashKey = ~position->hashKey;
  42.  
  43.    if (position->enPassantSquare != NO_SQUARE)
  44.    {
  45.       position->hashKey ^= GENERATED_KEYTABLE[0][position->enPassantSquare];
  46.    }
  47.  
  48.    position->enPassantSquare = NO_SQUARE;
  49.    position->activeColor = OPPCOLOR;
  50.  
  51.    if (to == from)
  52.    {
  53.       assert(checkVariation(variation) == 0);
  54.  
  55.       return result;            /* Nullmove */
  56.    }
  57.  
  58.    plyInfo->captured = capturedPiece;
  59.    position->piecesOfColor[COLOR] &= maxFrom;
  60.    position->piecesOfColor[COLOR] |= minTo;
  61.    position->piecesOfType[movingPiece] &= maxFrom;
  62.    position->hashKey ^=
  63.       GENERATED_KEYTABLE[movingPiece][from] ^
  64.       GENERATED_KEYTABLE[movingPiece][to];
  65.    position->castlingRights &=
  66.       remainingCastlings[to] & remainingCastlings[from];
  67.  
  68.    if (position->castlingRights != plyInfo->castlingRights)
  69.    {
  70.       position->hashKey ^=
  71.          GENERATED_KEYTABLE[0][plyInfo->castlingRights] ^
  72.          GENERATED_KEYTABLE[0][position->castlingRights];
  73.    }
  74.  
  75.    position->halfMoveClock++;
  76.    position->piece[to] = movingPiece;
  77.    position->piece[from] = NO_PIECE;
  78.    addBonus(position, pieceSquareBonus[movingPiece][to] -
  79.             pieceSquareBonus[movingPiece][from]);
  80.  
  81.    if (capturedPiece != NO_PIECE)
  82.    {
  83.       position->halfMoveClock = 0;
  84.       position->piecesOfColor[OPPCOLOR] &= ~minTo;
  85.       position->piecesOfType[capturedPiece] &= ~minTo;
  86.       position->numberOfPieces[OPPCOLOR]--;
  87.  
  88.       if (pieceType(capturedPiece) == PAWN)
  89.       {
  90.          position->numberOfPawns[OPPCOLOR]--;
  91.          position->pawnHashKey ^= GENERATED_KEYTABLE[capturedPiece][to];
  92.       }
  93.       else
  94.       {
  95.          position->pieceCount -= (capturedPiece == (BISHOP | OPPCOLOR) ?
  96.                                   bishopPieceCountWeight[OPPCOLOR][to] :
  97.                                   pieceCountWeight[capturedPiece]);
  98.       }
  99.  
  100.       position->hashKey ^= GENERATED_KEYTABLE[capturedPiece][to];
  101.       addBonus(position, pieceSquareBonus[capturedPiece][to]);
  102.    }
  103.  
  104.    if (pieceType(movingPiece) == PAWN)
  105.    {
  106.       position->halfMoveClock = 0;
  107.       position->pawnHashKey ^=
  108.          GENERATED_KEYTABLE[movingPiece][from] ^
  109.          GENERATED_KEYTABLE[movingPiece][to];
  110.  
  111.       if (distance(from, to) == 2)
  112.       {
  113.          position->enPassantSquare = (Square) ((from + to) >> 1);
  114.          position->hashKey ^=
  115.             GENERATED_KEYTABLE[0][position->enPassantSquare];
  116.       }
  117.       else if (to == plyInfo->enPassantSquare)
  118.       {
  119.          const Square captureSquare =
  120.             (Square) (to + (rank(from) - rank(to)) * 8);
  121.          const Piece capturedPawn = position->piece[captureSquare];
  122.  
  123.          clearSquare(position->piecesOfColor[OPPCOLOR], captureSquare);
  124.          clearSquare(position->piecesOfType[capturedPawn], captureSquare);
  125.          position->hashKey ^= GENERATED_KEYTABLE[capturedPawn][captureSquare];
  126.          position->pawnHashKey ^=
  127.             GENERATED_KEYTABLE[capturedPawn][captureSquare];
  128.          addBonus(position, pieceSquareBonus[capturedPawn][captureSquare]);
  129.  
  130.          plyInfo->restoreSquare1 = captureSquare;
  131.          plyInfo->restorePiece1 = capturedPawn;
  132.          position->piece[captureSquare] = NO_PIECE;
  133.          position->numberOfPieces[OPPCOLOR]--;
  134.          position->numberOfPawns[OPPCOLOR]--;
  135.       }
  136.       else if (newPiece != NO_PIECE)
  137.       {
  138.          const Piece effectiveNewPiece = (Piece) (newPiece | COLOR);
  139.  
  140.          plyInfo->restoreSquare1 = from;
  141.          plyInfo->restorePiece1 = movingPiece;
  142.          position->piece[to] = effectiveNewPiece;
  143.          position->numberOfPawns[COLOR]--;
  144.          position->pieceCount +=
  145.             (newPiece == (Piece) BISHOP ?
  146.              bishopPieceCountWeight[COLOR][to] :
  147.              pieceCountWeight[effectiveNewPiece]);
  148.          position->hashKey ^=
  149.             GENERATED_KEYTABLE[movingPiece][to] ^
  150.             GENERATED_KEYTABLE[effectiveNewPiece][to];
  151.          position->pawnHashKey ^= GENERATED_KEYTABLE[movingPiece][to];
  152.          addBonus(position, pieceSquareBonus[effectiveNewPiece][to] -
  153.                   pieceSquareBonus[movingPiece][to]);
  154.          setSquare(position->piecesOfType[position->piece[to]], to);
  155.       }
  156.    }
  157.  
  158.    else if (pieceType(movingPiece) == KING)
  159.    {
  160.       position->king[COLOR] = to;
  161.  
  162.       if (distance(from, to) == 2)
  163.       {
  164.          const Square rookFrom = rookOrigin[to];
  165.          const Square rookTo = (Square) ((from + to) >> 1);
  166.          const Piece movingRook = position->piece[rookFrom];
  167.  
  168.          plyInfo->restoreSquare1 = rookFrom;
  169.          plyInfo->restorePiece1 = movingRook;
  170.          plyInfo->restoreSquare2 = rookTo;
  171.          plyInfo->restorePiece2 = position->piece[rookTo];
  172.          position->piece[rookFrom] = NO_PIECE;
  173.          position->piece[rookTo] = movingRook;
  174.          position->halfMoveClock = 0;
  175.  
  176.          setSquare(position->piecesOfColor[COLOR], rookTo);
  177.          clearSquare(position->piecesOfColor[COLOR], rookFrom);
  178.          setSquare(position->piecesOfType[movingRook], rookTo);
  179.          clearSquare(position->piecesOfType[movingRook], rookFrom);
  180.          position->hashKey ^=
  181.             GENERATED_KEYTABLE[movingRook][rookFrom] ^
  182.             GENERATED_KEYTABLE[movingRook][rookTo];
  183.          addBonus(position, pieceSquareBonus[movingRook][rookTo] -
  184.                   pieceSquareBonus[movingRook][rookFrom]);
  185.  
  186.          if (getDirectAttackers(position, from, OPPCOLOR,
  187.                                 position->allPieces) != EMPTY_BITBOARD ||
  188.              getDirectAttackers(position, rookTo, OPPCOLOR,
  189.                                 position->allPieces) != EMPTY_BITBOARD)
  190.          {
  191.             result = 1;         /* castling move was not legal */
  192.          }
  193.       }
  194.    }
  195.  
  196.    setSquare(position->piecesOfType[position->piece[to]], to);
  197.    position->allPieces =
  198.       position->piecesOfColor[WHITE] | position->piecesOfColor[BLACK];
  199.  
  200.    assert(checkVariation(variation) == 0);
  201.  
  202. #ifdef TRACE_POSITIONS
  203.    if (variation->nodes >= POSITION_TRACE_START &&
  204.        variation->nodes <= POSITION_TRACE_START + POSITION_TRACE_QUANTITY)
  205.    {
  206.       char buffer[128];
  207.  
  208.       getMoveDump(move, buffer);
  209.       logDebug("pos %llu after %s: %llu\n",
  210.                variation->nodes, buffer, variation->singlePosition.hashKey);
  211.    }
  212. #endif
  213.  
  214.    return result;
  215. }
  216.