Behaviors - a state machine without a headache

  • Tutorial
The standard approach to describing the sequence of user inputs and reactions to them (for example, when controlling a character in a game) is a state machine. He, however, often leads to cumbersome programs, understanding of which requires considerable effort or even sketching on paper. In this article, I suggest a small shift in the description, which allows you to save screen space and brain resource.


image

The shift in the description is in the use of coroutines. To use this technique, you need to imagine what behavior we expect from the computer in the end. Therefore, I called the small library that I created for this task - Behaviors.

When a user interacts with a program, the computer waits for a certain action and responds to input in a certain way. Primitive Behaviors and their combinations can replace cumbersome state machines (state machines), which are often formally or informally found in programs. For example, when a program is in a state of waiting for a key to be pressed, we can say that it executes the Behavior waitForKey (...). Convenience is that Behaviors are combined in an easily readable form, unlike finite automata. A simple example of Drag & Drop:

* DragAndDrop =
    * draggedObject = ждем MouseDown на каком-то объекте
    * First
        * ждем MouseUp
        * Forever
            * ждем MouseMove
            * Двигаем draggedObject

Behavior has a beginning, an end, and can return a value. Behaviors are executed in order or can be executed in parallel using combinators. For example, the First combinator performs several Behaviors in parallel and ends when one of the Behaviors is finished, returning its result. Forever - repeats the performance of a certain Behavior to infinity. Unlike the execution of a function, Behavior does not block the main thread of execution, so endless Behaviors can be very useful.

I implemented Behaviors using functions that receive primitive events (like MouseDown, MouseUp, MouseMove, ...) as a parameter and return an object of the form:

{
    done: true|false,
    value: result value
}

You can see the implementation here: behavior.js on GitHub and the Drag & Drop example here: jsFiddle .

Where can I apply Behaviors?

  • Computer games - it is very convenient to write logic and AI, sometimes even doing everything with Behaviors, including animation and movement of objects, but you need to monitor performance
  • Tutorial in the frontend (tour of new functions) - we show information, we wait for user interaction, we continue depending on the input, all the code is in one place and is read almost like pseudo-code
  • The parser of an object-oriented language is an idiomatic code, there is no need to “look ahead” on input, since it is possible to execute several Behaviors in parallel

Photo: Behavior by Nick Youngson CC BY-SA 3.0 Alpha Stock Images

Also popular now: