Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to implement a large state machine?

Basically I have a state machine that controls a game character's attacks, with timings based on the animation length.

So for example:

I start at the default state, and if the player hits an attack button it starts an attack, switching the state and setting a timer based on the attacks length. The state machine gets more complex however when I consider charge attacks that can be cancelled, attacks that can move to different states depending on what they hit, and also every state has unique ways of dealing with the character being attacked. At the moment I have large switch statements. I thought about polymorphism but that would require a new class for every state for which there are a lot (starting attack, attacking and finishing attack all require separate states for example).

The switch statement works, but its quite large and also isn't as easily modified as an inheritance based system.

Any suggestions on good looking implementations?

EDIT: This is using java.

like image 350
deek0146 Avatar asked Jun 16 '11 20:06

deek0146


People also ask

How are finite state machines implemented?

A finite state machine may be implemented through software or hardware to simplify a complex problem. Within an FSM, all states in consideration exist in a finite list and the abstract machine can only take on one of those states at a time. This approach allows each input and output scenario to be studied and tested.

What is the quickest way of starting a new state machine project in LabVIEW?

Run The State Machine TemplateLaunch LabVIEW and select Create Project. From the Create Project dialog, launch the Simple State Machine template. In the Project Explorer window, open and run Main.vi. Click the front panel controls to display different pop-up dialog boxes.


3 Answers

With larger state machines you must watch out for the "transition explosion" phenomenon. It turns out that the traditional Finite State Machines don't provide mechanisms to reuse common transitions across many states, so you end up repeating too much and your state machine "explodes" (this goes also against the Do-not-Repeat-Yourself (DRY) principle).

For that reason I would recommend using hierarchical state machines and and implementation technique that allows easy mapping such state machines to code. For more information about hierarchical state machines, see the Wikipedia article http://en.wikipedia.org/wiki/UML_state_machine.

like image 101
Miro Samek Avatar answered Oct 09 '22 08:10

Miro Samek


Consider building a table-driven state machine. If you think about the definition of a state machine, you have basically a set of states with a distinguished initial state, a transition function, and (in this case) an input and output alphabet.

You can construct a table indexed by current state and input, and use a pointer to function, or a functor class, to represent what happens. That function should return the next state. Then you can build the state machine as (pseudocode):

 state := initial state
 while(state != STOP)
    state := (lookupTransition(inputs))()

where lookupTransition(inputs) simply finds the next state. I'm assuming here that the transition functions are functions of no arguments returning state, so lookupTransition(inputs) has to be a function of however many inputs you have, returning a pointer to function of void arguments returning state.

Set this up correctly, and you can put all the state machine and behavior into one table, which can be easily modified and recompiled.

(For extra credit, figure out how you can load that table from a file, so you don't need to recompile at all.)

Update

In Java, use something like a functor class in place of function pointers.

Another Update

Of course, another option is to use a state machine compiler like Ragel.

like image 43
Charlie Martin Avatar answered Oct 09 '22 07:10

Charlie Martin


Boost has a perfectly fine state machine, the only drawback is getting used to template / type programming

http://www.boost.org/doc/libs/1_46_1/libs/statechart/doc/index.html

like image 26
totowtwo Avatar answered Oct 09 '22 09:10

totowtwo