First Solo Challenge with a simple state machine

I found it very educational by reading posts in this community. It helped me to re-think my solution and re-organize some of my code.

Below is what I came up with given what has been taught up to this point.

public class Hacker : MonoBehaviour
{
    // Game state
    int level;
    string terminalInput;

    enum State
    {
        Initialized,
        MainMenu,
        Password,
        Win
    };
    State state;

    enum Event
    {
        Start,
        TerminalInput
    }

    private void Awake()
    {
        Debug.Log("Awake");
    }
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Start");

        state = State.Initialized;
        RunGame(Event.Start);
    }

    void OnUserInput(string input)
    {
        terminalInput = input;
        RunGame(Event.TerminalInput);
    }

    void RunGame(Event e)
    {
        if (state == State.Initialized)
        {
            if (e != Event.Start)
            {
                // Unexpected event
                // Report the error
                ReportError("Current state: " + state + ".  Received unexpected event: " + e);
            }
            ShowMainMenu();
        }
        else if (state == State.MainMenu)
        {
            if (e == Event.Start)
            {
                // Unexpected event
                // Report the error
                ReportError("Current state: " + state + ".  Received unexpected event: " + e);
            }
            else if (e == Event.TerminalInput)
            {
                if (isValidMenuItem(this.terminalInput))
                {
                    GetPassword();
                }
                else
                {
                    // Prompt the user again
                    // Stay in the same state: State.MainMenu
                    InvalidMenuInput();
                }
            }
        }
        else if (state == State.Password)
        {
            if (e == Event.Start)
            {
                // Unexpected event
                // Report the error
                ReportError("Current state: " + state + ".  Received unexpected event: " + e);
            }
            else if (e == Event.TerminalInput)
            {
                // validate the password that was entered
                string password = this.terminalInput;
                if (isValidPassword(password))
                {
                    Win();
                }
                else
                {
                    InvalidPassword();
                    GetPassword();
                }
            }
        }
        else if (state == State.Win)
        {
            if (e == Event.Start)
            {
                // Unexpected event
                // Report the error
                ReportError("Current state: " + state + ".  Received unexpected event: " + e);
            }
            else if (e == Event.TerminalInput)
            {

                // Start a new game
                ResetGame();
                RunGame(Event.Start);
            }
        }
        else
        {
            // Unexpected state
            // Report the error
            ReportError("Current state: " + state + ".  Received unexpected event: " + e);
        }
    }

    void ShowMainMenu()
    {
        state = State.MainMenu;
        Terminal.ClearScreen();
        Terminal.WriteLine("Welcome, Hacker.");
        Terminal.WriteLine("Which system would you like to access?");
        Terminal.WriteLine("");
        Terminal.WriteLine("1 ) Library");
        Terminal.WriteLine("2 ) Bank");
        Terminal.WriteLine("3 ) Police Station");
        Terminal.WriteLine("4 ) NASA");
        Terminal.WriteLine("");
        Terminal.WriteLine("Enter selection [1, 2, 3, or 4]: ");
    }

    private void GetPassword()
    {
        state = State.Password;
        Terminal.WriteLine("Enter password:");
    }

    private void Win()
    {
        state = State.Win;
        Terminal.WriteLine("Successfully entered!");
        Terminal.WriteLine("Press enter to access a different area");
    }

    private void InvalidMenuInput()
    {
        Terminal.WriteLine("Invalid menu option.  Try again.");
        Terminal.WriteLine("Pleasse enter 1, 2, 3, or 4");
    }

    private static void InvalidPassword()
    {
        Terminal.WriteLine("Invalid password.  Please try again.");
    }

    private bool isValidPassword(String password)
    {
        bool isValid = false;

        if (level == 1)
        {
            if (password == "librarypassword")
            {
                isValid = true;
            }
        }
        else if (level == 2)
        {
            if (password == "bankpassword")
            {
                isValid = true;
            }
        }
        else if (level == 3)
        {
            if (password == "policepassword")
            {
                isValid = true;
            }
        }
        else if (level == 4)
        {
            if (password == "nasapassword")
            {
                isValid = true;
            }
        }

        return isValid;
    }

    private bool isValidMenuItem(string input)
    {
        bool isValid = true;

        if (input == "1")
        {
            level = 1;
        }
        else if (input == "2")
        {
            level = 2;
        }
        else if (input == "3")
        {
            level = 3;
        }
        else if (input == "4")
        {
            level = 4;
        }
        else
        {
            isValid = false;
        }

        return isValid;
    }

    void ResetGame()
    {
        level = 0;
        Terminal.ClearScreen();
        state = State.Initialized;
    }
    private void ReportError(string error)
    {
        Debug.Log(error);
    }

}
1 Like

state machine if from my perspective is something that have something to do with AI ain’t I right? @ppineda

Hi @Chris_Shuo,

I haven’t done AI, so I can’t comment if state machines are used with it. But one area where state machines are used is with event driven systems. A state machine for this terminal hacking game is really overkill, but I thought I would just add it in. Games are event driven, so I just thought I’d just get an early start. The state machine in my implementation is very simplistic. A proper state machine should be a class. However, since we are not learning about classes, I didn’t implement it.

Thanks for the comment.

Privacy & Terms