Ошибка переполнения стека в минимаксном алгоритме

Привет, поэтому я недавно начал программировать на Java и поставил перед собой задачу создать ИИ для игры в крестики-нолики, которую я сделал. Однако алгоритм minmax выдает ошибку переполнения стека, и я не могу видеть в ошибке или программа, в которой проблема.

Вот программа:

public State minmax(boolean max, State currentState)
{
    if (currentState.getNull() == 0) {
        return currentState;
    }
    else {
        State[] successorStates = currentState.getSuccessorStates(aiPlayer);

        ArrayList<Integer> scoresTemp = new ArrayList<>();

        for (State state : successorStates) {
            scoresTemp.add(evaluate(aiPlayer, minmax(!max, state)));
        }

        Integer[] scores = (Integer[]) scoresTemp.toArray();

        if (max) {
            State maxState = successorStates[0];
            int maxScore = evaluate(aiPlayer, maxState);
            for (int score : scores) {
                if (scores[0] > maxScore) {
                    maxScore = score;
                    maxState = successorStates[score];
                }
            }
            return maxState;
        }
        else
        {
            State minState = successorStates[0];
            int minScore = evaluate(aiPlayer, minState);
            for (int score : scores) {
                if (scores[0] > minScore) {
                    minScore = score;
                }
            }
            return minState;
        }
    }
}

Он возвращает состояние, которое лучше всего сделать.

getNull() возвращает количество оставшихся мест, на которых можно играть.

getSuccesorStates(Player) возвращает все последующие состояния этого состояния, создавая новое состояние, которое содержит старые ходы и новое состояние Player.

оценка() возвращает значение -1, 0 или 1 в зависимости от выигрыша, ничьей или проигрыша в этом состоянии. Никто не возвращает 0

редактировать:

public int getNull()
{
    int amount = 0;

    for (int x =0; x<9; x++)
    {
        if (getAllCells()[x]==null)
        {
            amount++;
        }
    }

    return amount;
}

public State[] getSuccessorStates(Player player)
{
    State[] states = new State[getNull()];

    Player[][] stateCells = cells.clone();
    int[][] nullPositions = getNulls();

    for (int x=0; x<getNull(); x++)
    {
        stateCells[nullPositions[x][0]][nullPositions[x][1]] = player;
        states[x] = new State(player, stateCells);
        stateCells = cells.clone();
    }

    return states;
}

Caused by: java.lang.StackOverflowError
    at sample.AI.minmax(AI.java:23)
    at sample.AI.minmax(AI.java:32)
    at sample.AI.minmax(AI.java:32)
    .
    .
    .

23: if (currentState.getNull() == 0)
32: scoresTemp.add(evaluate(aiPlayer, minmax(!max, state)));

public Player[] getAllCells()
{
    Player[] cellList = new Player[9];
    for (int x = 0; x<3; x++)
    {
        for (int y = 0; y<3; y++)
        {
            cellList[y*3+x] = cells[x][y];
        }
    }
    return cellList;
}

minmax вызывается:

public Ply getPly(State state)
{
    State bestState = minmax(true, state);
    State[] successorStates = state.getSuccessorStates(aiPlayer);
    ArrayList<State> states = new ArrayList<State>();
    for (int x=0; x<successorStates.length; x++)
    {
        states.add(successorStates[x]);
    }
    int[][] nulls = state.getNulls();

    Ply bestPly = new Ply(aiPlayer, nulls[states.indexOf(bestState)][0], nulls[states.indexOf(bestState)][1]);

    return bestPly;
}

Спасибо, если кто-то может помочь :)


person Aliator    schedule 03.09.2016    source источник
comment
Где твоя рекурсия? Какие строки участвуют в исключении SO?   -  person Hovercraft Full Of Eels    schedule 03.09.2016
comment
Пожалуйста, включите код для State.getNull() и State.getSuccessorStates(Player)   -  person J Earls    schedule 03.09.2016
comment
Это похоже на возможное место: scoresTemp.add(evaluate(aiPlayer, minmax(!max, state)));   -  person Hovercraft Full Of Eels    schedule 03.09.2016
comment
добавил их, спасибо   -  person Aliator    schedule 03.09.2016
comment
в sample.AI.minmax(AI.java:23) в sample.AI.minmax(AI.java:32) в sample.AI.minmax(AI.java:32) в sample.AI.minmax(AI.java: 32) в sample.AI.minmax(AI.java:32) в sample.AI.minmax(AI.java:32) и так далее, и так далее...   -  person Aliator    schedule 03.09.2016
comment
если (currentState.getNull() == 0) {   -  person Aliator    schedule 03.09.2016
comment
scoresTemp.add(оценить(aiPlayer, minmax(!max, состояние)));   -  person Aliator    schedule 03.09.2016
comment
Пожалуйста, отредактируйте свой вопрос и включите эту важную информацию в вопрос.   -  person Hovercraft Full Of Eels    schedule 03.09.2016
comment
и показать getAllCells(...).   -  person Hovercraft Full Of Eels    schedule 03.09.2016
comment
Готово, спасибо за совет. это мой первый раз   -  person Aliator    schedule 03.09.2016
comment
Где впервые вызывается minmax(...)?   -  person Hovercraft Full Of Eels    schedule 03.09.2016
comment
Поместите несколько операторов print в свой код (особенно в начале ваших функций) и посмотрите, что произойдет во время работы программы. Я уверен, что это очень поможет вам.   -  person Saeid    schedule 03.09.2016
comment
спасибо за совет, sudo, я попрошу их проверить, что я помещаю в строки 23 и 32 и некоторые другие части   -  person Aliator    schedule 03.09.2016
comment
Обратите внимание: отвечая на чей-либо комментарий, добавьте @ перед его именем в стеке, например, @sudomakeinstall2. Это уведомит этого человека о том, что вы разместили для него комментарий.   -  person Hovercraft Full Of Eels    schedule 03.09.2016
comment
Спасибо @HovercraftFullOfEels   -  person Aliator    schedule 03.09.2016


Ответы (1)


Ваша проблема здесь:

scoresTemp.add(evaluate(aiPlayer, minmax(!max, state)));

Когда вы вызываете метод minmax, вы создаете кучу данных, которые используют память (java позволяет использовать определенный объем памяти компьютеров). Затем вы внутри minmax снова вызываете minmax, заставляя его создавать еще больше данных, и это происходит бесконечно, пока не останется памяти, и Java не выдаст исключение StackOverflow.

person Jonathan Botha    schedule 03.09.2016