So I was scripting blackjack in python, but came across a problem with the aces in hands (some hands might have 1 ace, 2 ace or after hit, 3 aces or max 4), the problem is to find the greatest sum less than or equal to 21. This sounded easy, but then the complication arises when each ace can either be of value 1 or 11, cannot be re-counted and the number of aces varies, example
aces = [[1, 11], [1, 11]] #could be aces = [[1,11]] or etc. where one ace is [1, 11]
so what I currently had didn't work for me as the amount of for-loops had already fixed an amount of aces... (in this case two)
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
This was fixed to having exactly two aces in the hand, and there existed the error that I was actually adding two lists, but I want to sum all the combinations of [1, 11] for how many aces there are. (e.g. for 20: 11, 1, 1, 7 where 7 is not an ace)
So what could I tackle this problem?
You can use a binary number to express all the possible hands.
Consider we have 3 aces in hand, so there are 23 = 8 possible hands. We can represent all the 8 possible hands by integers 0~7.
Let's say we want to know the value of a possible hand represented by integer 5(that is 101 in binary form). We check through all the bits of the binary integer, and if the i-th bit is 1, we consider selecting the i-th ace as 11, otherwise we consider selecting the i-th ace as 1. Then the value for possible hand #5(or 101 in binary form) is 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)
There is actually another solution to this problem, which I think is better. As we can only let at most one ace in hand to be 11(otherwise the sum will be at least 22, exceeding 21), we just need to check two possibilities: all of the aces are 1, and only one of them is 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)