Игра Ai с использованием Enum в качестве конечного автомата
Я хочу внедрить ai в простую игру в стиле уличных бойцов, и я хочу сделать это с помощью конечного автомата. Для простого примера этот FSM имеет состояния:
Атакующий, преследующий, убегающий
Из того, что я прочитал в Интернете, хорошим способом реализации этого было бы использование Enum, хотя я немного запутался, как это сделать.
В любой момент FMS находится в текущем состоянии и, если в игре произойдет изменение, это состояние может измениться с помощью функции перехода (next()). Используя Enum, как показано ниже, как я буду отслеживать текущее состояние и как я могу сделать это изменение при вызове функции next ()?
public enum FiniteStateAutomata {
ATTACKING() {
public FiniteStateAutomata next() {
if (!gun.isInRange()) return CHASING;
else if (health.isLow()) return FLEEING;
}
},
CHASING() {
public FiniteStateAutomata next() {
if (gun.isInRange()) return ATTACKING;
else if (health.isLow()) return FLEEING;
}
},
FLEEING() {
public FiniteStateAutomata next() {
if (health.isHigh()) return CHASING;
}
};
public abstract FiniteStateAutomata next();
}
4 ответа
Как я могу отслеживать текущее состояние и как я могу сделать это изменение при вызове функции next()?
В вашей игре вам нужно отслеживать текущее состояние:
FiniteStateAutomata state = FiniteStateAutomata.ATTACKING;
и измените его при необходимости:
state = state.next();
Реализация вашего собственного конечного автомата — непростая задача, потому что одна теория конечного автомата, которую большинство людей игнорирует, но, по моему мнению, невозможно смоделировать сложные конечные автоматы, вложенные / вложенные конечные автоматы, что имеет решающее значение для предотвращения проблемы взрыва состояния, которую я обсуждал. здесь .
Или если вы хотите независимого обсуждения предмета.
Я не знаю, на какой платформе вы планируете разрабатывать Java-игру, но если вы планируете реализовать конечный автомат на стороне сервера, я советую вам проверить Akka FSM.
Если вам нужен пример реализации для Akka, проверьте блоги blog1 blog2
Конечно, вы можете заставить его работать, но вы должны передать состояние игры следующей (...) функции в качестве параметра. Например, перечисление вернет то, каким будет следующее состояние для игры в данном состоянии. Он не будет содержать ссылки на любое игровое состояние.
Лично... нет смысла включать ограничения enum в это.
Хорошим решением для этого является использование функций в ваших перечислениях. Как следующий:
public enum FiniteStateAutomata {
ATTACKING((gun, health) -> {
if (!gun.isInRange()) return CHASING;
else if (health.isLow()) return FLEEING;
}),
CHASING((gun, health) -> {
if (gun.isInRange()) return ATTACKING;
else if (health.isLow()) return FLEEING;
}),
FLEEING((gun, health) -> {
if (health.isHigh()) return CHASING;
else return FLEEING;
});
private BiFunction<Gun, Health, FiniteStateAutomata> next;
FiniteStateAutomata(BiFunction<Gun, Health, FiniteStateAutomata> next) {
this.next = next;
}
public FiniteStateAutomata next(Gun gun, Health health) {
return next.apply(gun, health);
}
}