1
\$\begingroup\$

This is my simple Blackjack game made in Python. I would love some feedback to write better code.

from art import logo    
import random

input("Do you want to play black-jack ? 'y' or 'no': ")
print()
print(logo)

cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
user_hand = []
com_hand = []


def print_score(score_to_print):

    if score_to_print == "user":
        print(f"user_hand {user_hand} your score = {get_score(user_hand)}")
    elif score_to_print == "com":
        print(f"com_hand{com_hand} com_score = {get_score(com_hand)}")


def get_score(hand):
    score = 0
    for i in range(len(hand)):
        score += hand[i]

    return score


def restart_game(result):

    print(result)
    print_score("user")
    print_score("com")

    user_hand.clear()
    com_hand.clear()
    user_input = input("Do you want to play black-jack ? 'y' or 'no': ")
    if user_input == 'y':
        deal_cards(cards)
    else:
        print("ok bye bye have fun in the afterlife")


def check_for_blackjack(hand):
    if get_score(com_hand) == 21:
        restart_game("You Lose")
    elif get_score(user_hand) == 21:
        restart_game("you Win")


def check_for_score_over_21():
    if get_score(user_hand) > 21:
        restart_game("You Lose")
    elif get_score(com_hand) > 21:
        restart_game("You Win")


def check_for_ace(card, hand):
    if get_score(hand) + card > 21:
        card = 1
    return card


def check_for_winner():
    user_score = get_score(user_hand)
    com_score = get_score(com_hand)
    if user_score == com_score:
        restart_game("Draw")
    elif user_score < com_score:
        restart_game("You Lose")
    else:
        restart_game("You Win")


def deal_computer_cards():
    while get_score(com_hand) < 17:
        new_card = random.choice(cards)
        com_hand.append(check_for_ace(new_card, com_hand))


def ask_for_new_card():
    print_score("user")
    user_choice = input("Do you want another card ?: ")

    if user_choice == 'y':
        new_card = random.choice(cards)
        user_hand.append(check_for_ace(hand=user_hand, card=new_card))
        if get_score(user_hand) < 21:
            ask_for_new_card()
        elif get_score(user_hand) == 21:
            restart_game("You Win")
        elif get_score(user_hand) > 21:
            restart_game("You Lose")
        else:
            print_score("user")
    elif user_choice == 'n':
        deal_computer_cards()
        check_for_winner()


def add_cards_to_hand(hand):
    card1 = random.choice(cards)
    card2 = random.choice(cards)
    hand.append(check_for_ace(card1, hand))
    hand.append(check_for_ace(card2, hand))


def deal_cards(cards):
    add_cards_to_hand(user_hand)
    print_score("user")
    
    add_cards_to_hand(com_hand)
    check_for_blackjack(com_hand)
    check_for_blackjack(user_hand)
    
    print(f"com_hand {com_hand} com score = {get_score(com_hand)}")
    print(f"computer first card is a {com_hand[0]}")
    
    ask_for_new_card()

deal_cards(cards)
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

input("Do you want to play black-jack ? 'y' or 'no': ")
This line doesn't do anything since you never assign the result of the input function to a name or use it as a parameter.


def print_score(score_to_print):
    if score_to_print == "user":
        print(f"user_hand {user_hand} your score = {get_score(user_hand)}")
    elif score_to_print == "com":
        print(f"com_hand{com_hand} com_score = {get_score(com_hand)}")

This can be split in half to avoid unnecessary branching:

def print_user_info():
    print(f"Your hand: {*user_hand}")
    print(f"Your score: {get_score(user_hand)}")


def print_bot_info():
    print(f"Bot's hand: {*bot_hand}")
    print(f"Bot's score: {get_score(bot_hand)}")

Or rewritten for the general case:

def print_info(player_name: str, player_hand: List[int]):
    print(f"{player_name}'s hand: {*player_hand}")
    print(f"{player_name}'s score: {get_score(player_hand)}")

def get_score(hand):
    score = 0
    for i in range(len(hand)):
        score += hand[i]

    return score

This can be rewritten as

def get_score(hand: List[int]):
    return sum(hand)

In fact you don't really need a function for this, using sum(hand) in the code conveys the meaning pretty well.


ask_for_new_card() asks for user input and checks if it's y or n. It's never told to the player that these are the only options. If you type no for example, the program just exits.

You need to account for other possible input. For example asking again if the user didn't enter one of the options. You can also try to change the input to the standard form. For example this line will return "Y" for any word that starts with a y:
response = input()[0].upper()


def check_for_ace(card, hand):
    if get_score(hand) + card > 21:
        card = 1
    return card

This doesn't actually check whether the card is ace or not. Since you use it every time you add a card to someone's hand, it's completely impossible to lose:

user_hand [7, 7] your score = 14
Do you want another card ?: y
user_hand [7, 7, 1] your score = 15
Do you want another card ?: y
user_hand [7, 7, 1, 1] your score = 16
Do you want another card ?: y
user_hand [7, 7, 1, 1, 1] your score = 17
Do you want another card ?: y
user_hand [7, 7, 1, 1, 1, 1] your score = 18
Do you want another card ?: y
user_hand [7, 7, 1, 1, 1, 1, 1] your score = 19
Do you want another card ?: y
user_hand [7, 7, 1, 1, 1, 1, 1, 1] your score = 20
Do you want another card ?: y
You Win
user_hand [7, 7, 1, 1, 1, 1, 1, 1, 1] your score = 21

Please test your code before posting it here.

\$\endgroup\$
1
  • \$\begingroup\$ thank you for your extensive answer, and sorry for overlooking the problem with the ace, i will test my code more in-depth for the future will improve my code with your suggestions :) \$\endgroup\$ Oct 24, 2022 at 6:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.