我正在尝试使用 python 创建二十一点。我有创建一副纸牌的代码:
import random
values = ['2','3','4','5','6','7','8','9','10','Jack','Queen','King','Ace']
suites = ['Hearts', 'Clubs', 'Diamonds', 'Spades']
deck = []
outOfDeck = []
for s in suites:
for v in values:
deck.append(v + ' of ' + s)
random.shuffle(deck)
我正在尝试编写代码来计算您的卡的总价值。现在,我已经做了:
def calcTotal():
total1 = 0
total2 = 0
for card in playerCards:
if card[1] == '2' or card[1] == '3' or card[1] == '4' or card[1] == '5' or card[1] == '6' or card[1] == '7' or card[1] == '8' or card[1] == '9':
total1 += int(card[:2])
total2 += int(card[:2])
else:
if card[1] != 'a':
total1 += 10
total2 += 10
else:
total1 += 1
total2 += 11
if total1 == total2:
return total1
else:
return str(total1, total2)
仅当玩家获得 A 时才使用第二个总数,其中可能有两个总数,因为它可能等于 1 或 11。
但是,这只总是返回 20。我知道 if 语句很草率,所以如果这就是问题所在,我不会感到惊讶。我可以看出,由于返回值始终为 20,因此代码认为我始终有两张人头牌。有没有更好的方法来查看卡片是否为数字?
请记住,我不想检查字符串是否是数字,因为字符串中还有其他内容。仅前一位或前两位数字。
编译我所有的评论建议作为答案:
您当前看到的问题是由您查看
card[1]
引起的,它是字符串的 second 字符。请记住,在 python 中,索引从 0
开始,因此您需要查看 card[0]
。
另请记住,字符串比较区分大小写,因此
'a'
不等于 'A'
。您需要检查 A 检查中的第一个字符是否为 'A'
。
您可以将您的情况简化为:
if card[0] == 'A':
# do ace logic
if card[0] in ('K', 'Q', 'J', '1'):
total += 10
else:
total += int(card[0])
您很快就会看到另一个问题 -
str(total1, total2)
当您遇到它时会抛出错误。 str
构造函数期望第二个参数(如果有)是编码。如果您尝试返回包含 total1
和 total2
作为字符串的元组,则需要 return str(total1), str(total2)
。
此外,您的
calcTotal
仍然无法处理例如以下情况:三个王牌。带有 A♣, A♦, A♥
的牌的价值是 13,而不是 3 或 33。逻辑应该是:“我可以在不破产的情况下加 11 吗?是 - 加 11;否 - 加 1”。这样你只需要一个总变量。这种方法的一个警告是,在合计所有其他牌后,您需要保存 A 以进行处理。
最后,请记住,全局变量会使代码更难以阅读和调试。将函数所需的变量作为参数传递给函数非常容易。
结合所有这些建议,这就是我的做法:
def calc_total(player_cards):
total = 0
num_aces = 0
for card in player_cards:
if card[0] == 'A':
num_aces += 1 # Keep track of number of aces to process later
elif card[0] in ('K', 'Q', 'J', '1'):
total += 10
else:
total += int(card[0])
# Now process the aces
# Try to use a decreasing number of aces as 11
# If you bust, try with one fewer 11-ace
# If you don't, that's the score!
eleven_point_aces = num_aces
while eleven_point_aces >= 0:
new_score = total + 11 * eleven_point_aces + (num_aces - eleven_point_aces)
if new_score < 22:
return new_score
else:
eleven_point_aces -= 1
# Will bust even with all aces given one point, so just go ahead and do that
return total + num_aces
(请注意,我更改了函数和变量名称以符合PEP8,Python 风格指南)