0

我想在一个简单的街头霸王风格游戏中实现一个人工智能,我想用一个有限状态机来做到这一点。举个简单的例子,这个 FSM 有以下状态:

攻击、追逐、逃跑

从我在网上阅读的内容来看,实现这一点的一个好方法是使用枚举,尽管我对如何做到这一点有点困惑。

在任何时候,FMS 都处于当前状态并且应该在游戏中发生变化,这种状态可以通过转换函数 (next()) 改变。使用像下面这样的枚举,我将如何跟踪当前状态,以及在调用 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

3 回答 3

0

我将如何跟踪当前状态,以及在调用 next() 函数时如何进行此更改?

在您的游戏中,您需要跟踪当前状态:

FiniteStateAutomata state = FiniteStateAutomata.ATTACKING;

并在需要时更改它:

state = state.next();
于 2019-01-25T13:38:10.117 回答
-1

当然你可以让它工作,但你必须将游戏状态作为参数传递给 next(...) 函数。例如,枚举将返回给定状态下游戏的下一个状态。它不会引用任何游戏状态本身。

就个人而言...没有必要将枚举的限制纳入其中。

于 2019-01-25T13:09:55.583 回答
-1

一个好的解决方案是在枚举中使用函数。像下一个:

 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);
        }
    }
于 2019-01-25T13:09:12.863 回答