我目前拥有的是构建一副牌、洗牌以及从该牌组构建一手牌的代码。
from random import randint
def make_deck():
deck = []
for suit in suits:
for rank in ranks:
deck.append((suit,rank))
return deck
suits = ['spades','hearts','diamonds','clubs']
ranks = ['ace','two','three','four','five','six','seven','eight','nine','ten','jack','queen','king']
deck = make_deck() #list of cards
def shuffle(deck):
for k in range(100): # do it 100 times
card = deck.pop(randint(0,51))
deck.append(card)
def make_hand():
hand = []
for k in range(2):
card = deck.pop(randint(0,51))
hand.append(card)
return hand
hand = make_hand()
当我运行程序时,打印
deck
会给我我喜欢的卡片列表,然后当我尝试洗牌时,我收到一条错误消息,指出弹出索引超出范围。不太清楚为什么它会超出索引,因为范围 (0,51) 代表这副牌的所有 52 张牌。
当我尝试使用
make_hand()
函数时,会出现相同的错误,但并非总是如此。我是否错误地使用了 pop
方法?我必须更改什么才能使 shuffle
功能正常工作并且 hand
始终从牌组中返回两张不同的牌?
pop
通过从列表中删除项目来改变列表。因此,列表的长度将变得小于 52
并且最终会抛出错误。每次都使用列表的长度,而不是 51
。对于洗牌,您还可以使用库中的函数 len(deck)
shuffle
:random
from random import shuffle
## later in the code
shuffle(deck)
尽管如果将该值保存在某处,速度会更快。
但这也说明了一个问题,那就是你的套牌有问题。套牌创建中的 for 循环格式是否正确?您创建的卡片可能少于 52 张,因此当您生成高端整数时,您会捕获该错误。如果它偶尔发生在 make_hand 中(迭代两次)并且经常发生在 shuffle 中(迭代 100 次),那么这似乎也是可能的。
如果您的目的是在发牌后洗牌,那么您肯定需要使用 len() 或以其他方式跟踪牌组的大小。即使在 make_hand 函数中,您也会弹出一张卡,然后仍然尝试从大小为 52 的列表中绘制,即使您已经取出了一张卡。
card = deck.pop(randint(0,len(deck)-1))
中,您从牌堆中取出2张牌。第一个总是会成功,但第二个必须使用仅包含 51 张牌的牌组,而仍然有 52 分之一的机会尝试
make_hand
,这会失败。我无法使用
pop(52)
函数重现相同的错误,除非我先向它传递一个已在
shuffle
中使用过的牌组,所以我假设这也是您所做的。为了确定,您可以在这两个函数中使用
make_hand
。