我正在尝试编写一个国际象棋游戏,发现我无法找到解决方案来找到相持的情况。我正在尝试谷歌,但找不到任何东西。有没有众所周知的算法之类的?
2 回答
您的移动生成器将是两种不同设计之一;
- 要么在生成动作时检查合法性
- 或者您生成所有可能的动作并在之后删除那些非法的动作。
前者更好,因为它不需要后处理。
僵局状态只是没有合法移动并且移动方的国王不受控制的情况。将死条件是没有合法移动但移动方的国王受到控制的情况。
换句话说,如果您已经弄清楚如何检测检查和将死,那么您已经拥有了检测僵局所需的一切。
这是一个包含经典国际象棋游戏所有规则的开源代码: https ://github.com/cjortegon/basic-chess
您可以在克隆项目后立即运行项目(Android、iOS、桌面和 Web),也可以使用主逻辑,这里是:https ://github.com/cjortegon/basic-chess/tree/master/ libgdx/core/src/com/mountainreacher/chess/model
我的解决方案基于 3-moments 算法,第一个时刻是玩家从棋盘上选择一个棋子,然后是这个棋子的目的地被选择,最后是棋子到达那个位置(考虑到它是一个动画游戏,如果没有,可以合并第2步和第3步)。
以下代码已在 Java 中实现。从模型类的属性:
boolean turn;
GenericPiece selected, conquest;
ClassicBoard board;
List<int[]> possibleMovements;
int checkType;
第一种方法将处理时刻 1、2 和特殊的“征服”时刻(仅适用于典当):
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;
}
以下方法将处理第三个时刻(动画结束时):
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;
}
}
该代码涵盖了经典国际象棋的所有规则,包括:常规棋子移动、易位、检查、检查队友和棋子的征服。