• Recent Tutorials

  • Tripping The Class Fantastic: State Machines

    Round and Round We Go

    Effectively, your code will consist of a giant loop that never ends, going round and round, each time doing what you need to do for that state. This is good because your code is never sat waiting for things. In the case of firmware for micro-controllers, you're going to need to scan the hardware for changes of input state that could trigger a state transition (for example, you may be reading switches and de-bouncing the inputs to make sure the user has really pressed the button). In the case of a game, you can use this time for rendering, reading the controls or performing the calculations for your latest and greatest physics simulation.

    So let's consider a relatively simple example, the card vendor. The following pseudo code represents a few simple states:-

    Code: [View]
    WHILE (1=1) DO
      READ AND DE-BOUNCE INPUTS
    
      CASE CURRENTSTATE OF
    
        .....
    
        STATE_WAITING : BEGIN
          IF (VEND SIGNAL SET) THEN
            NEXTSTATE:=STATE_BEGIN_VEND
          END IF
        END
    
        STATE_BEGIN_VEND : BEGIN
          START MOTOR IN VEND STATE
          START JAM TIMER
          SET LED PROGRAM TO PROG_VENDING
          NEXTSTATE:=STATE_WAITING_FOR_CARD_ENTRY
        END
    
        STATE_WAITING_FOR_CARD_ENTRY : BEGIN
          IF JAM TIMER EXPIRED THEN
            STOP MOTOR
            SET LED PROGRAM TO PROG_FEED_JAM
            NEXTSTATE:=STATE_JAMMED_UNRECOVERABLE
          ELSE
            IF (CARD IN FEED SIGNAL SET) THEN
              STOP JAM TIMER
              START JAM TIMER
              NEXTSTATE:=STATE_WAITING_FOR_CARD_EXIT
            END IF
          END IF
        END
    
        .....
    
      END CASE
    
      IF (NEXTSTATE<>0) THEN
        CURRENTSTATE:=NEXTSTATE
        NEXTSTATE:=0
      END IF
    
    END WHILE
    As you can see, the actions that are performed in each state are really quite simple, and whilst this is an extremely simple example you should always aim for clean and simple states that have one or two exit conditions. If you find yourself putting lots of logic and flow control in a state (this probably means it's doing more than one thing), then you're probably over complicating it and you should think about simplifying the state by breaking it up a little.
    Comments 3 Comments
    1. Ñuño Martínez's Avatar
      Ñuño Martínez -
      Just did a very fast reading (titles and some of the code, not much more). Looks very interesting.

      I did my own state-machine library translating the one described in"Programming Game AI by Example". Your approach seems slightly different. I'll tell you once I read your tutorial in-deep and compare both ways.
    1. AthenaOfDelphi's Avatar
      AthenaOfDelphi -
      If anyone has downloaded the attachment, the file classBaseStateMachine.pas was missing. Sorry about that, thanks to d.spinetti for pointing out my mistake.
    1. Ñuño Martínez's Avatar
      Ñuño Martínez -
      Read. Your implementation is way different than the one described in"Programming Game AI by Example" but it's a nice approach.

      Thank-you.