2011-08-25 53 views
6

Tôi đang cố gắng lập trình công cụ cờ vua của riêng mình (không AI). Tôi biết có Chess Game Starter Kit và tôi đã xem nó để có nguồn cảm hứng khởi đầu.Lập trình cờ vua (không AI) - di chuyển xác nhận

Nhưng những gì tôi không nắm bắt là di chuyển được xác thực ở đâu (here is moves validation) cho các phần không phải là vua của tôi để ngăn mình tự kiểm tra?

Hãy tưởng tượng tình huống:
A5 - đối thủ Rook
A4 - giám mục của tôi
A3 - vua của tôi

tôi không thể di chuyển giám mục của tôi bây giờ kể từ khi tôi sẽ nhận được để kiểm tra.

Hoặc bạn đề xuất kiểm tra tình huống này như thế nào?

Cảm ơn bạn

+0

bạn có nghĩa là làm thế nào để bạn xác nhận rằng một động thái là bất hợp pháp vì làm như vậy nó đặt bạn trong kiểm tra? – Kevin

+0

Ồ, ý bạn là bạn muốn tìm ra nơi mã ** liên kết ** thực hiện loại xác thực cụ thể đó? – AakashM

+0

Vâng, như tôi đã đọc mã liên kết, tôi không nắm bắt được điều này sẽ được giải quyết bất cứ nơi nào. –

Trả lời

15

Đối với một vị trí hội đồng quản trị đưa ra, hầu hết các động cơ cờ vua bắt đầu bằng cách tạo ra chỉ di chuyển giả pháp lý. Bằng cách giả quy phạm pháp luật, ý tôi là một động thái sẽ được tạo ngay cả khi nó:

  • Lá vua trong tầm kiểm soát
  • Di chuyển Vua vào séc
  • Castles qua hình vuông đó đang bị tấn công

Lý do cho điều này là hiệu suất. Vì nhiều di chuyển sẽ không thực sự được tìm kiếm do cắt tỉa beta, bạn tiết kiệm thời gian bằng cách tránh kiểm tra toàn bộ giá trị di chuyển.

Đối với mỗi lần di chuyển được tìm kiếm, bạn cần kiểm tra xem nó có thực sự hợp lệ hay không. Điều này thường được thực hiện bằng cách chuyển màu và hình vuông của nhà vua (và hình vuông bên cạnh nhà vua để di chuyển) vào một phương pháp IsAttacked. Nếu phương thức đó trả về true, bạn biết di chuyển không hợp lệ và do đó bạn không nên đưa nó vào tìm kiếm của mình.

Đây là phương pháp IsAttacked từ công cụ cờ C# của riêng tôi. Hãy nhớ rằng động cơ của tôi là magic bitboard, do đó mã sẽ không được áp dụng trực tiếp cho bộ cờ khởi động mà bạn đã liên kết. Trừ khi bạn quen thuộc với bitmap ma thuật, bản dịch sẽ không tầm thường.

