我正在尝试编写一个模拟纸牌游戏的程序。我有一个名为MagicCard的课程,以及各种扩展卡片的课程,比如card1,card2 ......我想找到一种方法来存储不同卡片的列表/数组(甲板)。每个card1,card2 ......都有一个“特殊”效果,它们在播放时会触发,因此需要一个独特的功能,这就是为什么我需要所有不同的子类。很多卡都有类似的属性。如何以合理和方便的方式存放卡座? (我希望可以轻松操作卡座,这样我就可以添加卡片,或者在需要时从卡片中取出卡片。)
目前这就是我所拥有的:
//My Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace mtgDeckSimulator
{
//General properties of a magic card, extended by individual classes
class cardProperties
{
private String cardName;
/*Mana Array Aranged in the following Order:
* [Colorless,White,Blue,Black,Red,Green] */
private int[] manaCost;
/* Card Type int definitions:
* 0-Artifact
* 1-Creature
* 2-Enchantment
* 3-Instant
* 4-Land
* 5-Planeswalker
* 6-Sorcery
* 7-Tribal */
private int cardType;
public int attack;
public int defense;
private bool permBool;
private bool isLegen; //Or is restricted to one copy
public cardProperties(String cardName,int[] manaCostIn,int cardTypeIn,int attack,int defense,bool permBoolIn,bool isLegenIn)
{
this.cardName = cardName;
manaCost = manaCostIn;
cardType = cardTypeIn;
permBool = permBoolIn;
isLegen = isLegenIn;
}
//Get Variables
public String getCardName()
{
return cardName;
}
public int[] getManaCost()
{
return manaCost;
}
public int getCardType()
{
return cardType;
}
public bool getPermBool()
{
return permBool;
}
public bool getIsLegen()
{
return isLegen;
}
//Other Methods
}
//Interface for magic cards
interface MagicCard
{
int SpecialEffect();
}
#region Magic Card List
class WallOfOmens : cardProperties, MagicCard
{
public WallOfOmens()
: base("Wall of Omens", new int[6] { 1, 1, 0, 0, 0, 0 }, 1, 0, 4, true, false)
{
;
}
public int SpecialEfect()
{
return 1;
//throw new NotImplementedException();
}
}
class Card2 : cardProperties, MagicCard
{
public int SpecialEfect()
{
return 2;
//throw new NotImplementedException();
}
}
#endregion
}
有没有更好的方法来实现这个?此外代码不起作用,因为它告诉我WallOfOmens和Card2没有实现SpecialEffect(),为什么会发生这种情况?
答案 0 :(得分:5)
我会考虑另一种方法,使用组合而不是继承。组合比继承更灵活,它允许您比继承更自由地组合不同方面。
而不是创建
abstract class BaseCard{abstract int SpecialEffect();}
class Card1 : BaseCard{override int SpecialEffect(){return 1;}}
class Card2 : BaseCard{override int SpecialEffect(){return 2;}}
...
你创建了不同的SpecialEffect-classes
abstract class SpecialEffectBase{abstract int SpecialEffect();}
class SpecialEffect1 : SpecialEffectBase{override int SpecialEffect(){return 1;}}
class SpecialEffect2 : SpecialEffectBase{override int SpecialEffect(){return 2;}}
...
并在工厂组装不同的卡
Card card1 = new Card(new SpecialEffect1());
Card card2 = new Card(new SpecialEffect2());
这可能听起来只是间接的另一个步骤,但是如果你在不同的卡片中重复使用了几个效果,并且在卡片之间有其他不同的属性,比如规则或者你可以像这样组装它们
Card card1 = new Card(new SpecialEffect1(), new Rule1());
Card card2 = new Card(new SpecialEffect1(), new Rule2());
Card card3 = new Card(new SpecialEffect2(), new Rule1());
Card card4 = new Card(new SpecialEffect2(), new Rule2());
...
另一个好处是,它会强制您将SpecialEffect规则封装在SpecialEffect类中,规则类中的规则规则等,而不是将它们放在Card类中的所有位置。
答案 1 :(得分:1)
您在实现该界面的类中有拼写错误SpecialEffect
。修复拼写错误应该有所帮助。
编译完成后,您可以将MagicCard
实例存储在任何(最好是通用的)容器中。
扩展MagicCard
接口以使其具有将对象返回为cardProperties
的属性可能会有所帮助,以便于访问。双重继承使得访问容器元素的基类和接口变得更加棘手,因为您只能在通用容器中存储一个Type。任何MagicCard
都有cardProperties
。
答案 2 :(得分:0)
使用List类。其中T是cardProperties或MagicCard 另外,为什么不删除接口MagicCard并添加int SpecialEffect();而不是使用接口。作为cardProperties的抽象方法:
public abstract int SpecialEffect();
抽象方法必须由子类实现,然后你必须将cardProperties标记为抽象
答案 3 :(得分:0)
或许查找Polymorphism。
理想情况下,您应该存储List<Card>
。所有不同的卡都继承自基类Card
,有些卡实现了一个名为IMagicCard
的接口。
或者,如果只有一种类型的MagicCard
,则可以直接从Card
继承
所以,你可以:
Card
WizardCard : Card, IMagicCard
WitchCard : Card, IMagicCard
HumanCard : Card
或
Card
MagicCard : Card
NonMagic: Card
我会推荐前者,但根据你的游戏结构,两者都可能适用。
如果我误解了你的意图,你将不得不原谅我。
答案 4 :(得分:0)
我个人原本会将MagicCard
作为父类,而不是作为接口。在其中,您可以将SpecialEffect
声明为虚拟以允许覆盖,即使它不是必需的。然后,在您的deck类中,您可以使用List<MagicCard>
对象,就像andrewjs建议的那样。