我正在尝试创建一个程序来随机处理两张牌。但是,它总是出现错误:
AttributeError: type object `CardPack` has no attribute `suits`
我不确定,但我认为这意味着类CardPack
没有值suits
。但是,在__init__
函数中,它是被定义的。我完全被难住了。在
类别代码:
^{pr2}$运行的文件创建实例:
#DEALING TEST
from DeckDealer import CardPack
Dealer = CardPack
cards = Dealer.deal(CardPack)
print("Your cards are %s and %s!" % (cards[1], cards[2]))
您没有在此处创建实例:
这只是对类的另一个引用(a类型),因此
__init__
方法也不会被调用。在调用类以生成实例:
^{pr2}$此行不创建
CardPack
类型的实例,它只是复制对它的引用。因此,当您调用Dealer.deal()
时,实际上是在执行CardPack.deal()
,它无权访问实例属性。在相反,您应该创建一个实例,然后对该实例调用方法:
^{pr2}$在这种情况下,还需要注意的是,要调用一个方法,不是为
self
传递一个值。当您在实例上调用方法时,self
是隐式设置的。因此,当您执行dealer.deal()
操作时,self
会自动设置为dealer实例。如果您要调用dealer.deal(dealer)
,您将传递一个该方法没有的第二个参数,因此您将得到一个错误。这也是您在deal
中的getRandomCards
调用的问题:self.getRandomCards(self)
将self
设置为第二个参数,给您一个错误。做self.getRandomCards()
就是你想做的。在尽管如此,请注意您的
deal
方法将有一个无限循环,因为只要cards
不是3就继续迭代,但是您永远不会更改cards
的值。所以您可能想增加循环中的值。但即使这样,访问空列表上的cardsDealt[cards]
也会导致索引错误,所以您也需要修复它。您可以先重置列表,然后再向其添加append
张新卡片,但更好的方法是一次只创建一个新列表,其中包含3张卡片。您可以使用列表理解来简化:最后,您的
getRandomCards
可能并没有完全按照您的预期操作。通常,你会期望每张牌都有相同的机会。然而,你要做到的是俱乐部卡有1/4的几率,黑桃卡有3/16的几率,红桃卡有9/64的几率,钻石卡有27/256的几率。这样就有81/256的几率获得无牌。这显然是不对的。在发生这种情况的原因是你对每个测试都做了随机选择。所以为了测试你是否得到俱乐部卡,你要做一个选择(1/4的机会)。如果你没有得到一张黑桃牌(3/4的机会),你会做出另一个选择来获得黑桃牌(1/4的机会;所以总共是3/4*1/4)等等。相反,你应该只做一次选择,然后将结果重新用于子类别:
这也使得你不可能不从这个方法中随机得到一张牌,因为你总是得到四套西装中的一套。在
最后2点,正如gboffi在评论中提到的,你没有任何保护措施来阻止你得到多张相同的卡。从
getRandomCards()
得到三张同一张牌是可能的(不太可能,但仍然有可能),这在大多数游戏中是不可能的。在为了防止这种情况,您可以在所有卡片的列表中使用^{} 。这将给你三张(或任何数字)绝对不同的卡片。它还允许你有一个真正的“牌堆”,你从中抽牌,然后离开牌堆,直到你重新开始游戏。在
通过设置,您可以制作如下新牌组:
这实际上只是将所有四个卡片列表组合在一起,创建一个新的卡片列表,然后可以从中提取。要从它们中提取三个,可以使用
random.sample
,如下所示:然后你可以从牌堆中取出这些牌:
另一种方法是更接近真实的方式。你可以先洗牌,然后从最上面抽牌,而不是从牌堆中随机抽牌。要洗牌列表,可以使用^{} ,要从列表中提取和移除卡片,可以使用
list.pop
:相关问题 更多 >
编程相关推荐