开发者

Combined states, FSM

开发者 https://www.devze.com 2022-12-23 23:44 出处:网络
Is it \"correct\" to combine states of an FSM? Say you have an object with enum State { State1 = 1 << 0,

Is it "correct" to combine states of an FSM?

Say you have an object with

enum State
{
    State1 = 1 << 0,
    State2 = 1 << 1,
    State3 = 1 << 2
} ;

It just so happens that it makes sense to combine states, as in

State myState = State1 | State2 ;

however in FSM theory is this illegal?

It's more a shortcut:

Say you have 3 states: Running, Walking, and Jumping. Then you have a fourth state Firing.

You need to be able to Run and Fire, Wal开发者_运维知识库k and Fire, and Jump and Fire. instead of making 6 states RunningFiring, WalkingFiring, JumpingFiring, I'd like to combine the Firing state with (whatever Walking Running Jumping state)

I know I could just use a BOOL for the "fourth state", but doesn't that seem even wronger? Having a "state on the side..."


I remember reading a book on game programming back when I was 13 or so and seeing an example of a bitmask being used to model attributes. Something like

const int HAS_WEAPON =    0x1;
const int WEARING_ARMOR = 0x2;
const int IS_ALIENT     = 0x4;

and so on. Then you could represent an NPC's attributes as an int, and you could set / clear individual bits using the attributes as masks.

Now, of course, bitpacking is much less common as memory has become cheaper, and as such we can just use boolean values to represent attributes. Regardless, this seems similar to what you want to do.

Attributes, however, aren't the same as states in a state machine. In a state machine, being in one state means that you are necessarily not in any other state. So if you have a bag of things that are not mutually exclusive, a state machine is probably not the way to go. Consider that each binary-valued attribute you add will double the size of your entire machine.

When you say

I know I could just use a BOOL for the "fourth state", but doesn't that seem even wronger? Having a "state on the side.."

it signifies to me that there might be a problem with the way you're thinking about the information that you're representing. Sure, "Firing" sounds like a good candidate for a state, and if you're always either firing or doing something else then it works as a state machine. But if "Firing" can be combined with all of the states in the existing system, would it really do any harm to model it as an attribute instead?


In my opinion, when you start to need to combine states like this, then your state machine is starting to do too much. You may need to consider moving some functionality/logic into a separate state machine that is focused on the one tasks that may or may not change state while the "parent" state machine is in another state.


It seems to me that this is an example of the AND-decomposition of states (as well as the normal exclusive-OR decomposition). UML models this situation with orthogonal regions. So, in this case you have two orthogonal regions. The first one contains normal OR-states Running, Walking, and Jumping. The other orthogonal region contains state Firing. This state machine allows the following combinations: Running|Firing, Walking|Firing, and Jumping|Firing.

You can approximate such two orthogonal regions with two state machines (you need two state variables). For now, the state machine for Firing has only one state, but I'm sure you will end up with complementary state "not-Firing", so it will be a proper state machine.

Miro Samek, state-machine.com

0

精彩评论

暂无评论...
验证码 换一张
取 消