Python - 求和 'Aces' 以提供小于 21 的最大总和

Python - Summing 'Aces' to provide the greatest sum less than 21

所以我在 python 中编写二十一点脚本,但遇到了手中 A 的问题(有些手可能有 1 个 A、2 个 A 或击中后、3 个 A 或最多 4 个),问题是找到小于或等于 21 的最大总和。这听起来很容易,但是 当每个 ace 的值可以是 1 或 11,无法重新计算并且 ace 的数量会变化时,就会出现复杂情况,例子

aces = [[1, 11], [1, 11]] #could be aces = [[1,11]] or etc. where one ace is [1, 11]

所以我目前使用的方法对我不起作用,因为 for 循环的数量已经固定了一定数量的 ace...(在本例中为两个)

possiblehand = []
for ace1 in aces:
    aces.remove(ace1) #To not re-count this current ace
    for ace2 in aces:
        handtotal = currenthandsum + ace1 + ace2 #two for-loops fixes two aces, but the amount of aces is varying. The error of adding lists exists also, but was not able get rid of this yet still add up all the combinations.
        if handtotal <= 21:
            possiblehand.append(handtotal)

hand = 0
for possible in possiblehand:
    if possible > hand:
        hand = possible  #just getting the greatest value in this list 

这已固定为手中正好有两个 A,并且存在我实际上添加两个列表的错误,但我想对 [1, 11] 的所有组合求和以获得有多少个 A . (例如,对于 20:11、1、1、7,其中 7 不是 A)

那么我该如何解决这个问题呢?

你可以用一个二进制数来表示所有可能的手。

假设我们手里有 3 张 A,所以有 23 = 8 种可能的手牌。我们可以用整数0~7来表示所有8种可能的手牌。

假设我们想知道用整数 5(即二进制形式的 101)表示的可能手牌的值。我们检查二进制整数的所有位,如果第i位是1,我们考虑选择第​​i个ace作为11,否则我们考虑选择第​​i个ace作为1。那么可能手的值#5(或二进制形式的 101)是 11 + 1 + 11 + current_hand_value.

ace_num = 3         # Or whatever number you like
current_hand = 7    # Or whatever number you like
ans = 0

# Enumerate all the possible hands
# Represent each possible hand by a binary number
for i in range(0, 1 << ace_num):
    sum = current_hand

    for j in range(0, ace_num):
        # Decide to pick 1 or 11 according to the j-th bit of the binary number
        if ((j >> i) & 1) == 1:
            sum += 11
        else:
            sum += 1

    if sum > ans and sum <= 21:
        ans = sum

print(ans)

编辑

这个问题其实还有另一种解决方法,我觉得更好。由于我们最多只能让手中的一张A为11(否则总和至少为22,超过21),我们只需要检查两种可能:所有A都为1,并且只有一张为11 .

ace_num = 3         # Or whatever number you like
current_hand = 7    # Or whatever number you like
ans = 0

# All the aces are 1
hand = ace_num + current_hand
if hand <= 21 and hand > ans:
    ans = hand

# Only one ace is 11
if ace_num > 0:
    hand = ace_num-1 + 11 + current_hand
    if hand <= 21 and hand > ans:
        ans = hand

print(ans)