合并状态,FSM

时间:2010-03-19 01:56:09

标签: fsm

组合FSM的状态是否“正确”?

假设你有一个

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

恰好,组合状态是有意义的,如

State myState = State1 | State2 ;
然而,在FSM理论中这是非法的吗?

这是一条捷径:

假设你有3种状态:跑步,走路和跳跃。然后你有第四个状态射击。

你需要能够跑步和射击,步行和射击,以及跳跃和射击。而不是制作6种状态RunningFiring,WalkingFiring,JumpingFiring,我想组合射击状态(无论走路跑步跳跃状态)

我知道我可以使用BOOL作为“第四状态”,但这看起来不是甚至是wronger吗?有一个“状态......”

3 个答案:

答案 0 :(得分:1)

在我看来,当你开始需要组合这样的状态时,你的状态机开始做太多了。您可能需要考虑将一些功能/逻辑移动到一个单独的状态机,该状态机专注于在“父”状态机处于另一个状态时可能会或可能不会改变状态的一个任务。

答案 1 :(得分:1)

我记得在13岁左右的时候读过一本关于游戏编程的书,看到一个用于建模属性的位掩码的例子。像

这样的东西
const int HAS_WEAPON =    0x1;
const int WEARING_ARMOR = 0x2;
const int IS_ALIENT     = 0x4;

等等。然后你可以将NPC的属性表示为int,并且可以使用属性作为掩码来设置/清除各个位。

现在,当然,当内存变得更便宜时,bitpacking就不常见了,因此我们可以使用布尔值来表示属性。无论如何,这似乎与您想要做的类似。

但是,属性与状态机中的状态不同。在状态机中,处于一种状态意味着您不一定处于任何其他状态。因此,如果你有一堆不相互排斥的东西,状态机可能不是你要走的路。请考虑您添加的每个二进制值属性将使整个机器的大小加倍。

当你说

  

我知道我可以使用BOOL来实现   “第四国”,但似乎没有   甚至是wronger?拥有“状态”   侧..“

它向我表示,您正在考虑您所代表的信息的方式可能存在问题。当然,“射击”听起来像一个状态的好候选人,如果你总是要么开火或做其他事情,那么它就像一个状态机。但是,如果“Firing”可以与现有系统中的所有状态结合使用,那么将它作为属性进行建模会不会有任何损害?

答案 2 :(得分:1)

在我看来,这是状态的AND分解(以及正常的异或分解)的一个例子。 UML使用正交区域模拟这种情况。因此,在这种情况下,您有两个正交区域。第一个包含正常的OR状态Running,Walking和Jumping。另一个正交区域包含状态点火。此状态机允许以下组合:运行|射击,步行|射击和跳跃|射击。

您可以使用两个状态机来近似这两个正交区域(您需要两个状态变量)。目前,Firing的状态机只有一个状态,但我相信你最终会得到补充状态“not-Firing”,所以它将成为一个合适的状态机。

Miro Samek,state-machine.com