0

I want to implement an ai into a simple street fighter style game, and I want to do this with a finite state machine. For a simple example, this FSM has the states:

Attacking, Chasing, Fleeing

From what I have read online, a good way of implementing this would be to use an Enum, although I'm slightly confused how to do this.

At any one point the FMS is in a current state and should change occur in the game, this state could change through a transition function (next()). Using an Enum like below, how would I keep track of the current state, and how could I make this change when the next() function is called?

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();


}
Hdot
  • 403
  • 4
  • 11
  • 1
    This would be better suited for https://codereview.stackexchange.com/ – Torben Jan 25 '19 at 13:05
  • @Torben I'm not sure it would, it's not finished – Tom Jan 25 '19 at 13:07
  • @Hdot [This answer](https://stackoverflow.com/a/54239225/8075923) showcases how enums can be used to define actions in a program and [this answer](https://stackoverflow.com/a/54239645/8075923) demonstrates how functional interfaces can be used, which is probably the best choice in my humble opinion. – Soutzikevich Jan 25 '19 at 14:57

3 Answers3

0

how would I keep track of the current state, and how could I make this change when the next() function is called?

In your game you need to keep track of the current state :

FiniteStateAutomata state = FiniteStateAutomata.ATTACKING;

and change it when needed :

state = state.next();
c0der
  • 17,996
  • 6
  • 31
  • 62
-1

The good solution for that is using functions in your enumerations. Like the next one:

 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);
        }
    }
Naya
  • 820
  • 6
  • 19
-1

Sure you can make it work, but you would have to pass the game state to the next(...)-function as a parameter. E.g. the enum would return what the next state would be for a game in a given state. It would not hold references to any game state itself.

Personally... there's no point in involving the limitations of enum into this.

Torben
  • 3,469
  • 24
  • 27