나는 이런 종류의 질문이 전에 물어 왔지만, 나는 의심을 해결할 수 없었다. 나는 bestFound 인스턴스 변수를 가지고 내 의심의 여지가 이유를 가지고있다Minimax에서 최선의 움직임을 추적하십시오.
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;
}
}
: 나는 최고의 움직임을 얻기 위해 아래의 클래스를 사용하는 간단한 오델로 엔진 (실제로 아주 잘한다),이 전화
OthelloMove garbage = new OthelloMove();
을 전달하면됩니까? 코드는 작동하지만 나에게는 매우 이상하게 보입니다!
최선의 방법이나 교장 변이를 얻는 '더 좋은 방법'이 있습니까? 정말 재귀 전문가가 아니며 디버깅 및 시각화가 매우 어렵습니다. 감사합니다.
** PS : 당신은 https://github.com/fernandotenorio/
나중에 사용해 보겠습니다. 감사합니다. Principal Variation은 어떻습니까? PV를 얻기 위해 더 많은 구조/코딩이 필요합니까? 아니면 간단한 스택이 트릭을 할 것입니까? – Fernando
이렇게하지 않는 이유 중 하나는 스레딩에 클래스가 안전하지 않다는 것입니다. 이론 상으로는 여러 시작 동작을 수행하기 위해 다중 스레드 포크를 실행하고자 할 수 있습니다. 모두 bestfound 변수를 공유하면이 방법이 작동하지 않습니다. 나는 클래스가 Runnable을 구현했기 때문에 이것을 언급한다. –
당신의 첫 번째 제안은 작동하지 않습니다, 엔진이 미쳐 ... – Fernando