2

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

假设你有一个对象

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

碰巧组合状态是有意义的,例如

State myState = State1 | State2 ;

但是在 FSM 理论中这是非法的吗?

这更像是一条捷径:

假设您有 3 个状态:跑步、步行和跳跃。然后你有第四个状态 Firing。

你需要能够跑和火,走路和火,跳和火。而不是制作6个状态RunningFiring,WalkingFiring,JumpingFiring,我想Firing状态与(无论Walking Running Jumping状态)结合起来

我知道我可以将 BOOL 用于“第四状态”,但这似乎不是更错误的吗?有一个“侧面的状态......”

4

3 回答 3

1

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

于 2010-03-19T01:58:38.350 回答
1

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

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

Miro Samek,state-machine.com

于 2010-03-31T01:10:11.617 回答
1

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

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

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

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

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

当你说

我知道我可以将 BOOL 用于“第四状态”,但这似乎不是更错误的吗?有一个“侧面的状态..”

对我来说,这意味着您对所代表信息的思考方式可能存在问题。当然,“Firing”听起来像是一个很好的状态候选,如果你总是在开火或做其他事情,那么它就像一个状态机。但是,如果“Firing”可以与现有系统中的所有状态相结合,那么将其建模为一个属性真的会有什么坏处吗?

于 2010-03-19T02:33:22.247 回答