// IsAttacked is primarily used as a move legality test to see if a set of 
// one or more squares is under attack from the side to move. 
// It returns true as soon as an attack is detected, otherwise returns false. 
// It can be used for check detection, castling legality, or simply to 
// detect whether a specific square is attacked. 
internal bool IsAttacked(Board board, UInt64 targetSquares, bool whiteAttacking) 
{ 
    UInt64 slidingAttackers; Int32 targetSquare; 
    UInt64 remainingTargetSquares = targetSquares; 

    // Test for attacks by WHITE on any of the target squares. 
    if (whiteAttacking) 
    { 
     // For the remaining target squares... 
     while (remainingTargetSquares != 0) 
     { 
      // Find the next square in the list. 
      targetSquare = BitOperations.BitScanForward(remainingTargetSquares); 

      // Is this square attacked by a pawn, knight, or king? 
      if ((board.WhitePawns & Constants.BLACK_PAWN_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.WhiteKnights & Constants.KNIGHT_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.WhiteKing & Constants.KING_ATTACKS[targetSquare]) != 0) return true; 

      // Is this square attacked by a queen or rook along a file or rank? 
      slidingAttackers = board.WhiteQueens | board.WhiteRooks; 
      if (slidingAttackers != 0) 
      { 
       if (this.RankMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.FileMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // Is this square attacked by a queen or bishop along a diagonal? 
      slidingAttackers = board.WhiteQueens | board.WhiteBishops; 
      if (slidingAttackers != 0) 
      { 
       if (this.DiagonalA8H1Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.DiagonalA1H8Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // This square isn't attacked - remove and move on to next target square. 
      remainingTargetSquares ^= Constants.BITSET[targetSquare]; 
     } 
    } 

    // Test for attacks by BLACK on any of the target squares. 
    else 
    { 
     // For the remaining target squares... 
     while (remainingTargetSquares != 0) 
     { 
      // Find the next square in the list. 
      targetSquare = BitOperations.BitScanForward(remainingTargetSquares); 

      // Is this square attacked by a pawn, knight, or king? 
      if ((board.BlackPawns & Constants.WHITE_PAWN_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.BlackKnights & Constants.KNIGHT_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.BlackKing & Constants.KING_ATTACKS[targetSquare]) != 0) return true; 

      // Is this square attacked by a queen or rook along a file or rank? 
      slidingAttackers = board.BlackQueens | board.BlackRooks; 
      if (slidingAttackers != 0) 
      { 
       if (this.RankMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.FileMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // Is this square attacked by a queen or bishop along a diagonal? 
      slidingAttackers = board.BlackQueens | board.BlackBishops; 
      if (slidingAttackers != 0) 
      { 
       if (this.DiagonalA8H1Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.DiagonalA1H8Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // This square isn't attacked - remove and move on to next target square. 
      remainingTargetSquares ^= Constants.BITSET[targetSquare]; 
     } 
    } 

    // None of the target squares are attacked. 
    return false; 
} 

Dưới đây là một đoạn mã mà tạo ra di chuyển lên đời giả pháp lý cho trắng:

// If White can still castle kingside... 
if ((board.WhiteCastlingStatus & Board.EnumCastlingStatus.CanCastleOO) != 0) 
{ 
    // And the White kingside castling squares (F1/G1) aren't occupied... 
    if ((Constants.MASK_FG[Constants.WHITE_MOVE] & board.OccupiedSquares) == 0) 
    { 
     board.MoveBuffer[moveIndex++] = Constants.WHITE_CASTLING_OO; 
    } 
} 

// If White can still castle queenside... 
if ((board.WhiteCastlingStatus & Board.EnumCastlingStatus.CanCastleOOO) != 0) 
{ 
    // And the White queenside castling squares (D1/C1/B1) aren't occupied... 
    if ((Constants.MASK_BD[Constants.WHITE_MOVE] & board.OccupiedSquares) == 0) 
    { 
     board.MoveBuffer[moveIndex++] = Constants.WHITE_CASTLING_OOO; 
    } 
} 

Và đây là đoạn code để kiểm tra liệu một động thái castling giả quy phạm pháp luật được thực pháp lý:

// Checks whether the King is moving from or into check. 
// Checks whether the King is moving across attacked squares. 
internal bool IsCastlingMoveLegal(Board board, Move move) 
{ 
    if (move.IsCastlingOO) 
    { 
     if (move.IsWhiteMove) 
     { 
      // Are any of the White kingside castling squares (E1/F1/G1) attacked? 
      return !this.IsAttacked(board, Constants.MASK_EG[Constants.WHITE_MOVE], false); 
     } 
     else 
     { 
      // Are any of the Black kingside castling squares (E8/F8/G8) attacked? 
      return !this.IsAttacked(board, Constants.MASK_EG[Constants.BLACK_MOVE], true); 
     } 
    } 
    else if (move.IsCastlingOOO) 
    { 
     if (move.IsWhiteMove) 
     { 
      // Are any of the White queenside castling squares (E1/D1/C1) attacked? 
      return !this.IsAttacked(board, Constants.MASK_CE[Constants.WHITE_MOVE], false); 
     } 
     else 
     { 
      // Are any of the Black queenside castling squares (E8/D8/C8) attacked? 
      return !this.IsAttacked(board, Constants.MASK_CE[Constants.BLACK_MOVE], true); 
     } 
    } 
    // Not a castling move! 
    else 
    { 
     Debug.Assert(false, "Not a castling move!"); 
     return true; 
    } 
} 
0

Chương trình cờ vua của tôi có phương pháp kiểm tra xem một trường có bị đe dọa hay không. Khi tính toán di chuyển cho nhà vua, nó sẽ kiểm tra mọi lĩnh vực mà nhà vua có thể di chuyển đến nếu trường đó bị đe dọa.

Các vấn đề liên quan