ИИ, управляемый MiniMax, занимает 5 секунд, чтобы сделать первый ход в игре Android TicTacToe - PullRequest
0 голосов
/ 16 октября 2019

Я создал полную игру в крестики-нолики на андроиде с минимаксным ИИ.
Сначала я написал и запустил код в окне консоли в IDE NetBeans для простоты тестирования, и код работал нормально. Однако, когда я интегрировал код в свое приложение для Android, ИИ потребовалось 5 секунд, чтобы совершить свой первый ход. Хотя время, необходимое для воспроизведения других ходов, составляло <1 секунда. <br>Если бы в коде были какие-либо проблемы, то другие ходы должны были бы также занять некоторое время.

Я не могу найти решение этой проблемы. Ниже приведен мой код:

AI_Move.java: -

class AI_Move {   
private int x;
private int y;
private int score;

public AI_Move() {
}

public AI_Move(int score) {
    this.score = score;
}

//getters and setters method.....
    }

AI_Player.java: -

class AI_Player {

    private GameActivity activeGame;

    AI_Player(GameActivity gameActivity) {
        activeGame = gameActivity;
    }

    AI_Move playMove() {
        return getBestMove(PLAYER_AI);
    }

    private AI_Move getBestMove(String player) {          //This is the minimax algorithm function
        String status = activeGame.gameStatus();

        if (status != null) {
            switch (status) {
                case PLAYER_AI:
                    return new AI_Move(10);
                case PLAYER_HUMAN:
                    return new AI_Move(-10);
                case GameActivity.TIE:
                    return new AI_Move(0);
            }
        }

        ArrayList<AI_Move> moves = new ArrayList<>();

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {

                if (activeGame.getValue(i, j).equals(NO_VALUE)) {  //if empty slot is found
                    activeGame.enterValue(i, j, player);    //enter player (X or O)
                    AI_Move temp_move = new AI_Move();

                    if (player.equals(PLAYER_AI)) {
                        temp_move.setScore(getBestMove(PLAYER_HUMAN).getScore());
                        temp_move.setY(i);
                        temp_move.setX(j);
                    } else {
                        temp_move.setScore(getBestMove(PLAYER_AI).getScore());
                        temp_move.setY(i);
                        temp_move.setX(j);
                    }

                    moves.add(temp_move);
                    activeGame.enterValue(i, j, NO_VALUE);
                }

            }
        }

        int bestMove = 0;
        int bestScore;

        if (player.equals(PLAYER_AI)) {
            bestScore = -100;
            for (int i = 0; i < moves.size(); i++) {
                if (moves.get(i).getScore() > bestScore) {
                    bestScore = moves.get(i).getScore();
                    bestMove = i;
                }
            }
        } else if (player.equals(PLAYER_HUMAN)) {
            bestScore = 100;
            for (int i = 0; i < moves.size(); i++) {
                if (moves.get(i).getScore() < bestScore) {
                    bestScore = moves.get(i).getScore();
                    bestMove = i;
                }
            }
        }
        return moves.get(bestMove);
    }
}

Ниже приведена победная логика, содержащая функции (в GameActivity.java), используемые в AI_Player.java:-

public String gameStatus() {     //this returns a string indicating the winner or a tie
    ImageButton s1, s2, s3;
    String status;
    isTied = true;

    for (int pos = 0; pos < 3; pos++) {
        s1 = slots[pos][pos];
        s2 = slots[pos][(pos + 1) % 3];
        s3 = slots[pos][(pos + 2) % 3];
        status = check(s1, s2, s3);
        if (status != null && !status.equals(NO_VALUE)) {
            return status;
        }

        s2 = slots[(pos + 1) % 3][pos];
        s3 = slots[(pos + 2) % 3][pos];
        status = check(s1, s2, s3);
        if (status != null && !status.equals(NO_VALUE)) {
            return status;
        }

        if (pos != 1) {

            s1 = slots[2 - pos][0];
            s2 = slots[1][1];
            s3 = slots[pos][2];
            status = check(s1, s2, s3);
            if (status != null && !status.equals(NO_VALUE)) {
                return status;
            }

        }
    }
    return isTied == false ? null : TIE;
}

private String check(ImageButton s1, ImageButton s2, ImageButton s3) {
    if (!s1.getTag().equals(NO_VALUE) && !s2.getTag().equals(NO_VALUE) && !s3.getTag().equals(NO_VALUE)) {    //if all three slots are filled then...
        if (s1.getTag().equals(s2.getTag()) && s2.getTag().equals(s3.getTag())) {   //return winner if the slots are same (contain same tags)
            return s1.getTag().toString();
        } else {
            return null;
        }
    } else {    //if any one slot is empty return NO_VALUE
        isTied = false;
        return NO_VALUE;
    }

}

Мой «взлом» для задачи: -

Однако я нашел хак для этой проблемы. Я дал первый ход (который занимал 5 секунд) самому ИИ через следующий код и оставил остальные ходы для алгоритма: -

Random random = new Random();
    int y = random.nextInt(3);
    int x = random.nextInt(3);;
    fillSlot(slots[y][x], PLAYER_AI);

Удивительно, но он работал как хотелось!

Я знаю, что это "грязная работа", но я не могу думать о чем-то другом, поэтому я пришел сюда.

...