2011-09-09 160 views
3

在我的班級之一,我有一個存儲像這樣一組枚舉標誌的整數C++檢查枚舉標誌

enum AttackFlags 
{ 
    Contact = 1,      //Move connects with target 
    Projectile = 2,       //Attack is projectile based 
    Unblockable = 4,      //Attack can not be blocked 
    UncounterableLv1 = 8,     //Attack can't be countered except by extreme counter attack skills/status effects 
    UncounterableLv2 = 16,     //Attack can not be countered 
    Flinches = 32,       //Has a chance to stun the enemy, pushing back their next turn 
    Unreflectable = 64,      //Attack penetrates reflect. Only checked for Magic attacks 
    IgnoreDefenderStatusEffects = 128,  //Ignores active status effects on the defender 
    IgnoreAttackerStatusEffects = 256,  //Ignores active status effects on the attacker 
    IgnoreDefenderAbilities = 512,   //Ignore the defenders abilities 
    IgnoreAttackerAbilities = 1024,   //Ignore the attackers abilities 
    IgnoreArmorRating = 2048,    //Ignore the defensive boosts of armor 
    IgnoreWeaponRating = 4096,    //Ignore the attack boost from weapons 
    HighCritical = 8192,     //The move has an increased chance to crit 
    CausesStatus = 16384,     //Can the move cause status effects? 
    Elemental = 32768,      //Is the move elemental based? 
    Unimplemented = 65536,     //has the move been implemented yet? 
    ModsTimer = 131072,      //Does it have an effect on the target or users timer? 
    Heals = 262144,       //Does the move heal? 
    SecondaryEffects = 524288,    //Attack has additional effects besides basic attack 
    PhysicalAttackFlag = 1048576,   //Is the Class Physically based? I.E. blocked by Protect and Shield 
    MagicAttackFlag = 2097152,    //Is the move Magically Based? I.E. is it affected by things like Shell 
    MultiHit = 4194304,      //Does it enxcapsulate more then 1 hit 
    SingleUse = 8388608,     //Attack can only be used once per battle 
    DoesNotCauseDamage = 16777216 
}; 

class Attack 
{ 
    int AtkFlags; //Stores AttackFlags |'d together 

} 

我想一個方法添加到我的攻擊類具有以下簽名

bool HasAttackFlags(int flags); 

標誌會有很多AttackFlags |'d在一起。如果我只想檢查一個單一的標誌,我可以只將& AtkFlags和標誌放在一起,但是因爲我必須檢查多個可能的標誌,所以這不起作用。我怎樣才能正確地檢查多個標誌?我想,以避免傳遞載體/組標誌覈對簡單地|「荷蘭國際集團一組標誌在一起是那麼簡單,構建載體/提前

編輯設置

感謝:

爲了澄清我的意思,我可能有以下

Attack atk; 
atk.AtkFlags = Contact | Projectile | Heals | MagicAttackFlag; 

後來的後來,我要檢查的旗幟上ATK像這樣:

bool res = atk.HasAttackFlags(Contact | Projectile); 

資源應該是真實的,相反

bool res = atk.HasAttackFlags(Contact | Unreflectable); 

應該是假的becase的AtkFlags不包含這兩個聯繫ADN Unreflectable。

回答

8

我不知道我在跟蹤你的問題,因爲你似乎提到了明顯的解決方案。那麼,什麼是錯這個作爲一個解決方案,顯然是添加你所希望的任何其他標誌:

bool HasAttackFlags(int flags) { 
    return (flags&(contact|projectile))!=0; 
} 

編輯:哦......我想我只是想通了,你要檢查的2存在或更多的標誌作爲一組?在這種情況下,你可以簡單地修改方法:

bool HasAttackFlags(int flags) { 
    return (flags&(contact|projectile))==(contact|projectile); 
} 
+4

如果任何標誌的啓用第一個示例代碼返回true,第二個返回true,如果所有的標誌都啓用。只是爲了澄清。 –

2

舉個例子,你可以這樣做:

