纸牌游戏,卡片的体系结构

时间:2013-12-11 16:39:59

标签: c# polymorphism playing-cards

我仍在从Python背景中学习C#的细节。

考虑到这一点,让我们说我正在制作游戏。为了简单起见,让我们以Magic:the Gathering或任何其他流行的收藏卡片游戏为基础。在这样的游戏中,有多张牌可以玩。这些卡片会有不同的类型和效果。例如,可以有一张生物牌,并且可能有一张咒语牌。

这些类型的卡具有不同的属性。例如,生物具有attack属性和health属性,而咒语可能具有effect属性。但是,这些不同的类型仍然是卡片,并且有多个共同点,例如cost属性。这些不同的卡可能由Manager类管理。来自此类游戏的基本代码示例可能如下所示:

public class Manager
{
    public CreatureCard card1 = new CreatureCard();
    public SpellCard card2 = new SpellCard();
}

public class Card
{
    public int cost;
}

public class CreatureCard : Card
{
    public int attack;
    public int health;
}

public class SpellCard : Card
{
    public SpellEffect effect;
}

我基本上想要做的是创建卡片并将它们存储在经理课程中,而不知道他们是否提前成为咒语或生物。经理类可能看起来像这样:

public class Manager
{
    public Card card1;
    public Card card2;
}

这些卡片将从其他地方分配。

现在,这并没有真正奏效。例如,无法访问卡片的health属性。这很合乎逻辑,因为该卡甚至可能 具有health属性。 这就是为什么我正在寻找工作的方法,同时保持结构大致相同。所以会有一个Card类,其中包含很多内容,以及从中派生的其他类(CreatureCardSpellCard)。

有没有办法让这项工作?我来自Python,所以这种方法在C#中实际上可能完全错误。如果是这样,请告诉我我可以使用哪种方法,而不是我现在试图开始工作的方法。

1 个答案:

答案 0 :(得分:4)

您可以通过适当地转换Card实例来实现:

public class Manager
{
    public Card card1;
    public Card card2;
}

...
var manager = new Manager 
{
    card1 = new CreatureCard();
    card2 = new SpellCard();
}
if (manager.card1 is CreatureCard)
{
    var health = ((CreatureCard)manager.card1).Health;
    Console.WriteLine(health);
}
if (manager.card2 is SpellCard)
{
    var effect = ((SpellCard)manager.card2).effect;
    Console.WriteLine(effect);
}

或者像这样:

var creatureCard = manager.card1 as CreatureCard;
var spellCard = manager.card2 as SpellCard;
if (creatureCard != null)
{
    Console.WriteLine(creatureCard.health);
}
if (spellCard != null)
{
    Console.WriteLine(spellCard.effect);
}

要扩展此:

  • 要测试卡是否属于指定类型,请使用is operator

    bool isCardType = myCard is CardType;
    
  • 将卡片(CardType) cast / convert用于指定类型:

    CardType specificCardType = (CardType)myCard;
    
  • 要将卡安全地转换为特定类型,或者如果不属于该类型,请返回null,请使用as operator

    CardType specificCardType = myCard as CardType;
    if (specificCardType != null) {
        ...
    }