我目前正在将国际象棋AI应用于我的国际象棋游戏。现在,我目前正在努力如何处理AI的游戏状态。
因为我感觉像AI,所以需要开发板或游戏类的最新属性(在我的情况下,我发送了一个游戏类)。但是我想知道,这是错误的方法。为什么?
[每当我使用minmax计算AI的移动量时,我都会尝试将移动放置在板上,但问题是这不应该放在板上。因为第二位玩家基本上是在使用棋盘。我觉得它会崩溃,因为每当AI tries运动时,它将尝试在板上进行更新,从而导致崩溃。
所以我认为我必须创建游戏/棋盘的伪造/模拟副本(具有所需的属性,可用动作列表,棋子颜色,玩家等),并将其发送给AI。但是什么是最好的方法呢?
我当前的minimax算法代码设置与使用的其他代码相关:https://hastebin.com/niqaderule.java:
public class MiniMax implements MoveStrategy {
private final BoardEvaluator boardEvaluator;
private int searchDepth;
public MiniMax(BoardEvaluator boardEvaluator, int searchDepth) {
this.boardEvaluator = boardEvaluator;
this.searchDepth = searchDepth;
}
@Override
public String toString() {
return "MiniMax{" +
"boardEvaluator=" + boardEvaluator +
'}';
}
@Override
public Move execute(ChessGame game) {
long startTime = System.currentTimeMillis();
Move calculatedBestMove = null;
int highestSeenValue = Integer.MIN_VALUE;
int lowestSeenValue = Integer.MAX_VALUE;
int currentValue;
System.out.println("computer thinks" + " depth= " + this.searchDepth);
var numberOfAllMoves = game.getBoard().getAllAvailableMoves(PieceColor.BLACK);
for(Move move : game.getBoard().getAllAvailableMoves(PieceColor.BLACK)){
game.getBoard().movePiece(move.getSelectedPiece(), move);
currentValue = calculateValue(game);
if(game.getCurrentTurn() == game.getPlayers().get(0) && currentValue >= highestSeenValue)
{
highestSeenValue = currentValue;
calculatedBestMove = move;
}
else if(game.getCurrentTurn() == game.getPlayers().get(1) && currentValue <= lowestSeenValue){
lowestSeenValue = currentValue;
calculatedBestMove = move;
}
}
long CalculationTime = System.currentTimeMillis() - startTime;
return calculatedBestMove;
}
public int calculateValue(ChessGame game){
if(game.getCurrentTurn() == game.getPlayers().get(0)){
return min(game, -1);
}
return max(game, -1);
}
public int min(ChessGame game, int depth){
if(depth == 0 || game.getGameStatus() == GameStatus.BLACK_CHECK_MATE || game.getGameStatus() == GameStatus.WHITE_CHECK_MATE){
return this.boardEvaluator.evaluate(game, depth);
}
int lowestValue = Integer.MAX_VALUE;
for(Move move: game.getBoard().getAllAvailableMoves(PieceColor.BLACK)){
game.getBoard().movePiece(move.getSelectedPiece(), move);
int currentValue = max(game, depth -1);
if(currentValue <= lowestValue)
{
lowestValue = currentValue;
}
}
return lowestValue;
}
public int max(ChessGame game, int depth){
if(depth == 0 || game.getGameStatus() == GameStatus.BLACK_CHECK_MATE || game.getGameStatus() == GameStatus.WHITE_CHECK_MATE){
return this.boardEvaluator.evaluate(game, depth);
}
int highestSeenValue = Integer.MIN_VALUE;
for(Move move: game.getBoard().getAllAvailableMoves(PieceColor.BLACK)){
game.getBoard().movePiece(move.getSelectedPiece(), move);
int currentValue = min(game, depth -1);
if(currentValue <= highestSeenValue)
{
highestSeenValue = currentValue;
}
}
return highestSeenValue;
}
}
我对你也有同样的问题。 Trincot是对的。您可以使用必须编写的takeBack方法。在我的项目中,我想向玩家显示最后一步。但是,当我调用undoMove函数查找最后一步时,最后一步消失了。我尝试重复此问题解决的最后一步。也许我的代码对您有帮助。
button_showLastMove.setOnClickListener {
val move:Move = board.undoMove()
textView.text = move.toString()
board.doMove(move)
}
在我的代码中,我使用了具有Apache Licance(https://github.com/bhlangonijr/chesslib)的库。该库包含doMove和undoMove函数。我只定义val board: Board = Board()
。我建议您使用此库。否则,您必须为收回方法编写很多代码(因为必须收回城堡和其他举动)。如果您愿意,我可以共享undoMove方法。最后,您可以在游戏商店(https://play.google.com/store/apps/details?id=com.dreamscloud.deneme)