int v = Unblockable | UncounterableLv1| UncounterableLv; 
if ((flags & v) == v) 
{ 
    //flags has all three: Unblockable, UncounterableLv1 and UncounterableLv 
} 
else if ((flags & v) == (Unblockable | UncounterableLv1)) 
{ 
    //flags has Unblockable and UncounterableLv1 
} 
else if ((flags & v) == Unblockable) 
{ 
    //flags has Unblockable only 
} 
//and so on 
4

這是我的建議:

注意枚舉定義的使用使機器

enum AttackFlags 
{ 
    Contact      = 1ul << 0, // Move connects with target 
    Projectile     = 1ul << 1, // Attack is projectile based 
    Unblockable     = 1ul << 2, // Attack can not be blocked 
    UncounterableLv1   = 1ul << 3, // Attack can't be countered except by extreme counter attack skills/status effects 
    UncounterableLv2   = 1ul << 4, // Attack can not be countered 
    Flinches     = 1ul << 5, // Has a chance to stun the enemy, pushing back their next turn 
    Unreflectable    = 1ul << 6, // Attack penetrates reflect. Only checked for Magic attacks 
    IgnoreDefenderStatusEffects = 1ul << 7, // Ignores active status effects on the defender 
    IgnoreAttackerStatusEffects = 1ul << 8, // Ignores active status effects on the attacker 
    IgnoreDefenderAbilities  = 1ul << 9, // Ignore the defenders abilities 
    IgnoreAttackerAbilities  = 1ul << 10, // Ignore the attackers abilities 
    IgnoreArmorRating   = 1ul << 11, // Ignore the defensive boosts of armor 
    IgnoreWeaponRating   = 1ul << 12, // Ignore the attack boost from weapons 
    HighCritical    = 1ul << 13, // The move has an increased chance to crit 
    CausesStatus    = 1ul << 14, // Can the move cause status effects? 
    Elemental     = 1ul << 15, // Is the move elemental based? 
    Unimplemented    = 1ul << 16, // has the move been implemented yet? 
    ModsTimer     = 1ul << 17, // Does it have an effect on the target or users timer? 
    Heals      = 1ul << 18, // Does the move heal? 
    SecondaryEffects   = 1ul << 19, // Attack has additional effects besides basic attack 
    PhysicalAttackFlag   = 1ul << 20, // Is the Class Physically based? I.E. blocked by Protect and Shield 
    MagicAttackFlag    = 1ul << 21, // Is the move Magically Based? I.E. is it affected by things like Shell 
    MultiHit     = 1ul << 22, // Does it enxcapsulate more then 1 hit 
    SingleUse     = 1ul << 23, // Attack can only be used once per battle 
    DoesNotCauseDamage   = 1ul << 24, 

    MaskAttack  = MagicAttackFlag | PhysicalAttackFlag, 
    MaskIgnore  = IgnoreWeaponRating | IgnoreArmorRating | IgnoreAttackerAbilities | IgnoreDefenderAbilities | IgnoreAttackerStatusEffects, 
    // etc 
}; 

static bool HasAttackFlag(AttackFlags flags) 
{ 
    return flags & MaskAttack; 
} 

static bool HasIgnoreFlag(AttackFlags flags) 
{ 
    return flags & MaskIgnore; 
} 

作爲一個額外的好處,考慮一種方式只返回'miscellanous'(un-m問:這麼說)標誌:

static AttackFlags MiscFlags(AttackFlags flags) 
{ 
    return (AttackFlags) (flags & ~(MaskAttack | MaskIgnore)); 
} 
+0

我從來沒有見過這種初始化枚舉的方式,我總是看到'= 1 << 0'' = 1 << 1'' = 1 << 2'等等,所以如果你犯了一個錯誤是很明顯的。 –

+0

@運動:不同的目標。我想我平均喜歡那種方法。那麼,在這麼大的枚舉中可能會更好。我會接受這個建議! – sehe

+0

我喜歡面具..非常有效 –