2011-10-31 21 views
6

Estoy tratando de escribir un juego de ajedrez y descubro que no puedo encontrar soluciones para encontrar una situación de estancamiento. Intento googlear, pero no puedo encontrar nada. ¿Hay algún algoritmo conocido o algo así?¿Cómo codificar la regla de punto muerto de ajedrez?

+6

Eche un vistazo al wikispace [chessprogramming] (http://chessprogramming.wikispaces.com/Stalemate) – Bart

Respuesta

9

Su generador de movimientos será uno de dos diseños diferentes;

  • o bien se comprueba la legalidad al tiempo que genera los movimientos
  • o generar todos los movimientos posibles y eliminar aquellas que son ilegales después.

El primero es mejor ya que no necesita procesamiento posterior.

Una condición de estancamiento es simplemente una donde no hay movimientos legales y el rey del lado móvil está no en jaque. Una condición de jaque mate es aquella donde no hay movimientos legales, pero el rey del lado móvil está en jaque.

En otras palabras, si ha descubierto cómo detectar la comprobación y el jaque mate, ya tiene todo lo necesario para detectar el estancamiento.

2

Aquí es un código de fuente abierta con todas las reglas para el juego de ajedrez clásico: https://github.com/cjortegon/basic-chess

Puede ejecutar el proyecto de la derecha después de clonar el proyecto (Android, iOS, escritorio y web), o puede use la lógica principal, que está aquí: https://github.com/cjortegon/basic-chess/tree/master/libgdx/core/src/com/mountainreacher/chess/model

Basé mi solución en un algoritmo de 3 momentos, el primer momento es cuando el jugador selecciona una pieza del tablero, luego cuando el destino de esta pieza ha sido elegido y finalmente cuando la pieza alcanza esa posición (considerando que es un juego animado, si no, puede fusionar los pasos 2 y 3).

El siguiente código se ha implementado en Java. A partir de las propiedades de la clase del modelo:

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

El primer método se encargará momentos 1, 2 y el momento especial 'conquista' (aplicado a empeñar pieza única):

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

Y el siguiente método se encargará de la tercera momento (cuando termina la animación):

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

Ese código cubre todas las reglas del ajedrez clásico, incluyendo: movimientos regulares pieza, enroque, cheque, jaque mate y conquistas de peones.

+0

Estos son buenos enlaces pero, como regla general, una respuesta debe ser razonablemente independiente. Los enlaces se mueven y caducan, pero estas respuestas están aquí para ... bueno, un tiempo realmente largo. –

+0

@DavidLively He incluido las partes esenciales del código del repositorio de Github. –

Cuestiones relacionadas