我目前正在我的棋类游戏中实现一个国际象棋人工智能。现在,我正在挣扎如何处理游戏状态的AI。
因为我觉得自己像人工智能,需要来自板或游戏类的最新属性(在我的例子中,我发送了一个游戏类)。但我想知道,这是错误的方式。为什么?
每当我使用minmax计算AI的移动时,我都会尝试将移动放到董事会上,但问题是这不应该出现在董事会上。因为第二个玩家基本上是在使用棋盘。我觉得它会崩溃,因为每当AI尝试一个动作,它就会试图在板上得到更新,从而导致崩溃。
因此,我认为我必须创建一个假的/模拟的副本(使用所需的属性、可用移动列表、单张颜色、播放器等)。游戏/棋盘并将其发送给人工智能。但是怎样才是最好的方法呢?
我当前的代码设置的最小极大算法相关性其他代码使用: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;
}
}发布于 2020-01-29 09:31:05
有两种常见的方法可以做到这一点:
发布于 2021-04-08 16:58:20
最近,我开始对各种人工智能机器人进行类似的项目,我采用的方法是使用ApacheCommons-lang3中的SerializationUtils。请确保板状态类实现了可序列化接口,然后您可以这样做:
final Board state = SerializationUtils.clone(currentState)
您可以在这里找到更多信息:https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/SerializationUtils.html
https://stackoverflow.com/questions/59708531
复制相似问题