我正在针对机器人构建扑克游戏,并在列表中列出了卡号。当给玩家或机器人一张卡时,我显然需要从列表中删除该卡,以免再次发卡。
def dealPlayer():
cardSuit = random.randrange(1, 5) #Decide card suit#
if cardSuit == 1:
cardNum = random.randrange(0, 13) #Decide card num#
if cardNum == 11: #Make sure it prints the name not position in list#
cardNum = "jack"
elif cardNum == 12:
cardNum = "queen"
elif cardNum == 13:
cardNum = "king"
elif cardNum == 0:
cardNum = "ace"
print ("Your first card is the", cardNum, "of clubs.")
del Clubs[cardNum] #Problem#
print(Clubs) #Debugging#
我遇到的问题在倒数第二行。这是它引起我的错误:
TypeError: list indices must be integers or slices, not str
答案 0 :(得分:0)
尝试使用以下代码作为完整代码:
def dealPlayer():
cardSuit = random.randrange(1, 5) #Decide card suit#
if cardSuit == 1:
cardNum = random.randrange(0, 13) #Decide card num#
if cardNum == 11: #Make sure it prints the name not position in list#
cardNum_ = "jack"
elif cardNum == 12:
cardNum_ = "queen"
elif cardNum == 13:
cardNum_ = "king"
elif cardNum == 0:
cardNum_ = "ace"
print ("Your first card is the", cardNum_, "of clubs.")
del Clubs[cardNum]
print(Clubs)
稍微更改变量名称使其起作用。
答案 1 :(得分:0)
每当cardNum
随机值为0、11、12或13时,您都将为cardNum
变量分配一个字符串值。
在将Clubs
变量设置为cardNum
之后访问"king"
列表时,实际上是在做以下事情:
Clubs["king"] # Invalid access (str as list index)
您只能访问整数形式的列表索引(0、1、2等),并且只能访问列表中填充的那些索引(有效索引)。
由于分配字符串值的原因是为了打印,因此您应该只使用另一个变量来存储卡名,就像这样:
def dealPlayer():
cardSuit = random.randrange(1, 5) #Decide card suit#
if cardSuit == 1:
cardNum = random.randrange(0, 14) # Decide card number [0,14), upper exclusive
if cardNum == 11:
cardName = "jack"
elif cardNum == 12:
cardName = "queen"
elif cardNum == 13:
cardName = "king"
elif cardNum == 0:
cardName = "ace"
else:
cardName = cardNum
print ("Your first card is the", cardName, "of clubs.")
Clubs.remove(cardNum)
那么您将没有任何问题,因为cardNum
保持不变并且是整数。另请注意,更改为Clubs.remove(cardNum)
。这是从列表中删除项目的正确方法。
这里的逻辑也是有缺陷的:从列表中删除“三个俱乐部”(在您的情况下,索引为3
的对象,如果0
为ace),该列表将然后缩短一张牌,列表中“三家具乐部”之后的任何一张牌都将降低一个索引。这意味着,如果您然后期望索引4
上的对象是“四家具乐部”,则实际上将是“五家具乐部”,因为所有东西都相减了一个。您需要更改设计以解决此问题。
答案 2 :(得分:0)
首先,cardNum是一个字符串。你可以做
del Clubs[int(cardNum)]
但这不会得到您想要的结果,它将从列表中删除索引cardNum。 您想要的是:
Clubs.remove(cardNum)
所以del按索引删除 list.remove()按项目删除
答案 3 :(得分:0)
问题是您在某些情况下会将cardNum转换为字符串,因此答案是停止这样做。就个人而言,我会将卡命名为单独的方法:
def cardName(cardNum):
if cardNum == 11:
return "jack"
elif cardNum == 12:
return "queen"
elif cardNum == 13:
return "king"
elif cardNum == 0:
return "ace"
return str(cardNum)
def dealPlayer():
cardSuit = random.randrange(1, 5) #Decide card suit#
if cardSuit == 1:
cardNum = random.randrange(0, 14) #Decide card num#
print ("Your first card is the", cardName(cardNum), "of clubs.")
del Clubs[cardNum]
注意:您的random.randrange(0, 13)
是错误的,它不包括13。您要么想使用random.randrange(0, 14)
,要么想使用random.randint(0, 13)
。
我认为您还应该考虑使用卡组而不是列表作为牌手和副牌,因为列表的去除是O(1)vs O(n)。
此外,您对事物的跟踪方式也不理想。如果Clubs
是一组可用的卡片,那么您实际上应该从该卡片集中选择下一张卡片。像这样:
cardNum = random.choice(Clubs)
当然,您也需要注意西服的选择。有可能没有剩余的俱乐部,在这种情况下,您需要选择其他方式。我认为,理想情况下,您应该只保留一个套牌,而不是每套西装都单独列出。您可以在这里使用元组来帮助您:
deck = set([])
for suit in ["clubs", "spades", "hearts", "diamonds"]:
for i in range(14):
deck.add((suit, i))
然后使用deck
随机选择,从random.sample(deck, 1)[0]
中删除每张卡:
>>> random.sample(deck, 1)[0]
('spades', 9)
(如果您可以在此处使用random.choice()
,但它不接受集合,那将是很好的选择