检查字符串的某个字符是否为数字
我正在用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)
第二个总值只有在玩家抽到一张王牌时才会用到,因为王牌的值可以是1或11,所以会有两个可能的总值。
但是现在这段代码总是返回20。我知道我的if语句写得不太好,所以我不惊讶这可能是问题所在。我能看出来,因为返回的总是20,代码认为我手里总是有两张人头牌。有没有更好的方法来判断牌的数字?
请记住,我不想检查字符串是否是数字,因为字符串里还有其他东西。我只想看前面一两个数字。
1 个回答
把我所有的评论建议整理成一个回答:
你现在遇到的问题是因为你在看 card[1]
,也就是字符串的 第二个 字符。记住,在 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)
。不过我觉得这可能不是你想要的,因为一手黑杰克只有一个值。如果你想返回两个中的较小值,你应该用 return str(min(total1, total2))
。
还有,你的 calcTotal
仍然无法处理比如三个 A 的情况。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 风格指南)