Three simple ways to code finite state machines

Finite State Machine Diagram Title Image

This tutorial will show you three simple ways to code finite state machines using the C++ programming language in Visual Studio.

1. Enum and Switch Case

2. Inheritance and Polymorphism

3. Function Pointer

Introduction

A finite state machine can only be in one of a finite number of states at any given time. This means complex behaviour can be simplified by splitting code into multiple states. Each state can transition from zero to many states depending on the supplied inputs.

To follow along to this tutorial, you can either just read it and apply the knowledge to your programming language. Or you can use Visual Studio, by creating a solution, then create a project with a console application for each numbered section. Then run the project to see and engage with the output in the console window.

1. Enum and Switch Case

The first way to implement the finite state machine pattern uses an enum and a switch case.

First include iostream, since we need this to output text to the console.

#include <iostream>

We create an enum called State, which has two states: wait and dance.

// The states
enum class State
{
    WAIT, DANCE
};

Next we will code the main function.

int main()
{
// code goes here
}

Create a state variable.

    // Set the state
    State state = State::WAIT;

Next we want to create a string and check it’s value. Since we will be reading the keyboard input into this string soon. We check if the string is not equal to ‘q’. Since we will use ‘q’ to quit the program.

    std::string s;
    while (s != "q")
    {
    // code goes here
    }

Inside the while loop, output a message to console for the user.

std::cout << "Type '1' to wait, '2' to dance, or 'q' to quit" << std::endl;

Then get the keyboard input and store it in the string variable.

        // Get keyboard input
        std::cin >> s;

Switch the state based on the key press.

        // Switch state based on number
        if (s == "1")
        {
            state = State::WAIT;
        }
        else if (s == "2")
        {
            state = State::DANCE;
        }

Finally we can execute the currently selected state using a switch case and enum state value.

        // Execute current state
        switch (state)
        {
        case State::WAIT:
            std::cout << "I'm waiting!" << std::endl;
            break;
        case State::DANCE:
            std::cout << "I'm dancing!" << std::endl;
            break;
        }

2. Inheritance And Polymorphism

The second way to implement the finite state machine pattern uses inheritance and polymorphism.

First include iostream, since we need this to output text to the console.

#include <iostream>

Next create a class called StateParent. This class will be used as the parent class, and the children will implement it’s pure virtual function called Execute. A class with a pure virtual function cannot be instantiated.

class StateParent
{
public:
    // Pure virtual function has to be implemented by children
    virtual void Execute() = 0;
};

Now create a class called WaitState. Which will output a unique message to the console in the Execute function, which we have overridden from the parent class.

class WaitState : public StateParent
{
public:
    void Execute() override
    {
        std::cout << "I'm waiting!\n";
    }
};

Next create a class called DanceState. Which will output a unique message to the console in the Execute function, which we have overridden from the parent class.

class DanceState : public StateParent
{
public:
    void Execute() override
    {
        std::cout << "I'm dancing!\n";
    }
};

Now create a main function.

int main()
{
// code goes here
}

Inside the main function, create two variables. One for the WaitState and one for the DanceState.

    WaitState waitState;
    DanceState danceState;

Next create a pointer to the StateParent class. Then set the current state pointer to the address of the waitState variable.

    // Set the state
    StateParent*  currentState = &waitState;

Now create a string variable and a while loop. Like before we use the ‘q’ letter to quit the program.

    std::string s;
    while (s != "q")
    {
    // code goes here
    }

Inside the while loop, we will output a message to the user again to tell them how to use the program. Then get the keyboard input.

        std::cout << "Type '1' to wait, '2' to dance, or 'q' to quit" << std::endl;
        // Get keyboard input
        std::cin >> s;

Then we will switch the state if the correct number key is pressed, by changing the current state pointer so that it points to a different class instance.

        // Switch state based on number
        if (s == "1")
        {
            currentState = &waitState;
        }
        else if (s == "2")
        {
            currentState = &danceState;
        }

Finally we can execute the current state using the pointer.

        // Execute current state
        currentState->Execute();

3. Function Pointer

The third way to implement the finite state machine pattern uses inheritance and polymorphism.

First include iostream, since we need this to output text to the console.

#include <iostream>

Create a function called Wait. Which will output a unique message to the console.

static void Wait()
{
    std::cout << "I'm waiting!" << std::endl;
}

Then create another function called Dance. Which will output a unique message to the console.

static void Dance()
{
    std::cout << "I'm dancing!" << std::endl;
}

Next create a main function.

int main()
{
// code goes here
}

Inside the main function, we will create a function pointer variable. The function pointer is called ‘currentState’. It has a return type of void, and takes no arguments, like the two functions above! We set it to point to the ‘Wait’ function.

    // Set the state
    void (*currentState)() = Wait;

Next create a string variable and a while loop. Like before we use the ‘q’ letter to quit the program.

    std::string s;
    while (s != "q")
    {
    // code goes here
    }

Inside the while loop, we will output a message to the user again to tell them how to use the program. Then get the keyboard input.

        std::cout << "Type '1' to wait, '2' to dance, or 'q' to quit" << std::endl;
        // Get keyboard input
        std::cin >> s;

Now we will switch the state based on the key press, by setting the function pointer to a different function if the correct number key is pressed.

        // Switch state based on number
        if (s == "1")
        {
            currentState = Wait;
        }
        else if (s == "2")
        {
            currentState = Dance;
        }

Finally we can execute the current state by calling the function, which the function pointer points to.

        // Execute current state
        currentState();

Conclusion

Congratulations you have completed this tutorial and learned three simple ways to implement the finite state machine pattern. Thanks for reading this tutorial, see you in the next post.

For more finite state machine tutorials, check out:

  1. Coding a bouncing slime in Processing
  2. Rabbit and Carrot Finite State Machine

One response to “Three simple ways to code finite state machines”

Leave a comment