Blackjack game not functioning on second restart - python

############### Our Blackjack House Rules #####################
## The deck is unlimited in size.
## There are no jokers.
## The Jack/Queen/King all count as 10.
## The the Ace can count as 11 or 1.
## Use the following list as the deck of cards:
## cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
## The cards in the list have equal probability of being drawn.
## Cards are not removed from the deck as they are drawn.
## The computer is the dealer.
from replit import clear
from art import logo
import random
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
computers_first_card = random.choice(cards)
# print(score)
# print(initial_hand)
def play_again():
play_again = input("Play again? y or n: ")
if play_again == "n":
return False
else:
clear()
blackjack_game()
def ace_check(hand, score):
if 11 in hand and score > 21:
hand[11] = 1
score - 10
def blackjack_game():
print(logo)
playing_game = True
initial_hand = [random.choice(cards), random.choice(cards)]
score = sum(initial_hand)
computers_score = computers_first_card
computers_hand = [computers_first_card]
while playing_game:
print(f"Your cards: {initial_hand}, current score: {score}")
print(f"Computer's first card: {computers_first_card}")
draw_again = input("Type 'y' to get another card, type 'n' to pass: ")
if draw_again == 'y':
draw = random.choice(cards)
ace_check(initial_hand, score)
if draw + score > 21:
initial_hand.append(draw)
score += sum(initial_hand) - score
print(f"Your final hand: {initial_hand}, final score: {score}")
print(f"Computer's final hand: {computers_first_card}")
print("You Lose!")
if play_again() == False:
playing_game = False
else:
play_again()
else:
initial_hand.append(draw)
score += sum(initial_hand) - score
else:
while computers_score < score:
draw = random.choice(cards)
ace_check(computers_hand, computers_score)
if draw + computers_score > 21:
print(f"Your final hand: {initial_hand}, final score: {score}")
print(f"Computer's final hand: {computers_hand}, final score: {computers_score}")
print("Computer went over 21 on draw!")
print("You Win!")
if play_again() == False:
playing_game = False
else:
play_again()
else:
computers_hand.append(draw)
computers_score = sum(computers_hand)
if computers_score > score:
print(f"Your final hand: {initial_hand}, final score: {score}")
print(f"Computer's final hand: {computers_hand}, final score: {computers_score}")
print("You Lose!")
if play_again() == False:
playing_game = False
else:
play_again()
play_game = input("Do you want to play a game of Blackjack? Type 'y' or 'n': ")
if play_game == "y":
clear()
blackjack_game()
In the above code, on replit, if I go over 21 after restarting an initial game when prompted, and inputing 'n' to end the program, the input print from:
def play_again():
play_again = input("Play again? y or n: ")
if play_again == "n":
return False
else:
clear()
blackjack_game()
Gets printed twice and breaks my program.
The first game always works properly. I can properly input 'n' to stop the program, but once I input I'd like to play another game, when endgame arrives again and I try to stop with inputing 'n' into play_again(), I get asked the same input twice.
Any ideas what I'm doing wrong? Here's my replit of the program so far below:
https://replit.com/#AbrahamFrancis1/blackjack-start#main.py

Related

Blackjack python game

