检查字符串的某个字符是否为数字

0 投票
1 回答
49 浏览
提问于 2025-04-14 18:17

我正在用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 个回答

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 构造函数希望第二个参数(如果有的话)是一个编码。如果你想返回一个包含 total1total2 的元组作为字符串,你需要用 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 风格指南

撰写回答