编辑:由于attack.condition偶尔会有多个值,所以switch语句将不起作用!

所以我有这个会增长的枚举:

enum Condition {    Null            =   0x0001,
            SelfIsUnderground   =   0x0002,
            SelfIsGround        =   0x0004,
            SelfIsAir       =   0x0008,
            SelfIsWater     =   0x0010,
            OtherIsUnderground  =   0x0020,
            OtherIsGround       =   0x0040,
            OtherIsAir      =   0x0080,
            OtherIsWater        =   0x0100,
            Tile            =   0x0200,
            CONDITION_COUNTX    =   0x03FF};

这个功能也将不断增长:
bool Attack::CanBeDone(Spirit* pSelf, Spirit* pTarget,Map* pMap)
{
    if(this->condition!=Null)
    {
        if(this->condition & SelfIsUnderground)
            if(pSelf->GetcurrentLayer()!=Underground)
                return false;

        if(this->condition & SelfIsGround)
            if(pSelf->GetcurrentLayer()!=Ground)
                return false;

        if(this->condition & SelfIsAir)
            if(pSelf->GetcurrentLayer()!=Air)
                return false;

        if(this->condition & SelfIsWater)
            if(pSelf->GetcurrentLayer()!=Water)
                return false;

        if(this->condition & OtherIsUnderground)
            if(pTarget->GetcurrentLayer()!=Underground)
                return false;

        if(this->condition & OtherIsGround)
            if(pTarget->GetcurrentLayer()!=Ground)
                return false;

        ...

有没有替代另一遍写的方法:
    if(this->condition & arg)
        if(pSelf->GetcurrentLayer()!=value)
            return false;



奖励:如果我给Condition::Null值0x0000,SelfIsUnderground 0x0001,SelfIsGround 0x0002并再次使用2的幂,它将起作用吗?最终,Tile的值将为0x0100。

最佳答案

首先,我会写这样的东西:

enum Condition {    Null            =   0x0001,
            SelfBase        =   0x0002,
            SelfIsUnderground   =   SelfBase * (1 << Underground),
            SelfIsGround        =   SelfBase * (1 << Ground),
            SelfIsAir       =   SelfBase * (1 << Air),
            SelfIsWater     =   SelfBase * (1 << Water),
            SelfMask        =   SelfBase * ((1 << Max) - 1),
            OtherBase       =   0x0020,
            OtherIsUnderground  =   OtherBase * (1 << Underground),
            OtherIsGround       =   OtherBase * (1 << Ground),
            OtherIsAir      =   OtherBase * (1 << Air),
            OtherIsWater        =   OtherBase * (1 << Water),
            OtherMask       =   OtherBase * ((1 << Max) - 1),
            Tile            =   0x0200,
            CONDITION_COUNTX    =   0x03FF};

(假设Underground == 0Max == Water + 1)。然后,长列表简化为两个非常清晰的表达式:
if ( (SelfMask & this->condition & (SelfBase * (1 << pSelf->GetcurrentLayer()))) )
    return false;

if ( (OtherMask & this->condition & (OtherBase * (1 << pTarget->GetcurrentLayer()))) )
    return false;

return true;

当您扩展枚举时,这仍然是正确的。但是请注意,仍然存在一些冗余(例如,如何定义OtherBaseTile),也可以减少冗余。静态断言可以帮助确保Condition枚举定义正确。

关于c++ - 除了 “if argA == argB do …”这么长的 list ,还有其他选择吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15777404/

10-11 01:03