I have to create a blackjack game in python in which the user inputs the number of decks that are being used and the amount of money the user wants to bet. The rules are: o The player places his bet (should be read from the keyboard).
o The dealer and player are dealt two cards (one card of the dealer should be hidden).
o If the player has 21 he wins his bet; else if the dealer has 21 then the dealer wins and the player loses his bet.
o The player can only select to draw a new card (hit) or pass. Repeat until the player passes or busts. If the player goes above 21 then he busts.
o Then the dealer draws cards (automatically) until he either busts or reaches 17 or higher.
o Values of cards: A= 1 or 11 (the highest that does not bust you) and J=Q=K=10
o Note: in blackjack there are more actions: insurance, double, split; those are not required to be implemented as they would make the code you have to produce much, much longer and harder
I will show you my code below when I tried to run it, it said that the name "total" is not defined on the function game, but earlier on I have already defined it. I don't know how can i fix it.
import random
N=int(input("Please enter number of decks of cards used: "))
deck= [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]*N
wins=0
losses=0
chip_pool = 100
bet = 1
def deal(deck):
hand = []
for i in range(2):
random.shuffle(deck)
card=deck.pop()
if card == 11:
card = "J"
if card == 12:
card = "Q"
if card == 13:
card = "K"
if card == 14:
card = "A"
hand.append(card)
return hand
def play_again():
again = input("Do you want to play again? (Y/N) : ").lower()
if again == "y":
dealer_hand = []
player_hand = []
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]*N
game()
else:
print("Thank you for playing.")
exit()
def total_hand():
total = 0
for card in hand:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
def hit(hand):
card = deck.pop()
if card == 11:
card = "J"
if card == 12:
card = "Q"
if card == 13:
card = "K"
if card == 14:
card = "A"
hand.append(card)
return hand
def print_results(dealer_hand, player_hand):
clear()
print("\n WELCOME TO BLACKJACK!\n")
print("The dealer has a " + str(dealer_hand) + "for a total of" + str(total(dealer_hand)))
print("You have a" + str(player_hand) + "for a total of" + str(total(player_hand)))
def blackjack(dealer_hand, player_hand):
global wins
global losses
if total(player_hand) == 21:
print_results(player_hand,dealer_hand)
print("Congratulations! You got a blackjack.\n")
wins = wins + 1
play_again()
elif total(dealer_hand) == 21:
print_results(dealer_hand,player_hand)
print("Sorry you lose. The dealer got a blackjack.\n")
chip_pool -= bet
loses = loses + 1
play_again()
def score(dealer_hand,player_hand):
if total(player_hand) == 21:
print_results(dealer_hand, player_hand)
print("Congratulations! You got a blackjack1\n")
elif total(dealer_hand) == 21:
print_results(dealer_hand, player_hand)
print("Sorry you lose. The dealer go a blackjack\n")
elif total(player_hand) > 21:
print_results(dealer_hand, player_hand)
print("Sorry, you busted. You lose.\n")
elif total(dealer_hand) > 21:
print_results(dealer_hand, player_hand)
print("Dealer busts. You win!\n")
chip_pool += bet
elif total(player_hand) < total(dealer_hand):
print_results(dealer_hand, player_hand)
print("Sorry, the score is not higher than the dealer. You lose.\n")
chip_pool -= bet
elif total(player_hand) > total(dealer_hand):
print_results(dealer_hand, player_hand)
print("Congratulations. Your score is higher than the dealer. You win.\n")
chip_pool += bet
elif total(player_hand) == total(dealer_hand):
print_results(playe_hand, dealer_hand)
print("There is a tie. In a tie dealer always wins!\n")
chip_pool -= bet
def make_bet():
global bet
bet = 0
print("What amount of chips would you like to bet? ")
while bet == 0:
bet_comp = input()
bet_comp = int(bet_comp)
if bet_comp >= 1 and bet_comp <= chip_pool:
bet = bet_comp
else:
print("Invalid bet, you only have" + str(chip_pool) + "remaining")
def game():
choice = 0
print("Welcome to Blackjack!\n")
dealer_hand = deal(deck)
player_hand = deal(deck)
print("The dealer is showing a " +str(dealer_hand[0]))
make_bet()
print("You have a " + str(player_hand))
blackjack(dealer_hand, player_hand)
quit = False
while not quit:
choice = input("Do you want to [H]it, [S]tand, or [Q]uit: ").lower()
if choice == 'h':
hit(player_hand)
print(player_hand)
if total(player_hand) > 21:
print("You busted")
chip_pool -= bet
play_again()
elif choice == "s":
while total(dealer_hand) < 17:
hit(dealer_hand)
print(dealer_hand)
if total(dealer_hand) > 21:
print("Dealer busts. You win!")
chip_pool += bet
play_again()
score(dealer_hand, playe_hand)
play_again()
elif choice == "q" :
print("Thank you for playing. Hope you enjoyed!")
quit = True
exit()
if __name__ == "__main__":
game()
You have not defined the function total that you call. Try adding this to your code
def total(array):
total = 0
for card in array:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
However I see some more issues in your code that will need fixing later on! Stand or Quit do nothing currently, and on busting there is an exception thrown since chip_pool never had a value assigned to it
EDIT 1:
You defined a function
def total_hand():
total = 0
for card in hand:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
Similar to what I suggested. Maybe it was just a typo but you need to do the following
Rename the function from total_hand to total OR call total_hand
Change the definition from total_hand() to total_hand(hand)

Is there a bug in this

