Алгоритм MiniMax, выбрасывающий nullpointerexception
Создание игры Отелло / Реверси. Алгоритм AlphaBeta/MiniMax для размещения AI. Иногда ход, возвращаемый в минимаксе, будет нулевым, но я не могу понять, почему. Я сделал несколько отладочных операторов печати и думаю, что проблема возникает в самом минимаксном методе. Когда он проходит через узлы, если нет лучшего движения, то я просто получаю ноль, и он остается нулевым.
Решено: я объявлял макс неправильно, должно быть -1E100 вместо 0
private Node makeTree(Node parent, int depth) {
if(depth > 0 && parent.end == false) {
depth--;
boolean nextTurn = false;
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
Move currentMove = new Move(i, j, evaluator(parent.board.board, nextTurn));
if(parent.board.validMove(i, j, nextTurn)) {
Board futureBoard = new Board(parent.board.board);
Piece p = new Piece(nextTurn);
futureBoard.place(p, i, j);
Node newNode = new Node(currentMove, futureBoard, !nextTurn);
newNode.score = evaluator(futureBoard.board, !nextTurn);
newNode.end = newNode.board.gameOver();
parent.addChild(newNode);
newNode.parent = parent;
if(newNode == null) {
System.out.println("null node");
}
//System.out.println("child added");
}
}
}
if(depth > 0) {
for(Node n : parent.children) {
n = makeTree(n, depth);
}
}
}
return parent;
}
public Move minimax(Node root, boolean color)
{
double max = 0;
Node bestNode = new Node();
for (Node n : root.children)
{
//double tempMin = min(n, -1E100, 1E100);
double tempMin = min(n);
if (bestNode == null)
{
max = tempMin;
bestNode = n;
}
else if (tempMin > max)
{
max = tempMin;
bestNode = n;
}
}
return bestNode.move;
}
private double max(Node root) {
double max = -1E100;
for(Node n : root.children) {
if(n.children.isEmpty() || n.end) {
return evaluator(n.board.board, false);
}
else {
max = min(n);
}
}
return max;
}
private double min(Node root) {
double min = 1E100;
for(Node n : root.children) {
if(n.children.isEmpty() || n.end) {
return evaluator(n.board.board, false);
}
else
min = max(n);
}
return min;
}
private double max(Node n, double alpha, double beta) {
if(n.end || n.children.isEmpty()) {
return evaluator(n.board.board, false);
}
double value = -1E100;
for(Node nd : n.children) {
value = Math.max(value, min(nd, alpha, beta));
if(value >= beta) {
return value;
}
alpha = Math.max(alpha, value);
}
return value;
}
private double min(Node n, double alpha, double beta) {
if(n.end || n.children.isEmpty()) {
return evaluator(n.board.board, false);
}
double value = 1E100;
for(Node nd : n.children) {
value = Math.min(value, max(nd, alpha, beta));
if(value <= alpha) {
return value;
}
beta = Math.min(beta, value);
}
return value;
}