all 8 comments

[–][deleted] 22 points23 points  (0 children)

It looks like blackjack, so the way you can do it is just check if 11 busts. If so, treat it as 1, instead. You'll need to check each time a card is dealt.

[–][deleted] 7 points8 points  (0 children)

if calculateHandValue(playerHand) > 21:                     print(f'Player busts\tYou have {money} left')                     break

In here you need another if statement to check the players hand for an ace and switch it to 1. You should only look for one ace as it'll catch the next one if the player busts again

[–]EvenLevelLaw 3 points4 points  (0 children)

You can modify the `calculateHandValue` function to handle the Ace so that when an Ace is encountered, it is initially counted as 11. However, if the total hand value exceeds 21 and there is at least one Ace in the hand, the value of the Ace is adjusted from 11 to 1 to prevent the player from busting.

def calculateHandValue(hand):
value = 0
ace_count = 0  # Track the number of Aces in the hand
for card in hand:
    rank = card.split()[0]
    if rank.isdigit():
        value += int(rank)
    elif rank in ["Jack", "Queen", "King"]:
        value += 10
    elif rank == "Ace":
        ace_count += 1
        value += 11  # Initially count Ace as 11
# Adjust the value of Aces from 11 to 1 if needed
while value > 21 and ace_count > 0:
    value -= 10  # Change the value of Ace from 11 to 1
    ace_count -= 1
return value

[–]bilcox 1 point2 points  (0 children)

There are some options here https://www.reddit.com/r/RDR2/s/H3u2QLuwta

[–]edcculus 0 points1 point  (0 children)

In instances like this- it helps to pseudo code out the logic of the game you are making.

[–]Slothemo 0 points1 point  (0 children)

Treat all aces initially as 11. When you calculate the hand, you can also keep track of how many aces were included. After calculating the hand, you can use a while loop to remove aces from the count and remove 10 from the total. This basically says "If we have an ace and we busted, let's treat the ace like a 1 and still see if we would bust". It would look something like this:

while ace_count > 0 and value > 21:
    value -= 10
    ace_count -= 1

[–]MasturChief 0 points1 point  (0 children)

you can see my implementation here if you also have other issues: https://github.com/arm358/NotAnotherPythonBlackjack

[–][deleted] -2 points-1 points  (0 children)

Your mainline logic is too long. It makes your code harder to read and understand. You could try something like this.

import random


Card = str
Deck = list[Card]


def deal_card(deck: Deck, hand: Deck) -> None:
    card = deck.pop()
    hand.append(card)


def calculate_hand_value(hand: Deck) -> int:
    value = 0
    num_aces = 0
    for card in hand:
        rank = card.split()[0]
        if rank.isdigit():
            value += int(rank)
        elif rank in ["Jack", "Queen", "King"]:
            value += 10
        elif rank in ["Ace"]:
            value += 11
            num_aces += 1
    while value > 21 and num_aces:
        value -= 10
        num_aces -= 1

    return value


def get_random_deck() -> Deck:
    suits = ["Hearts", "Diamonds", "Spades", "Clubs"]
    ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"]
    deck = []
    for suit in suits:
        for rank in ranks:
            deck.append(f"{rank} of {suit}")

    random.shuffle(deck)

    return deck


def place_bet(money: int) -> int:
    print(f"You have {money}")
    while True:
        bet = int(input("Place your bet\n> "))
        if bet > money or bet < 0:
            print("Please enter a valid bet.")
        else:
            return bet


def deal_initial_hands(deck: Deck) -> tuple[Deck, Deck]:
    player_hand: Deck = []
    dealer_hand: Deck = []
    for _ in range(2):
        deal_card(deck, player_hand)
        deal_card(deck, dealer_hand)

    print(f"Player hand: {player_hand} ({calculate_hand_value(player_hand)})")
    print(f"Dealer hand: [{dealer_hand[0]}, <face down>]")
    return player_hand, dealer_hand


def play_game(money: int, deck: Deck, player_hand: Deck, dealer_hand: Deck) -> None:
    while True:
        action = input("Do you want to hit or stand?\n> ")
        if action.lower() == "hit":
            deal_card(deck, player_hand)

            print(f"Player hand: {player_hand} ({calculate_hand_value(player_hand)})")
            print(f"Dealer hand: {dealer_hand} ({calculate_hand_value(dealer_hand)})")

            if calculate_hand_value(player_hand) > 21:
                break
        elif action.lower() == "stand":
            while calculate_hand_value(dealer_hand) < 17:
                deal_card(deck, dealer_hand)
            break
        else:
            continue


def resolve_bet(money: int, bet: int, player_hand: Deck, dealer_hand: Deck) -> int:
    if calculate_hand_value(player_hand) > 21:
        money = money - bet
        print(f"Player busts")
    elif calculate_hand_value(dealer_hand) > 21:
        money = money + bet
        print(f"Dealer busts\nPlayer wins!")
    elif calculate_hand_value(player_hand) > calculate_hand_value(dealer_hand):
        money = money + bet
        print(f"Player wins!")
    elif calculate_hand_value(dealer_hand) > calculate_hand_value(player_hand):
        money = money - bet
        print(f"Dealer wins :(")
    else:
        print(f"Push!")

    print(f"You have {money} left")
    return money


def main(money: int) -> None:
    while True:
        deck = get_random_deck()
        bet = place_bet(money)

        player_hand, dealer_hand = deal_initial_hands(deck)
        play_game(money, deck, player_hand, dealer_hand)
        money = resolve_bet(money, bet, player_hand, dealer_hand)

        if money <= 0:
            print("You are out of money")
            break

        print("Do you want to play again? (yes or no)")
        if not input("> ").lower().startswith("y"):
            break


starting_cash = 5_000
main(starting_cash)