I am totally new to programming. This is my second program so far. I have two challenges in this code.
For most of the initial runs this works fine in pycharm but after few runs this gives an error message like below. The bloc of code which is causing this error seems to be executing in the beginning and then its giving this error. Please someone help me with this.
Error message:
Traceback (most recent call last):
File "D:\Python\Practice\100 Days of coding\Day 11\Black Jack.py", line 81, in <module>
play_game()
File "D:\Python\Practice\100 Days of coding\Day 11\Black Jack.py", line 70, in play_game
while comp_score < 17:
TypeError: '<' not supported between instances of 'NoneType' and 'int'
Challenge 2: I have overserved that the cards stored for computer alter occasionally. I am unable to figure out why. Please help.
import random
def play_game():
def deal_card():
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
card = random.choice(cards)
return card
def calculate_score(card_list):
if sum(card_list) == 21:
if len(card_list) == 2:
return 0
else:
if 11 in card_list and sum(card_list) > 21:
card_list.remove(11)
card_list.append(1)
return sum(card_list)
def game_result():
print(f"Computer cards are {comp_cards} and computer score is {comp_score}.")
print(f"Your cards are {user_cards} and score is {user_score}.")
if comp_score == user_score:
print("Your scores are equal. Match Draw.")
elif user_score == 0:
print("Yay Black Jack! You win!")
elif comp_score == 0:
print("Computer has Black Jack. You loose.")
elif user_score > 21:
print("You went over 21. You loose.")
elif comp_score > 21:
print("Computer score went over 21. You win!")
elif user_score > comp_score:
print("You won!")
else:
print(f"Computer score {comp_score} is greater than your score {user_score}.\n You loose.")
print("Welcome to BlackJack!")
comp_cards = []
user_cards = []
for _ in range(2):
comp_cards.append(deal_card())
user_cards.append(deal_card())
user_score = calculate_score(user_cards)
print(f"Computer cards {comp_cards}")
print(f"Your cards are {user_cards} and your score is: {user_score}")
pass_ = False
while pass_ == False:
deal_a_new_card = input("Type 'y' to get another card and 'n' to pass. : ")
if deal_a_new_card == "y":
user_cards.append(deal_card())
user_score = calculate_score(user_cards)
else:
pass_ = True
if user_score > 21:
pass_ = True
print(f"Your cards are {user_cards} and your score is: {user_score}")
comp_score = calculate_score(comp_cards)
while comp_score < 17:
comp_cards.append(deal_card())
comp_score = calculate_score(comp_cards)
game_result()
play_again = 'y'
while play_again == "y":
play_game()
play_again = input("\nWould you like to play again? Enter 'y' to play. : ")
This occurs because there are some circunstances where calculate_score() is not returning any value.
You are only returning a value when 'the sum isn't 21' or 'when it's equal to 21 AND there are 2 cards'. But you should also return value if you got a sum of 21 in more than 2 cards.
So you need to include in line 13th of your code:
if sum(card_list) == 21:
if len(card_list) == 2:
return 0
#From here on:
else:
return another_value

What could I return to continue my game, another Funcion or the answer?

