Я работаю над минимаксным ИИ для 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;
}