2011-10-31 15 views
6

Sto provando a scrivere una partita di scacchi e scopro che non riesco a trovare soluzioni per trovare una situazione di stallo. Sto cercando di google, ma non riesco a trovare nulla. C'è un algoritmo noto o qualcosa del genere?Come codificare la regola di stallo degli scacchi?

+6

Dai un'occhiata a [chessprogramming] (http://chessprogramming.wikispaces.com/Stalemate) wikispace – Bart

risposta

9

Il generatore di spostamento sarà uno dei due diversi design;

  • o si controlla per la legalità, mentre la generazione delle mosse
  • oppure generare tutte le possibili mosse e rimuovere quelli che sono illegali in seguito.

Il primo è migliore in quanto non ha bisogno di post-elaborazione.

Una condizione di stallo è semplicemente quella in cui non ci sono mosse legali e il re del lato mobile è non sotto controllo. Una condizione di scaccomatto è quella in cui non ci sono mosse legali, ma il re del lato mobile è sotto controllo.

In altre parole, se hai capito come rilevare il check e lo scacco matto, hai già tutto il necessario per rilevare lo stallo.

2

Ecco un codice open-source con tutte le regole per il classico gioco di scacchi: https://github.com/cjortegon/basic-chess

È possibile eseguire il progetto subito dopo la clonazione del progetto (Android, iOS, desktop e web), oppure è possibile usa la logica principale, che è qui: https://github.com/cjortegon/basic-chess/tree/master/libgdx/core/src/com/mountainreacher/chess/model

Ho basato la mia soluzione su un algoritmo di 3 momenti, il primo momento è quando il giocatore seleziona un pezzo dal tabellone, poi quando la destinazione di questo pezzo è stata scelta e infine quando il pezzo raggiunge quella posizione (considerando che si tratta di un gioco animato, in caso contrario, puoi unire i passaggi 2 e 3).

Il seguente codice è stato implementato in Java. Dalle proprietà della classe del modello:

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

Il primo metodo consente di gestire momenti 1, 2 e il momento speciale 'conquista' (applicata alla parte pegno solo):

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; 
} 

E il metodo seguente gestirà il terzo momento (quando l'animazione termina):

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; 
    } 
} 

Quel codice copre tutte le regole della chess Classic, tra cui: movimenti regolari pezzo, arrocco, controllare, controllare il compagno e di conquiste pedine.

+0

Questi sono buoni collegamenti ma, di regola, una risposta dovrebbe essere ragionevolmente autonoma. I collegamenti si muovono e scadono, ma queste risposte sono qui per ... beh, un tempo veramente lungo. –

+0

@DavidLively Ho incluso le parti essenziali del codice dal repository Github. –