Im coding a game called blackjack in py, but I've stop at this part.
Im trying to set this funcion on my code, the def end_game(), where return if the Player win or the Opponent win.
I don't know what I need return to player
import random
from art import logo
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
player_deck = []
opponent_deck = []
def table():
"""Table of cards for each player."""
print(f" Your cards: {player_deck}, current score: {sum(player_deck)}")
print(f" Computer's first card: {opponent_deck[0]}")
def add_card(player: list):
"""Add a new card on the current deck."""
player.append(random.choice(cards))
def deck(player: list):
"""Define the deck for a player, need to define the first argument as a list."""
for x in range(0,2):
add_card(player)
# Verify if the player just passed the number of cards necessary to play again.
def opponent_win():
print(f" Your final hand: {player_deck}, final score: {sum(player_deck)}")
print(f" Computer's final hand: {opponent_deck}, final score: {sum(opponent_deck)}")
print("You went over. You lose =(")
def player_win():
print(f" Your final hand: {player_deck}, final score: {sum(player_deck)}")
print(f" The computer's final hand: {opponent_deck}, final score: {sum(opponent_deck)}")
print("Opponent went over. You win =)")
# End Game
def end_game(player_decision):
"""Tell if the player or the opponent win"""
sum_player = sum(player_deck)
sum_opponent = sum(opponent_deck)
if sum_player == sum_opponent:
return print("Drawn")
elif sum_player == 21:
return player_win()
elif sum_player > 21:
return opponent_win()
elif sum_opponent > 21:
return player_win()
elif sum_opponent == 21:
return opponent_win()
if player_decision == "y":
add_card(player_deck)
if sum_opponent > sum_player:
return opponent_win()
elif sum_player > sum_opponent:
return player_win()
def start():
"""Start the blackjack game."""
# Show the logo
print(logo)
print("\n" * 50)
# Set your deck and the opponent deck and start the table
deck(player_deck)
deck(opponent_deck)
while sum(opponent_deck) < 21:
add_card(opponent_deck)
table()
while True:
another_card = input("Type 'y' to get another card, type 'n' to pass: ").lower()
end_game(another_card)
while True:
confirm = input("Do you want to play a game of blackjack? (y/n): ")
if confirm != "n":
start()
player_deck = []
opponent_deck = []
else:
break
I put an While loop to ask every time to player if he wants another card, and while this's doing I need to verify if the player overpass his hand and if the game end, the player ou the opponent wins.
If you are trying to stop the while loop, you need to do that outside of the end_game function
Make the function return a boolean to indicate if the game should continue
def end_game(player_decision):
"""Tell if the player or the opponent win"""
sum_player = sum(player_deck)
sum_opponent = sum(opponent_deck)
if sum_player == sum_opponent:
print("Drawn")
elif sum_player == 21:
player_win()
elif sum_player > 21:
opponent_win()
elif sum_opponent > 21:
player_win()
elif sum_opponent == 21:
opponent_win()
elif sum_opponent > sum_player:
opponent_win()
else:
player_win()
if player_decision == "y":
add_card(player_deck)
return True
return False
Then check it
continue_game = True
while continue_game:
another_card = input("Type 'y' to get another card, type 'n' to pass: ").lower()
continue_game = end_game(another_card)
But I'd recommend moving the another_card check outside of the end_game function since they are separate phases of the game. In which case, you don't need any return statements in end_game(), or any function parameter

The code get an error: (while computer_cards_total < 17:) NameError: name 'computer_cards_total'

When I run my code through I get an error "NameError: name 'user' is not defined". I don't know what to change/add to fix this error.
I've tried to make different versions of the code and none of them worked. This one does looks like it would do what I want, but 'user' is not defined.
import art
import random
def one_cards_func():
return random.sample(set([11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]), 1)
def two_cards_func():
return random.sample(set([11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]), 2)
def calculate_score(cards):
return sum(cards)
def play_blackjack():
print(art.logo)
# I tried to define de variable as global but still didn't work...
global computer_cards_total
player_card_list = two_cards_func()
player_card_total = player_card_list[0] + player_card_list[1]
if player_card_total > 10 and player_card_list[1] == 11:
player_card_list[1] = 1
print (f"Your cards: {player_card_list} you have {player_card_total} Points.")
computer_cards_list = one_cards_func()
print(f"Computer's first card is: {computer_cards_list}")
get_another_card = input("type 'y' to get another card or type 'n' to pass: ")
if get_another_card == "y":
player_card_list += one_cards_func()
player_card_total += player_card_list[2]
if player_card_total > 10 and player_card_list[2] == 11:
player_card_list[1] = 1
computer_cards_list.append(one_cards_func())
computer_cards_total = calculate_score(computer_cards_list)
print(f"your cards: {player_card_list} your current score: {player_card_total} ")
print(f" computer card is: {computer_cards_list} with a score {computer_cards_total}")
if player_card_total <= 21 and player_card_total > computer_cards_total:
print ("You win!!!")
continue_play = input("do you want to play again? 'y' or 'n': ")
if continue_play == "y":
play_blackjack()
else:
print("bye")
else:
print("You lose...")
continue_play = input("do you want to play again? 'y' or 'n': ")
if continue_play == "y":
play_blackjack()
else:
print("bye")
elif get_another_card == "n":
*here is the error*
#The code get an error: (while computer_cards_total < 17:)
#NameError: name 'computer_cards_total' #is not defined
while computer_cards_total < 17:
computer_cards_list.append(one_cards_func())
computer_cards_total = calculate_score(computer_cards_list)
print(f"{player_card_list} your final score: {player_card_total}")
print(f"{computer_cards_list} computer final score: {computer_cards_total}")
if player_card_total <= 21 and player_card_total > computer_cards_total:
print ("You win!!!")
continue_play = input("do you want to play again? 'y' or 'n': ")
if continue_play == "y":
play_blackjack()
else:
print("bye")
else:
print("You lose...")
continue_play = input("do you want to play again? 'y' or 'n': ")
if continue_play == "y":
play_blackjack()
else:
print("bye")
if input("Do you want to play blackjack? 'y'or 'n': ") == "y":
play_blackjack()
else:
print("Bye...")
Instead of global computer_cards_total, you need to initialize computer_cards_total with some value like computer_cards_total = 0.
The problem is that computer_cards_total is only defined in the if statement if get_another_card == "y"
I would recommend you define computer_cards_total immediately after you create computer_cards_list or before the while loop where the error occurs.

