Алгоритм MiniMax, выбрасывающий нулевое значение - PullRequest
0 голосов
/ 07 июня 2019

Создание игры Отелло / Реверси.АлфаБета / 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;
    }
...