Функция оценки минимаксного алгоритма Пакмана - PullRequest
0 голосов
/ 11 февраля 2019

Я работаю над минимаксным ИИ для pacman, и мне нужна небольшая помощь, чтобы сначала убедиться, что я нахожусь в правильном общем направлении, а во-вторых, для улучшения моей функции оценки.

ИзЯ могу получить все предыдущие состояния, точечные локации, призрачные локации, локации pacmans.Очки и время сохраняются в игре.В настоящее время моя функция оценки возвращает результат, если точка съела, сколько всего точек было собрано, и местоположение ближайшего призрака на расстоянии до 7 квадратов.

Основная проблема, с которой я сталкиваюсь, заключается в том, чтоигра продолжается. pacman просто сидит в углу, прыгая между 2 ходами, и ничего не сделает, пока к нему не придет призрак.В настоящее время я думаю, что хороший способ решить эту проблему - найти ближайшую точку и либо добавить, либо вычесть это место из оценки.Если у кого-то есть какие-нибудь отличные идеи, я бы с удовольствием их услышал.

Спасибо

public Move chooseMove(Game game) {
    return findBestMove(game);
}

private int maxvalue(Game game, int depth) {
    State currentState = game.getCurrentState();
    if(depth == DEPTH_LIMIT || game.isFinal(currentState)) {
        return evaluateMove(currentState);
    }
    else {
        int bestScore = Integer.MIN_VALUE;
        List<Move> legalMoves = game.getLegalPacManMoves();

        for(Move move: legalMoves) {
            //Go to next state
            State nextState = game.getNextState(currentState, move);
            game.setCurrentState(nextState);

            bestScore = Math.max(minvalue(game, depth + 1), bestScore);

            //Undo Move
            game.setCurrentState(currentState);
        }
        return bestScore;
    }
}

private int minvalue(Game game, int depth) {
    State currentState = game.getCurrentState();
    if(depth == DEPTH_LIMIT || game.isFinal(currentState)) {
        return evaluateMove(currentState);
    }
    else {
        int worstScore = Integer.MAX_VALUE;
        List<Move> legalMoves = game.getLegalPacManMoves();

        for(Move move: legalMoves) {
            //Go to next state
            State nextState = game.getNextState(currentState, move);
            game.setCurrentState(nextState);

            worstScore = Math.min(maxvalue(game, depth + 1), worstScore);

            //Undo Move
            game.setCurrentState(currentState);
        }
        return worstScore;
    }
}

private Move findBestMove(Game game) {
    int bestValue = Integer.MIN_VALUE;
    Move bestMove = Move.NONE;
    State currentState = game.getCurrentState();

    List<Move> legalMoves = game.getLegalPacManMoves();

    for(Move move : legalMoves) {
        //Go to next state
        State nextState = game.getNextState(currentState, move);
        game.setCurrentState(nextState);

        int moveValue = maxvalue(game, 0);

        //Undo Move
        game.setCurrentState(currentState);

        if(moveValue > bestValue) {
            bestValue = moveValue;
            bestMove = move;
        }
    }

    return bestMove;
}

private int evaluateMove(State state) {
    //Get previous state
    State previousState = state.getParent();

    //Was a dot eaten this state
    int dotEaten = (previousState.getDotLocations().size() - state.getDotLocations().size());

    int totalDots = state.getHistory().get(0).getDotLocations().size() - state.getDotLocations().size();

    return dotEaten + totalDots + getClosestGhost(state);
}

private int getClosestGhost(State state) {
    List<Location> ghosts = state.getGhostLocations();
    Location pacman = state.getPacManLocation();

    int closest = Integer.MAX_VALUE;

    for(Location ghost : ghosts) {
        int x = ghost.getX() - pacman.getX();
        x = Math.abs(x);

        int y = ghost.getY() - pacman.getY();
        y = Math.abs(y);

        int total = x + y;

        if(total < closest) {
            closest = total;
        }
    }

    if(closest > 7) {
        closest = 7;
    }

    return closest;
}
...