2011-10-31 36 views
6

Tôi đang cố gắng viết một trò chơi cờ vua và thấy rằng tôi không thể tìm ra giải pháp để tìm ra một tình huống bế tắc. Tôi đang cố gắng tìm kiếm nhưng không thể tìm thấy gì. Có một thuật toán nổi tiếng hay cái gì đó?Làm thế nào để mã quy tắc bế tắc cờ vua?

+6

Hãy xem [chessprogramming] (http://chessprogramming.wikispaces.com/Stalemate) wikispace – Bart

Trả lời

9

Máy phát điện di chuyển của bạn sẽ là một trong hai thiết kế khác nhau;

  • hoặc nó sẽ kiểm tra tính hợp pháp cho trong khi tạo ra các chuyển động
  • hoặc bạn tạo ra tất cả di chuyển tốt và loại bỏ những bất hợp pháp sau đó.

Trước đây tốt hơn vì không cần xử lý hậu kỳ.

Điều kiện bế tắc chỉ đơn giản là điều kiện không có động thái pháp lý và vị vua di chuyển của bên là không phải là khi kiểm tra. Tình trạng của người kiểm tra là một trong những nơi không có động thái hợp pháp nhưng vua chuyển động khi kiểm tra.

Nói cách khác, nếu bạn đã tìm ra cách phát hiện kiểm tra và kiểm tra, bạn đã có mọi thứ cần thiết để phát hiện bế tắc.

2

Đây là một mã nguồn mở với tất cả các quy tắc cho các trò chơi cờ vua cổ điển: https://github.com/cjortegon/basic-chess

Bạn có thể chạy dự án ngay sau khi nhân bản dự án (Android, iOS, máy tính để bàn và Web), hoặc bạn có thể sử dụng logic chính, có ở đây: https://github.com/cjortegon/basic-chess/tree/master/libgdx/core/src/com/mountainreacher/chess/model

Tôi dựa trên giải thuật 3 phút, thời điểm đầu tiên là khi người chơi chọn một mảnh từ bảng, khi điểm đến của đoạn này đã được chọn và cuối cùng khi mảnh đạt đến vị trí đó (xem xét nó là một trò chơi hoạt hình, nếu không, bạn có thể hợp nhất bước 2 và 3).

Mã sau đã được triển khai trong Java. Từ các thuộc tính của lớp mô hình:

boolean turn; 
GenericPiece selected, conquest; 
ClassicBoard board; 
List<int[]> possibleMovements; 
int checkType; 

Phương pháp đầu tiên sẽ xử lý những khoảnh khắc 1, 2 và 'chinh phục' khoảnh khắc đặc biệt (áp dụng cho cầm mảnh chỉ):

public boolean onCellClick(int row, int column) { 
    if (row == -1 && conquest != null) { 
     checkType = 0; 
     conquest.changeFigure(column); 
     return true; 
    } else if (selected != null) { 
     if (possibleMovements != null) { 
      for (int[] move : possibleMovements) { 
       if (move[0] == row && move[1] == column) { 
        // Move the PieceActor to the desired position 
        if (selected.moveTo(row, column)) { 
         turn = !turn; 
        } 
        break; 
       } 
      } 
     } 
     selected = null; 
     possibleMovements = null; 
     return true; 
    } else { 
     selected = board.getSelected(turn ? Piece.WHITE_TEAM : Piece.BLACK_TEAM, row, column); 
     if (selected != null) { 
      possibleMovements = new ArrayList<>(); 
      possibleMovements.addAll(((GenericPiece) selected).getMoves(board, false)); 
      // Checking the movements 
      board.checkPossibleMovements(selected, possibleMovements); 
      if (possibleMovements.size() == 0) { 
       possibleMovements = null; 
       selected = null; 
       return false; 
      } else { 
       return true; 
      } 
     } 
    } 
    return false; 
} 

Và phương pháp sau sẽ xử lý các thời điểm thứ 3 (khi hình ảnh động kết thúc):

public void movedPiece(Piece piece) { 
    Gdx.app.log(TAG, "movedPiece(" + piece.getType() + ")"); 

    // Killing the enemy 
    Piece killed = board.getSelectedNotInTeam(piece.getTeam(), 
      piece.getRow(), piece.getColumn()); 
    if (killed != null) { 
     killed.setAvailable(false); 
    } 

    // Checking hacks 
    GenericPiece[] threat = board.kingIsInDanger(); 
    if (threat != null) { 
     checkType = board.hasAvailableMoves(threat[0].getTeam()) ? CHECK : CHECK_MATE; 
    } else { 
     checkType = NO_CHECK; 
    } 

    // Checking castling 
    if (piece.getFigure() == Piece.ROOK && ((GenericPiece) piece).getMovesCount() == 1) { 
     Piece king = board.getSelected(piece.getTeam(), 
       piece.getRow(), piece.getColumn() + 1); 
     if (king != null && king.getFigure() == Piece.KING && ((GenericPiece) king).getMovesCount() == 0) { 
      // Left Rook 
      if (board.getSelected(piece.getRow(), piece.getColumn() - 1) == null) { 
       king.moveTo(piece.getRow(), piece.getColumn() - 1); 
      } 
     } else { 
      king = board.getSelected(piece.getTeam(), 
        piece.getRow(), piece.getColumn() - 1); 
      if (king != null && king.getFigure() == Piece.KING && ((GenericPiece) king).getMovesCount() == 0) { 
       // Right Rook 
       if (board.getSelected(piece.getRow(), piece.getColumn() + 1) == null) { 
        king.moveTo(piece.getRow(), piece.getColumn() + 1); 
       } 
      } 
     } 
    } 

    // Conquest 
    else if (piece.getFigure() == Piece.PAWN && (piece.getRow() == 0 || piece.getRow() == board.getRows() - 1)) { 
     conquest = (GenericPiece) piece; 
     checkType = CONQUEST; 
    } 
} 

Đó là mã bao gồm tất cả các quy tắc từ cờ cổ điển, bao gồm: phong trào mảnh thường xuyên, lên đời, rà soát, kiểm tra-mate và cuộc chinh phục của pawns.

+0

Đây là những liên kết tốt nhưng, như một quy luật, một câu trả lời phải được khép kín một cách hợp lý. Liên kết di chuyển và hết hạn, nhưng những câu trả lời này ở đây cho ... tốt, một Thời gian thực sự dài. –

+0

@DavidLively Tôi đã bao gồm các phần thiết yếu của mã từ kho lưu trữ Github. –

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