gpt4 book ai didi

java - 追踪 Minimax 的最佳移动

转载 作者:行者123 更新时间:2023-12-01 14:46:55 31 4
gpt4 key购买 nike

我知道以前有人问过此类问题,但我无法解决我的疑问。我有一个简单的黑白棋引擎(实际上它玩得很好),它使用下面的类来获得最佳棋步:

import java.util.*;
import java.util.concurrent.*;

public class MinimaxOthello implements Runnable
{
private CountDownLatch doneSignal;
private int maxDepth;
private int calls;
private OthelloMove bestFound;
private OthelloBoard board;
private static float INFINITY = Float.MAX_VALUE/1000;
private boolean solve = false;
private Comparator<OthelloMove> comparator = Collections.reverseOrder(new MoveComparator());

public MinimaxOthello (OthelloBoard board, int maxDepth, CountDownLatch doneSignal, boolean solve)
{
this.board = board;
this.bestFound = new OthelloMove();
bestFound.setPlayer(board.getCurrentPlayer());
this.maxDepth = maxDepth;
this.doneSignal = doneSignal;
this.solve = solve;
}

public OthelloMove getBestFound()
{
return this.bestFound;
}
public void run()
{
float val = minimax(board, bestFound, -INFINITY, INFINITY, 0);
System.out.println("calls: " + calls);
System.out.println("eval: " + val);
System.out.println();
doneSignal.countDown();
}

private float minimax(OthelloBoard board, OthelloMove best, float alpha, float beta, int depth)
{
calls++;
OthelloMove garbage = new OthelloMove();
int currentPlayer = board.getCurrentPlayer();

if (board.checkEnd())
{
int bd = board.countDiscs(OthelloBoard.BLACK);
int wd = board.countDiscs(OthelloBoard.WHITE);

if ((bd > wd) && currentPlayer == OthelloBoard.BLACK)
{
return INFINITY/10;
}
else if ((bd < wd) && currentPlayer == OthelloBoard.BLACK)
{
return -INFINITY/10;
}
else if ((bd > wd) && currentPlayer == OthelloBoard.WHITE)
{
return -INFINITY/10;
}
else if ((bd < wd) && currentPlayer == OthelloBoard.WHITE)
{
return INFINITY/10;
}
else
{
return 0.0f;
}
}
if (!solve)
{
if (depth == maxDepth)
return OthelloHeuristics.eval(currentPlayer, board);
}

ArrayList<OthelloMove> moves = board.getAllMoves(currentPlayer);
if (moves.size() > 1)
{
OthelloHeuristics.scoreMoves(moves);
Collections.sort(moves, comparator);
}

for (OthelloMove mv : moves)
{
board.makeMove(mv);
float score = - minimax(board, garbage, -beta, -alpha, depth + 1);
board.undoMove(mv);

if(score > alpha)
{
alpha = score;
best.setFlipSquares(mv.getFlipSquares());
best.setIdx(mv.getIdx());
best.setPlayer(mv.getPlayer());
}

if (alpha >= beta)
break;

}
return alpha;
}
}

我有一个bestFound实例变量,我的疑问是,为什么必须调用

OthelloMove garbage = new OthelloMove(); 

并传递它?该代码有效,但对我来说似乎很奇怪!

是否有“更好”的方法来获得最佳着法或主要变体?我真的不是递归专家,这非常难以调试和可视化。谢谢!

**PS:您可以在 https://github.com/fernandotenorio/ 克隆它

最佳答案

看来您可以将 best 参数去掉为 minimax,从而消除对 garbage 的需要,然后替换 bestthis.bestFound。仅当深度 = 0 时才设置 bestFound 的属性。

您可以通过将 this.bestFound 设置为初始空列表来获取主要变体。在 moves 循环之前,创建一个新的移动。在 if (score > alpha) 部分,将其属性设置为与现在相同。将移动推到循环之后的列表中。主要变化将与列表相反。

如果这很重要,您可以进行一些更改来提高类的多线程能力:

  • 不要将 bestFound 列表存储为实例变量,而是将其设为 run 中的局部变量,并将其作为参数添加到 minimax
  • Make Board.makeMove 不会修改棋盘,而是返回应用了移动的棋盘的新实例。您可以通过克隆棋盘并将移动代码应用到克隆来实现这一点,而不是改变this。然后,将克隆的板传递给下一次调用 minimax。

关于java - 追踪 Minimax 的最佳移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15341917/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com