Python - суммирование "тузов", чтобы получить наибольшую сумму менее 21
Итак, я писал сценарий для блэкджека в python, но столкнулся с проблемой тузов в руках (в некоторых руках может быть 1 туз, 2 туза или после удара, 3 туза или макс 4), проблема в том, чтобы найти наибольшую сумму меньше или равно 21. Это звучит легко, но тогда возникает сложность, когда каждый туз может иметь значение 1 или 11, не может быть пересчитан и количество тузов меняется, например
aces = [[1, 11], [1, 11]] #could be aces = [[1,11]] or etc. where one ace is [1, 11]
так что то, что у меня сейчас не получалось, так как количество циклов for уже фиксировало количество тузов... (в данном случае два)
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
Это было исправлено для того, чтобы в руке было ровно два туза, и существовала ошибка, что я фактически добавлял два списка, но я хочу суммировать все комбинации [1, 11] для того, сколько тузов существует. (например, для 20: 11, 1, 1, 7, где 7 не туз)
Итак, что я мог решить эту проблему?
1 ответ
Вы можете использовать двоичное число, чтобы выразить все возможные руки.
Предположим, у нас в руке 3 туза, поэтому есть 23 = 8 возможных рук. Мы можем представить все 8 возможных рук целыми числами от 0 до 7.
Допустим, мы хотим узнать значение возможной руки, представленной целым числом 5(то есть 101 в двоичной форме). Мы проверяем все биты двоичного целого числа, и если i-й бит равен 1, мы рассматриваем выбор i-го туза как 11, в противном случае мы рассматриваем выбор i-го туза как 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)
РЕДАКТИРОВАТЬ
На самом деле есть другое решение этой проблемы, которое я считаю лучше. Так как мы можем позволить не более одного туза в руке равняться 11(в противном случае сумма будет не менее 22, превышая 21), нам просто нужно проверить две возможности: все тузы равны 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)