Jak zaimplementować wydajne drzewo wyszukiwania w grze Alpha-Beta?

Próbuję dowiedzieć się o sztucznej inteligencji i jak ją wdrożyć w programie. Najłatwiej jest zacząć od prostych gier (w tym przypadku Tic-Tac-Toe) i drzew wyszukiwania gier (wywołania rekurencyjne; nie rzeczywista struktura danych).znalazłem to bardzo przydatne wideo na temat wykładu na ten temat.

Problem, który mam, polega na tym, że pierwsze wywołanie algorytmu zajmuje bardzo dużo czasu (około 15 sekund) na wykonanie. Umieściłem dane wyjściowe dziennika debugowania w całym kodzie i wygląda na to, że wywołuje on części algorytmu zbyt wiele razy.

Oto metoda wyboru najlepszego ruchu dla komputera:

    public Best chooseMove(boolean side, int prevScore, int alpha, int beta){
    Best myBest = new Best(); 
    Best reply;

    if (prevScore == COMPUTER_WIN || prevScore == HUMAN_WIN || prevScore == DRAW){
        myBest.score = prevScore;
        return myBest;
    }

    if (side == COMPUTER){
        myBest.score = alpha;
    }else{
        myBest.score = beta;
    }
    Log.d(TAG, "Alpha: " + alpha + " Beta: " + beta + " prevScore: " + prevScore);
    Move[] moveList = myBest.move.getAllLegalMoves(board);
    for (Move m : moveList){
        String choice;
        if (side == HUMAN){
            choice = playerChoice;
        }else if (side == COMPUTER && playerChoice.equals("X")){
            choice = "O";
        }else{
            choice = "X";
        }
        Log.d(TAG, "Current Move: column- " + m.getColumn() + " row- " + m.getRow());
        int p = makeMove(m, choice, side);
        reply = chooseMove(!side, p, alpha, beta);
        undoMove(m);
        if ((side == COMPUTER) && (reply.score > myBest.score)){
            myBest.move = m;
            myBest.score = reply.score;
            alpha = reply.score;
        }else if((side == HUMAN) && (reply.score < myBest.score)){
            myBest.move = m;
            myBest.score = reply.score;
            beta = reply.score;
        }//end of if-else statement
        if (alpha >= beta) return myBest;
    }//end of for loop
    return myBest;
}

GdziemakeMove metoda wykonuje ruch, jeśli spot jest pusty i zwraca wartość (-1 - wygrana ludzka, 0 - remis, 1 - wygrana komputera, -2 lub 2 - w przeciwnym razie). Chociaż wierzę, że błąd może być wgetAllLegalMoves metoda:

    public Move[] getAllLegalMoves(String[][] grid){
    //I'm unsure whether this method really belongs in this class or in the grid class, though, either way it shouldn't matter.
    items = 0;
    moveList = null;
    Move move = new Move();

    for (int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            Log.d(TAG, "At Column: " + i + " At Row: " + j);
            if(grid[i][j] == null || grid[i][j].equals("")){
                Log.d(TAG, "Is Empty");
                items++;
                if(moveList == null || moveList.length < items){
                    resize();
                }//end of second if statement
                move.setRow(j);
                move.setColumn(i);
                moveList[items - 1] = move;
            }//end of first if statement
        }//end of second loop
    }//end of first loop
    for (int k = 0; k < moveList.length; k++){
        Log.d(TAG, "Count: " + k + " Column: " + moveList[k].getColumn() + " Row: " + moveList[k].getRow());
    }
    return moveList;
}

private void resize(){
    Move[] b = new Move[items];
    for (int i = 0; i < items - 1; i++){
        b[i] = moveList[i];
    }
    moveList = b;
}

Podsumowując: Co powoduje, że mój telefon, aby wybrać najlepszy ruch, tak długo? czego mi brakuje? Czy istnieje łatwiejszy sposób wdrożenia tego algorytmu? Każda pomoc lub sugestie będą bardzo mile widziane, dzięki!

questionAnswers(2)

yourAnswerToTheQuestion