Java Minimax:保存电路板副本以进行回溯

Java Minimax:保存电路板副本以进行回溯,java,minimax,alpha-beta-pruning,Java,Minimax,Alpha Beta Pruning,我正在尝试实现一个极小极大值(使用alpha-beta修剪。我现在的问题是,如果我评估一个位置并回溯到迭代中的下一步(向上一级),“currentBoard”不是初始板,而是来自评估叶的板,即使makeMove和removeFigure都返回一个新板 那么,我如何“保存”旧板以进行正确的回溯呢 附言:我想使用复制而不是撤销移动,因为电路板是一个简单的hashmap,所以我想这样更容易 以下是我目前掌握的代码: public int alphaBeta(Board currentBoard, in

我正在尝试实现一个极小极大值(使用alpha-beta修剪。我现在的问题是,如果我评估一个位置并回溯到迭代中的下一步(向上一级),“currentBoard”不是初始板,而是来自评估叶的板,即使makeMove和removeFigure都返回一个新板

那么,我如何“保存”旧板以进行正确的回溯呢

附言:我想使用复制而不是撤销移动,因为电路板是一个简单的hashmap,所以我想这样更容易

以下是我目前掌握的代码:

public int alphaBeta(Board currentBoard, int depth, int alpha, int beta, boolean maximisingPlayer) {
    int score;
    if (depth == 0) {
        return Evaluator.evaluateLeaf(whichColorAmI, currentBoard);
    }
    else if (maximisingPlayer) {
        ArrayList<Move> possibleMoves= new ArrayList<Move>();
        possibleMoves=getPossibleMoves(whichColorAmI, currentBoard);
        for (Move iterMoveForMe : possibleMoves) {
            if(currentBoard.figureAt(iterMoveForMe.to)!=null){
                currentBoard =  currentBoard.removeFigure(iterMoveForMe.to);
            }
            currentBoard= currentBoard.moveFigure(iterMoveForMe.from, iterMoveForMe.to);
            score = alphaBeta(currentBoard, depth-1, alpha, beta, false);
            if(score>=alpha){
                alpha=score;
                if(depth==initialDepth){
                    moveToMake=iterMoveForMe;
                }
            }
            if (alpha>=beta) {
                break;
            }
        }
        return alpha;
    }
    else {[Minimizer...]
public int-alphaBeta(板电流板、int-depth、int-alpha、int-beta、布尔最大化播放器){
智力得分;
如果(深度==0){
返回Evaluator.evaluateLeaf(颜色、电流板);
}
else if(maximisingPlayer){
ArrayList possibleMoves=新的ArrayList();
possibleMoves=getPossibleMoves(颜色为AMI,当前板);
对于(移动iterMoveForMe:possibleMoves){
if(电流板图(iterMoveForMe.to)!=null){
currentBoard=currentBoard.removeFigure(iterMoveForMe.to);
}
currentBoard=currentBoard.moveFigure(iterMoveForMe.from,iterMoveForMe.to);
分数=αβ(电流板,深度1,α,β,假);
如果(分数>=α){
α=分数;
如果(深度==初始深度){
moveToMake=iterMoveForMe;
}
}
如果(α>=β){
打破
}
}
返回α;
}
else{[最小值…]

}

我想我找到了一种方法。至少它看起来是可行的。他们的关键是在for循环之后制作一个副本,以后使用这个副本而不是currentBoard,这样currentBoard for the循环就永远不会被修改

public int alphaBeta(Board currentBoard, int depth, int alpha, int beta, boolean maximisingPlayer) {
    Display dis = new ConsoleDisplay();

    int score;
    if (depth == 0) {
        int evaluatedScore = Evaluator.evaluateLeaf(whichColorAmI, currentBoard);
        return evaluatedScore;
    }
    else if (maximisingPlayer) {
        ArrayList<Move> possibleMoves= new ArrayList<Move>();
        possibleMoves=getPossibleMoves(whichColorAmI, currentBoard);
        for (Move iterMoveForMe : possibleMoves) {
            Board copy = new Board(currentBoard.height, currentBoard.width,currentBoard.figures());
            if(copy.figureAt(iterMoveForMe.to)!=null){
                copy =  currentBoard.removeFigure(iterMoveForMe.to);
            }
                copy= copy.moveFigure(iterMoveForMe.from, iterMoveForMe.to);
            score = alphaBeta(copy, depth-1, alpha, beta, false);

            if(score>=alpha){
                alpha=score;
                if(depth==maxDepth){
                    moveToMake=iterMoveForMe;
                }
            }
            if (alpha>=beta) {
                    break;
            }
        }
        return alpha;
    }
    else {
public int-alphaBeta(板电流板、int-depth、int-alpha、int-beta、布尔最大化播放器){
显示dis=新控制台显示();
智力得分;
如果(深度==0){
int evaluatedScore=Evaluator.EvaluateLab(哪个颜色,当前板);
返回评价得分;
}
else if(maximisingPlayer){
ArrayList possibleMoves=新的ArrayList();
possibleMoves=getPossibleMoves(颜色为AMI,当前板);
对于(移动iterMoveForMe:possibleMoves){
线路板副本=新线路板(currentBoard.height,currentBoard.width,currentBoard.figures());
if(copy.figureAt(iterMoveForMe.to)!=null){
复制=currentBoard.removeFigure(iterMoveForMe.to);
}
copy=copy.moveFigure(iterMoveForMe.from,iterMoveForMe.to);
分数=α-β(复制,深度-1,α,β,假);
如果(分数>=α){
α=分数;
如果(深度==最大深度){
moveToMake=iterMoveForMe;
}
}
如果(α>=β){
打破
}
}
返回α;
}
否则{

我在为国际象棋编写ai时遇到了类似的问题。我不确定我的解决方案是否正确,但我创建了棋盘元素的防御性副本。