Dice-rolling game doesn't change results

Doing a dice Rolling game in python, and whenever I start my second round I still end up getting the same dice results from the previous round.
import random
import time
#gets the dice side
def roll_dice(sides):
dice_results = list()
for side in sides:
roll_result = random.randint(1,side+1)
dice_results.append(roll_result)
return dice_results
#pulls a dice out from the list
def dice_fell(roll_result):
player1_dice = player1_dice_results
player2_dice = player2_dice_results
for item in player1_dice:
if item % 4 == 0:
player1_dice.remove(item)
return player1_dice
for item in player2_dice:
if item % 4 == 0:
player2_dice.remove(item)
return player2_dice
# variables
dice_set1=[4, 6, 8, 10, 12, 20, 100]
dice_set2=[4, 6, 8, 10, 12, 20, 100]
player1_dice_results = roll_dice(dice_set1)
player2_dice_results = roll_dice(dice_set2)
player1_final_results = dice_fell(player1_dice_results)
player2_final_results = dice_fell(player2_dice_results)
player1_total= sum(player1_dice_results)
player2_total= sum(player2_dice_results)
player1_score = 0
player2_score = 0
while player1_score < 3 or player2_score < 3:
# This part just announces what happens
exit= input(str("Press Enter to start! Press 'q' to leave after each round! \n"))
if exit != "q":
print("Let's begin! Be careful for the small table!")
elif exit == "q":
quit()
print("You are rolling...")
time.sleep(2)
print("You have rolled: ",player1_final_results)
if len(player1_final_results) < 7:
print("Sorry player 1, some of your dice have fallen off the table!")
print()
print("Your total is: ",player1_total)
print()
print("Player 2 is rolling...")
time.sleep(2)
print("Player 2 has rolled:" ,player2_final_results)
if len(player2_final_results) < 7:
print("Sorry player 2, some of your dice have fallen off the table!")
print()
print("Player 2's total is: ",player2_total)
print()
if player1_total > player2_total:
print()
print("You have won the round with,",player1_total,"!"),
player1_score += 1
print("Your score is: ",player1_score)
elif player2_total > player1_total:
print()
print("Player 2 has won the round with,",player2_total,"!"),
player2_score += 1
print("Player 2's score is: ",player2_score)
if player1_score == 3:
print("Congratulations, you won!")
elif player2_score == 3:
print("Player 2 wins! Better luck next time champ!")
I believe that I've fixed the indentation problems.
I have reproduced the problem.
As Kevin said, your immediate problem is that you roll the dice only once, before you enter your while loop. Here's what it looks like with the rolls inside the loop, but after the player decides whether to continue.
dice_set1=[4,6,8,10,12,20,100]
dice_set2=[4,6,8,10,12,20,100]
player1_score = 0
player2_score = 0
while player1_score < 3 or player2_score < 3:
# This part just announces what happens
exit = raw_input(str("Press Enter to start! Press 'q' to leave after each round! \n"))
if exit != "q":
print("Let's begin! Be careful for the small table!")
elif exit == "q":
quit()
player1_dice_results = roll_dice(dice_set1)
player2_dice_results = roll_dice(dice_set2)
player1_final_results = dice_fell(player1_dice_results)
player2_final_results = dice_fell(player2_dice_results)
player1_total= sum(player1_dice_results)
player2_total= sum(player2_dice_results)
print("You are rolling...")
... # remainder of code omitted
That said, do note that you have several other problems with the program. You won't terminate until both players have won three times -- use and instead of or in the while condition.
Most of my other comments are more appropriate for the codeReview group; you might post there when you're done debugging.

Categories

Resources