0

こんにちは、私は最近 Java でプログラミングを始めました。私が作成した三目並べゲームの AI を作成するタスクを自分自身に設定しました。ただし、最小最大アルゴリズムがスタック オーバーフロー エラーをスローし、エラーまたは問題のあるプログラム。

プログラムは次のとおりです。

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) は、プレーヤーの古い動きと新しい動きを含む新しい状態を作成することにより、その状態の後続の状態をすべて返します。

evaluate() は、その状態での勝ち、引き分け、または負けに応じて、値 -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:32 if (currentState.getNull() == 0)
: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;
}

誰かが助けてくれたらありがとう:)

4

1 に答える 1

0

あなたの問題はここにあります:

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

minmax メソッドを呼び出すと、メモリを使い果たす一連のデータが作成されます (Java では、一定量のコンピュータ メモリを使用できます)。次に、minmax 内で minmax を再度呼び出して、さらに多くのデータを作成します。これは、メモリがなくなるまで無限に発生し、Java が StackOverflow 例外をスローします。

于 2016-09-03T21:58:47.263 に答える