Игра Ai с использованием Enum в качестве конечного автомата - PullRequest
0 голосов
/ 25 января 2019

Я хочу внедрить 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();


}

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Конечно, вы можете заставить его работать, но вам придется передать состояние игры следующей (...) - функции в качестве параметра. Например. перечисление вернет то, каким будет следующее состояние для игры в данном состоянии. Он не будет содержать ссылки на любое игровое состояние.

Лично ... нет смысла вовлекать в это ограничения enum.

0 голосов
/ 25 января 2019

как я буду отслеживать текущее состояние и как я могу это сделать изменить, когда вызывается функция next ()?

В вашей игре вам нужно следить за текущим состоянием:

FiniteStateAutomata state = FiniteStateAutomata.ATTACKING;

и измените его при необходимости:

state = state.next();
0 голосов
/ 25 января 2019

Хорошим решением для этого является использование функций в ваших перечислениях. Как и следующий:

 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);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...