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?
Respuesta
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.
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.
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. –
@DavidLively He incluido las partes esenciales del código del repositorio de Github. –
- 1. ¿Cuándo un punto muerto no es un punto muerto?
- 2. Cómo causar un punto muerto
- 3. SqlException: Punto muerto
- 4. Punto muerto del semáforo
- 5. Punto muerto en ThreadPoolExecutor
- 6. Punto muerto en ThreadPool
- 7. ¿Cómo provocar deliberadamente un punto muerto?
- 8. Punto muerto en Ruby join()
- 9. Intento de punto muerto de ActiveRecord3
- 10. Cómo codificar (.) Punto en url Rails
- 11. ¿Cómo encontrar AMBOS hilos de un punto muerto?
- 12. ¿Cómo puedo evitar este aparente punto muerto de EhCache?
- 13. punto y coma en la definición de la regla Makefile
- 14. Cómo depurar un punto muerto en Java usando Eclipse
- 15. Bloqueo de reentrada y punto muerto con Java
- 16. ¿Alguien puede explicar el punto muerto del buffer de tubería?
- 17. Diferencia entre condición de carrera y punto muerto
- 18. ¿Cómo puede la marca de tiempo causar un "punto muerto global"?
- 19. Patrones para manejar un punto muerto SQL en C#?
- 20. Ajedrez optimizaciones
- 21. Punto de inicio para codificar un dispositivo virtual
- 22. ¿Es posible que ConcurrentHashMap esté en "punto muerto"?
- 23. punto muerto en código Java con semáforo y adquirir (int)
- 24. ¿Cómo despachar en la cola principal sincrónicamente sin un punto muerto?
- 25. Tablero de ajedrez JavaScript gratuito
- 26. ¿Cómo hacer un reportero de enlace muerto?
- 27. Juego de ajedrez en JavaScript
- 28. XSL: Muerto o no muerto
- 29. ¿Cómo puedo modelar un tablero de ajedrez cuando programo una computadora para jugar al ajedrez?
- 30. ¿Cómo puedo identificar las filas involucradas en un punto muerto de Oracle?
Eche un vistazo al wikispace [chessprogramming] (http://chessprogramming.wikispaces.com/Stalemate) – Bart