Why does newDeck.pop(0) give an attribute error? - python

I'm making a blackjack game in python, but the .pop(0) method I'm using to get rid of cards comes up with an attribute error, does anyone know why?
for i in range(2):
drawnCard = newDeck.pop(0)
playerList.append(drawnCard)
if (drawnCard[:1] == "J" or drawnCard[:1] == "Q" or drawnCard[:1] == "K"):
playerSum += 10
elif (drawnCard[:1] == "A"):
playerSum += 11
elif ((drawnCard[:2]) == "10"):
playerSum += 10
else:
playerSum += int(drawnCard[:1])
here's the full code
from random import shuffle
deck = ["A♠", "2♠", "3♠", "4♠", "5♠", "6♠", "7♠", "8♠", "9♠", "10♠", "J♠", "Q♠", "K♠", "A♥", "2♥", "3♥", "4♥", "5♥", "6♥", "7♥", "8♥", "9♥", "10♥", "J♥", "Q♥", "K♥", "A♣", "2♣", "3♣", "4♣", "5♣", "6♣", "7♣", "8♣", "9♣", "10♣", "J♣", "Q♣", "K♣", "A♦", "2♦", "3♦", "4♦", "5♦", "6♦", "7♦", "8♦", "9♦", "10♦", "J♦", "Q♦", "K♦"]
newDeck = shuffle(deck)
playerList = []
playerSum = 0
dealerList = []
dealerSum = 0
for i in range(2):
drawnCard = newDeck.pop(0)
playerList.append(drawnCard)
if (drawnCard[:1] == "J" or drawnCard[:1] == "Q" or drawnCard[:1] == "K"):
playerSum += 10
elif (drawnCard[:1] == "A"):
playerSum += 11
elif ((drawnCard[:2]) == "10"):
playerSum += 10
else:
playerSum += int(drawnCard[:1])
if len(playerList) == 2:
if playerSum == 21:
if dealerSum != 21:
print ("Players Hand: ")
print (playerList)
print()
print ("Total: ")
print (playerSum)
print("Congrats, you got a blackjack!!!")
exit("Won Game")
if dealerSum == 21:
print ("Players Hand: ")
print (playerList)
print()
print ("Total: ")
print (playerSum)
print("You both got a blackjack, it's a tie!")
exit("Game Tied!")
playing = True
while(playing):
print ("Players Hand: ")
print (playerList)
print()
print ("Total: ")
print (playerSum)
user = input("Would you like to hit or stay? (h/s)\n")
if (user == "h"):
drawnCard = newDeck.pop(0)
playerList.append(drawnCard)
if (drawnCard[:1] == "J" or drawnCard[:1] == "Q" or drawnCard[:1] == "K"):
playerSum += 10
elif (drawnCard[:1] == "A"):
playerSum += 11
elif (drawnCard[:2] == "10"):
playerSum += 10
else:
playerSum += int(drawnCard[:1])
print ("Players Hand: ")
print (playerList)
print()
print ("Total: ")
print (playerSum)
print("---------------------------------------------------------------------------------------------------------------------------------------------------------------------")
if playerSum > 21:
if 'A' in playerList:
playerSum -= 10
else:
print ("Players Hand: ")
print (playerList)
print()
print ("Total: ")
print (playerSum)
print("Wow you suck at blackjack ._.")
exit("Game Lost!")
elif (user == "s"):
print("---------------------------------------------------------------------------------------------------------------------------------------------------------------------")
playing = False
for i in range(2):
drawnCard = newDeck.pop(0)
dealerList.append(drawnCard)
if (drawnCard[:1] == "J" or drawnCard[:1] == "Q" or drawnCard[:1] == "K"):
dealerSum += 10
elif (drawnCard[:1] == "A"):
dealerSum += 11
elif (drawnCard[:2] == "10"):
dealerSum += 10
else:
dealerSum += int(drawnCard[:1])
playing = True
while (playing):
if dealerSum >= 17:
playing = False
else:
drawnCard = newDeck.pop(0)
dealerList.append(drawnCard)
if (drawnCard[:1] == "J" or drawnCard[:1] == "Q" or drawnCard[:1] == "K"):
dealerSum += 10
elif (drawnCard[:1] == "A"):
dealerSum += 11
elif ((drawnCard[:2]) == "10"):
dealerSum += 10
else:
dealerSum += int(drawnCard[:1])
print ("Dealers Hand: ")
print (dealerList)
print()
print ("Total: ")
print (dealerSum)
print("---------------------------------------------------------------------------------------------------------------------------------------------------------------------")
if dealerSum > 21:
if "A" in dealerList:
dealerSum -= 10
else:
print("Players hand: ")
print(playerList)
print()
print("Total: ")
print(playerSum)
print("Dealers hand: ")
print(dealerList)
print()
print("Total: ")
print(dealerSum)
print("The dealer busted! Congrats!")
exit("Won Game! ")
if playing == False:
if (dealerSum > playerSum):
print("---------------------------------------------------------------------------------------------------------------------------------------------------------------------")
print("Final results: ")
print("Players hand: ")
print(playerList)
print()
print("Total: ")
print(playerSum)
print("Dealers hand: ")
print(dealerList)
print()
print("Total: ")
print(dealerSum)
print("You Lose!")
exit("Game Lost!")
elif (dealerSum < playerSum):
print("---------------------------------------------------------------------------------------------------------------------------------------------------------------------")
print("Final results: ")
print("Players hand: ")
print(playerList)
print()
print("Total: ")
print(playerSum)
print("Dealers hand: ")
print(dealerList)
print()
print("Total: ")
print(dealerSum)
print("You Win!")
exit("Game Won!")
else:
print("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------")
print("Final results: ")
print("Players hand: ")
print(playerList)
print()
print("Total: ")
print(playerSum)
print("Dealers hand: ")
print(dealerList)
print()
print("Total: ")
print(dealerSum)
print ("It's a tie!")
exit("Game Tied!")
name-MacBook-Air:Python name$ /usr/bin/env /usr/local/bin/python3 /Users/name/.vscode/extensions/ms-python.python-2022.14.0/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher 61743 -- /Users/name/Desktop/Code/Python/boop.py
Traceback (most recent call last):
File "/Users/name/Desktop/Code/Python/boop.py", line 15, in <module>
drawnCard = newDeck.pop(0)
AttributeError: 'NoneType' object has no attribute 'pop'
name-MacBook-Air:Python name$

The error is in how you're shuffling the deck.
newDeck = shuffle(deck)
The random.shuffle function shuffles a list in-place and returns None, so newDeck is getting assigned to None here. This is why Python gives you the error:
AttributeError: 'NoneType' object has no attribute 'pop'
later when you try to pop the first card off of newDeck.
You need to call shuffle(deck) (without assigning it to a new variable) and use the deck variable in the rest of your program.

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)

When my code not exiting while loop in python?

It's a black jack game project. When user_score > 21 or 21 , it shold exit the while loop but it is not exiting while loop.I am new in coding. Plese tell me where is the problem.
I don't want to use break command. Because from which tutorial I am learning she has not taught me it yet.
You can get an idea of black jack game here.247blackjack
I tried these lines of code.
import random
def deal_card():
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
random_index = random.randint(0,(len(cards)-1))
random_card = cards[random_index]
return random_card
def want_another_card():
want_card = input("Want another card type 'y' for yes and type 'n' for no.")
return want_card
user_card = []
computer_card = []
for x in range(0,2):
user_card.append(deal_card())
computer_card.append(deal_card())
def calculate_score(list):
score = sum(list)
return score
user_score = calculate_score(user_card)
computer_score =calculate_score(computer_card)
#final score function
def final_score_calculation():
while calculate_score(computer_card)< 17:
computer_card.append(deal_card())
line_gap()
print(f"Your final hand: {user_card}, final score: {user_score}")
print(f"Computer's final hand: {computer_card}, final score: {computer_score}")
if user_score > computer_score and user_score < 21:
winner = "User"
print(f"{winner} wins")
elif computer_score > user_score and computer_score < 21:
winner = "computer"
print(f"{winner} wins")
elif computer_score > 21:
print("Computer busted. You win.")
elif user_score > 21:
print("User busted, Computer wins")
elif user_score == 21:
print("user wins")
elif computer_score == 21:
print("computer wins")
elif computer_score == user_score:
print("It's a draw")
should_continue = True
while should_continue == True:
print(f"Your cards: {user_card}, current score {calculate_score(user_card)}")
print(f"computer's first card {computer_card[0]}")
#checking if user or computer has a black jack
if user_score == 21 and len(user_card) == 2:
print("User has the blackJack. You win")
should_continue = False
elif computer_score ==21 and len(computer_card) == 2:
print("Computer has the black jack .You lose")
should_continue = False
#checking if they got busted or got 21
if user_score > 21: #checking user
if 11 in user_card:
usr_indx_pos=user_card.index(11)
user_card[usr_indx_pos] = 1
if user_score > 21:
print("you got busted.You lose.")
should_continue = False
elif user_score ==21:
print("you have 21 . you win")
should_continue = False
else:
print("you got busted.You lose.")
should_continue = False
elif computer_score > 21: #checking computer
if 11 in computer_card:
com_indx_pos = computer_card.index(11)
computer_card[com_indx_pos] = 1
if computer_score > 21:
print("computer busted. you win")
should_continue = False
else:
print("computer got busted. You win")
should_continue = False
elif user_score ==21:
print("you win. you got 21")
should_continue = False
elif computer_score ==21:
print("computer win. computer got 21")
should_continue = False
line_gap()
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
Assuming your complaint is that it is prompting you if you want another card even after you bust (or win), the solution is to ensure you don't issue that prompt when the loop is supposed to be done anyway. Just change:
if want_another_card() == "y":
to:
if should_continue and want_another_card() == "y":
This will cause it to do the final_score_calculation() call in the else, which may be redundant; if it shouldn't report the results again when someone has already busted or got exactly 21, wrap the whole of:
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
in a check to see if it already knows it's done, making it:
if should_continue:
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
so it does no additional work when it already knows the game is over.

Rock Paper Scissor Loop Issue Python

As most learning python I have been tasked with making a game of rock paper scissor. As of right now I have a put together a code that works if you just run it through once. My issue is that it needs to run on a loop, running until either the user or the computer wins three times. This is what I have without putting the loop in place:
ug = input("Please enter your choice for: rock, paper, or scissors: ")
comp = [ ]
user = [ ]
random = np.random.randint(0, 3, 1)
# 1). Converts the randomly generated computer guess to str
def guessC(random):
if random == 0:
return ("R")
if random == 1:
return ("S")
if random == 2:
return ("P")
compg = guessC(random)
# prints the user guess (ug) and comp guess (compg)
print("You guessed: ", ug)
print("The computer guessed: ", compg)
#2). Determine winner
def rockpaperscisccor(compg, ug):
if compg == "R":
if ug == "R":
return 0,0
elif ug == "S":
return 1,0
elif ug == "P":
return 0,1
if compg == "P":
if ug == "P":
return 0,0
elif ug == "R":
return 1,0
elif ug == "S":
return 0,1
if compg == "S":
if ug == "S":
return 0,0
elif ug == "P":
return 1,0
elif ug == "R":
return 0,1
cs,us = rockpaperscisccor(compg, ug)
# 3). take scores of game and append comp score to its own list and user score to
# own list
def tallyuserH(us):
user = [ ]
user.append(us)
tus = 0
for i in user:
tus += i
return tus
sus = tallyuserH(us)
def compuserH(cs):
comp = [ ]
comp.append(cs)
tcs = 0
for i in comp:
tcs += i
return tcs
scs = compuserH(cs)
# 4). Score counter to determine score
def scorecounter(scs, sus):
if scs == 3:
print("The computer wins!", cs, "-", us, "!")
elif sus == 3:
print("You win!", us, "-", cs, "!")
elif scs > sus:
print("The computer leads!", cs, "-", us, "!")
elif sus > scs:
print("You lead!", us, "-", cs, "!")
elif sus == scs:
print("The score is tied at", cs, "-", us, "!")
else:
print("That doesn't seem to be a valid input")
scorecounter(scs,sus)
This is what I have got so far when I put it into a while loop. it's running infinitely where as I wanted it to stop when one player gets to 3:
print("Lets play rock, paper, scissor!")
def thegame():
i = 0
ug = input("Please enter your choice for: rock, paper, or scissors: ")
random = np.random.randint(0, 3, 1)
compg = guess(random)
print("You guessed: ", ug)
print("The computer guessed: ", compg)
cs,us = rockpaperscisccor(compg, ug)
sus = tallyuser(us)
scs = compuser(cs)
print ("user score is", sus)
print ("comp score is", scs)
while i < 6:
if scs == 3:
print("The computer wins!", cs, "-", us, "!")
elif sus == 3:
print("You win!", us, "-", cs, "!")
elif scs > sus:
print("The computer leads!", cs, "-", us, "!")
elif sus > scs:
print("You lead!", us, "-", cs, "!")
elif sus == scs:
print("The score is tied at", cs, "-", us, "!")
else:
print("That doesnt seem to be a valid input")
i += 1
return i
def guess(random):
if random == 0:
return ("R")
if random == 1:
return ("S")
if random == 2:
return ("P")
def tallyuser(us):
user = [ ]
user.append(us)
tus = 0
for i in user:
tus += i
return tus
def compuser(cs):
comp = [ ]
comp.append(cs)
tcs = 0
for i in comp:
tcs += i
return tcs
thegame()
I can't figure out how to structure the While loop. Also the "score counter function" needs to remain its own piece, just meaning I can't nest that part in where I determine the winner. If that makes sense!
Thank you,
Rachel
Tried my best to keep the essence of your existing code, and not change it too much:
import random
def get_round_points(comp_choice, user_choice):
if comp_choice == "R":
if user_choice == "R":
return 0, 0
elif user_choice == "S":
return 1, 0
elif user_choice == "P":
return 0, 1
if comp_choice == "P":
if user_choice == "P":
return 0, 0
elif user_choice == "R":
return 1, 0
elif user_choice == "S":
return 0, 1
if comp_choice == "S":
if user_choice == "S":
return 0, 0
elif user_choice == "P":
return 1, 0
elif user_choice == "R":
return 0, 1
def get_choice():
valid_choices = {'R', 'P', 'S'}
choice = ''
while choice not in valid_choices:
choice = input("Please enter your choice from (R)ock, (P)aper, or (S)cissors: ")
return choice
def score_counter(current_comp_score, current_user_score, win_threshold):
if current_comp_score == win_threshold:
print("The computer wins!", current_comp_score, "-", current_user_score, "!")
elif current_user_score == win_threshold:
print("You win!", current_user_score, "-", current_comp_score, "!")
elif current_comp_score > current_user_score:
print("The computer leads!", current_comp_score, "-", current_user_score, "!")
elif current_user_score > current_comp_score:
print("You lead!", current_user_score, "-", current_comp_score, "!")
elif current_user_score == current_comp_score:
print("The score is tied at", current_comp_score, "-", current_user_score, "!")
else:
print("That doesn't seem to be a valid input to score_counter...")
def play_rock_paper_scissors(win_threshold):
comp_score, user_score = 0, 0
while comp_score != win_threshold and user_score != win_threshold:
score_counter(comp_score, user_score, win_threshold)
user_choice = get_choice()
print("You guessed: ", user_choice)
comp_choice = ['R', 'P', 'S'][random.randint(0, 2)]
print("The computer guessed: ", comp_choice)
round_result = get_round_points(comp_choice, user_choice)
comp_score += round_result[0]
user_score += round_result[1]
score_counter(comp_score, user_score, win_threshold)
if __name__ == '__main__':
play_rock_paper_scissors(3)
Example Usage:
The score is tied at 0 - 0 !
Please enter your choice from (R)ock, (P)aper, or (S)cissors: R
You guessed: R
The computer guessed: S
You lead! 1 - 0 !
Please enter your choice from (R)ock, (P)aper, or (S)cissors: P
You guessed: P
The computer guessed: R
You lead! 2 - 0 !
Please enter your choice from (R)ock, (P)aper, or (S)cissors: S
You guessed: S
The computer guessed: R
You lead! 2 - 1 !
Please enter your choice from (R)ock, (P)aper, or (S)cissors: S
You guessed: S
The computer guessed: P
You win! 3 - 1 !

Print the cards that I used after I typed yes to play again

I want this game to start each hand with the cards left over from the previous hand. Instead, it begins with a complete, newly-shuffled deck. How can I fix it to just continue?
I updated the code based in your advice but it doesnt display my show card thanks a lot
import random, sys
suits = ('Clubs', 'Spades', 'Hearts', 'Diamonds')
pip = ('Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King')
pipValues = {'Ace':11, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'Jack':10, 'Queen':10, 'King':10}
class Card:
def __init__(self, suit, pip):
self.suit = suit
self.pip = pip
self.value = pipValues.get(pip)
def __str__(self):
thisCard = ""
thisCard += str(self.pip)
thisCard += str(self.suit)
return (thisCard)
def __repr__(self):
thisCard = ""
thisCard += str(self.pip)
thisCard += str(self.suit)
return (thisCard)
class Player:
def __init__(self):
self.hand = []
self.handTotal = 0
def __str__(self):
printHand = ""
for i in self.hand:
printHand += str(i) + " "
return (printHand)
def __repr__(self):
printHand = ""
for i in self.hand:
printHand += str(i) + " "
return (printHand)
class Deck:
def __init__(self):
self.cardList = []
#for each suit take every card
for i in range(len(suits)):
for j in range(len(pip)):
self.cardList.append(Card(suits[i], pip[j]))
def shuffle(self):
random. shuffle (self.cardList)
def dealOne(self, player):
(player.hand).append(self.cardList[0])
player.handTotal += self.cardList[0].value
del self.cardList[0]
print self.cardList
return self.cardList
def __str__(self):
printString = ""
for i in range(len(self.cardList)):
if i % 13 == 0:
printString += "\n \t"
printString += str(self.cardList[i]) + " "
else:
printString += str(self.cardList[i]) + " "
printString += "\n"
return printString
def showHands(player, opponent):
print ('Dealer shows ' + str(opponent.hand[0]) + ' faceup')
print ('You show ' + str(player.hand[0]) +str(player.hand[0] ))
def playerTurn(deck, player, other):
#First, check scores to see if either player has a blackjack:
if player.handTotal == 21 or other.handTotal == 21:
if other.handTotal == 21:
print ('You hold ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("Dealer has " + str(other) + "for a total of 21")
print ("Dealer has a Blackjack! Dealer wins!")
print ("Thanks for playing. Come back again soon! ")
message()
else:
print ("You hold " + str(player) + "for a total of 21")
print ("You have a Blackjack! You win!")
print ("Thanks for playing. Come back again soon! ")
message()
hitOrStand = 0
aces = False
#IF TWO ACES
if player.hand[0].pip == "A" and player.hand[1].pip == "A":
player.hand[0].pipValue = 1
if player.handTotal == 21:
print ('You hold ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("Blackjack! You win!")
print ("Thanks for playing. Come back soon!")
print()
message()
while hitOrStand != 2:
#check for aces
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
print ('You hold ' + str(player) + 'for a total of ' + str(player.handTotal))
print()
hitOrStand = input('Do you hit or stand? Enter "1" for hit and "2" for stand: ')
while hitOrStand != 1 and hitOrStand != 2:
try:
hitOrStand = int(hitOrStand)
break
except ValueError:
print ("Enter a valid integer \n")
hitOrStand = input('Do you hit hit or stand? Enter "1" for hit and "2" for stand: ')
print()
if hitOrStand == 1:
print('Card dealt: ' + str(deck.cardList[0]))
print()
deck.dealOne(player)
#check if an ace was drawn
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
if player.handTotal == 21:
print ('You hold ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("Blackjack!! You Win!")
print()
print ("Thanks for playing. Come back soon!")
message()
if player.handTotal > 21:
#check for aces
if aces:
print ('You hold ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("Over 21. Value of ace changed to 1")
#chanlge value of ace and hand
player.handTotal = player.handTotal - 10
for i in player.hand:
if i.pip == "A" and i.value == 11:
i.value = 1
#check for other standard aces
aces = False
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
else:
print ('You hold ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("You Bust! Dealer Wins!")
#exit, since you're a loser
print ("Thanks for Playing! Come Back Soon!")
print()
raise SystemExit
if hitOrStand == 2:
print ('You stand at: ' + str(player.handTotal))
print()
print ("Now Dealer's Turn")
print ()
def message():
again = raw_input("Do you want to play again? (Y/N) : ")
if(again == "Y" or again == "y"):
main()
else:
print "\n\n-------Thank you for playing!--------\n\n"
exit()
def opponentTurn(deck, player, other):
if other.handTotal == 21:
raise SystemExit
aces = False
hitOrStand = 0
#IF TWO ACES
if player.hand[0].pip == "A" and player.hand[1].pip == "A":
player.hand[0].pipValue = 1
while hitOrStand != 2:
#check for aces
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
print ('Dealer holds ' + str(player) + 'for a total of ' + str(player.handTotal))
print()
#if blackjack
if player.handTotal == 21:
print ("Dealer has a BlackJack! Dealer Wins!")
break
if player.handTotal <21 and other.handTotal == 21:
print ("Dealer's hand is " + str(player.handTotal) + ". You have a Blackjack! Congratulations! You win! ")
break
if player.handTotal < other.handTotal:
hitOrStand = 1
if player.handTotal >= other.handTotal:
hitOrStand = 2
if hitOrStand == 1:
print("Dealer hits. " + 'Card dealt: ' + str(deck.cardList[0]))
deck.dealOne(player)
#check if an ace was drawn
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
if player.handTotal > 21:
#check for aces
if aces:
print ('Dealer holds ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("Over 21. Value of ace changed to 1")
#chanlge value of ace and hand
player.handTotal = player.handTotal - 10
for i in player.hand:
if i.pip == "A" and i.value == 11:
i.value = 1
#check for other standard aces
aces = False
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
else:
print ('Dealer holds ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("Dealer Busts! You Win!")
message()
if hitOrStand == 2:
print ("Dealer stands at " + str(player.handTotal))
print ("Your score is " + str(other.handTotal))
print ("Dealer Wins!")
message()
#who won
def main():
cardDeck = Deck()
print ('Initial Deck: ')
print(cardDeck)
cardDeck.shuffle()
print ('Shuffled Deck: ')
print(cardDeck)
keep_playing = True
while keep_playing:
player = Player()
opponent = Player()
#give each player 2 cards, alternating
cardDeck.dealOne(player)
cardDeck.dealOne(opponent)
cardDeck.dealOne(player)
cardDeck.dealOne(opponent)
print ('Deck after giving 2 cards each')
print (cardDeck)
#show 1 faceup card for each player
showHands(player,opponent)
#start playing
playerTurn(cardDeck,player, opponent)
opponentTurn(cardDeck, opponent, player)
again = raw_input("Do you want to play again? (Y/N) : ")
keep_playing = again in "Yy"
# Reach here after dropping out of the while loop
print "\n\n-------Thank you for playing!--------\n\n"
main()
Yes, you can have one game continue from where the previous one left off. The current problem is that you call main recursively. This starts over from the beginning, shuffling a full deck, etc.
Instead, you would want a main program something like this:
def main():
cardDeck = Deck()
print ('Initial Deck: ')
print(cardDeck)
cardDeck.shuffle()
print ('Shuffled Deck: ')
print(cardDeck)
keep_playing = True
while keep_playing:
player = Player()
opponent = Player()
#give each player 2 cards, alternating
cardDeck.dealOne(player)
cardDeck.dealOne(opponent)
cardDeck.dealOne(player)
cardDeck.dealOne(opponent)
print ('Deck after giving 2 cards each')
print (cardDeck)
#show 1 faceup card for each player
showHands(player,opponent)
#start playing
playerTurn(cardDeck,player, opponent)
opponentTurn(cardDeck, opponent, player)
again = raw_input("Do you want to play again? (Y/N) : ")
keep_playing = again in "Yy"
# Reach here after dropping out of the while loop
print "\n\n-------Thank you for playing!--------\n\n"
This gets rid of your message function and the recursive call to main.
See the repl.it for a complete solution:
There are a lot of issues, here are a few of overarching themes:
If you're having to repeat yourself, you're doing it wrong:
aces = False
#IF TWO ACES
if player.hand[0].pip == "A" and player.hand[1].pip == "A":
player.hand[0].pipValue = 1
#check for aces
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
#check if an ace was drawn
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
#check for aces
if aces:
print ('You hold ' + str(player) + 'for a total of ' + str(player.handTotal))
print ("Over 21. Value of ace changed to 1")
#chanlge value of ace and hand
player.handTotal = player.handTotal - 10
for i in player.hand:
if i.pip == "A" and i.value == 11:
i.value = 1
#check for other standard aces
aces = False
for i in player.hand:
if i.pip == "A" and i.value == 11:
aces = True
Each of those is used twice... I replaced it by letting my players hand decide it's own value:
#property
def handTotal(self):
while sum(card.value for card in self.hand) > 21 and \
any(card.pip == 'Ace' and card.value == 11 for card in self.hand):
for card in self.hand:
if card.pip == 'Ace' and card.value == 11:
card.value = 1
break
return sum(card.value for card in self.hand)
The #property decorator forces it to recalculate every time someone asks for the handTotal.
Telling main you want to keep playing
You need to return a value all the way back to main, in some way. Because you already have some global state variables, I added playing = True, then:
def message():
global playing
again = input("Do you want to play again? (Y/N) : ")
if again.lower() == "n":
print("\n\n-------Thank you for playing!--------\n\n")
playing = False
return True # Tells `turn()` the game is over

Python 3 IndentationError

In spite of seeing a lot of posts about the python indentation error and trying out a lot of solutions, I still get this error:
import random
import copy
import sys
the_board = [" "]*10
def printboard(board):
print(board[7] + " " + "|" + board[8] + " " + "|" + board[9])
print("--------")
print(board[4] + " " + "|" + board[5] + " " + "|" + board[6])
print("--------")
print(board[1] + " " + "|" + board[2] + " " + "|" + board[3])
def choose_player():
while True:
player = input("What do you want to be; X or O?")
if player == "X":
print("You chose X")
comp = "O"
break
elif player == "O":
print("You chose O")
comp = "X"
break
else:
print("Invalid Selection")
continue
return [player, comp]
def virtual_toss():
print("Tossing to see who goes first.....")
x = random.randint(0,1)
if x== 0:
print("AI goes first")
move = "comp"
if x == 1:
print("Human goes first")
move = "hum"
return move
def win(board,le):
if (board[7] == le and board[8] == le and board[9]==le) or (board[4] == le and board[5]==le and board[6] == le)or (board[1] == le and board[2]==le and board[3] == le)or (board[7] == le and board[5]==le and board[3] == le)or (board[9] == le and board[5]==le and board[1] == le)or (board[7] == le and board[4]==le and board[1] == le)or (board[8] == le and board[5]==le and board[2] == le)or (board[9] == le and board[6]==le and board[3] == le):
return True
else:
return False
def make_move(board,number,symbol):
board[number] = symbol
def board_full(board):
count = 0
for item in board:
if item in ["X","O"]:
count+= 1
if count ==9 :
return True
else:
return False
def valid_move(board,num):
if board[num] == " ":
return True
else:
return False
def player_move(board):
number = int(input("Enter the number"))
return number
def copy_board(board):
copied_board = copy.copy(board)
return copied_board
def check_corner(board):
if (board[7] == " ") or (board[9] == " ") or (board[1] == " ") or (board[3] == " "):
return True
else:
return False
def check_center(board):
if (board[5] == " "):
return True
else:
return False
while True:
count = 0
loop_break = 0
print("welcome to TIC TAC TOE")
pla,comp = choose_player()
turn = virtual_toss()
while True:
printboard(the_board)
if turn == "hum":
if board_full() == True:
again = input ("Game is a tie. Want to try again? Y for yes and N for No")
if again == "Y":
loop_break = 6
break
else:
system.exit()
if loop_break == 6:
continue
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
else:
turn = "comp"
printboard(the_board)
continue
else:
if board_full() == True:
again = input ("Game is a tie. Want to try again? Y for yes and N for No")
if again == "Y":
loop_break = 6
break
else:
system.exit()
if loop_break = 6:
continue
copy_board(the_board)
for i in range(0,9):
make_move(copied_board,i,pla)
if(win(copied_board,pla) == True):
make_move(the_board,comp)
turn = "hum"
loop_break = 1
break
else:
continue
if loop_break = 1:
continue
if (check_corner(the_board) == True) or (check_center(the_board)==True):
for i in [7,9,1,3,5]:
if(valid_move(copied_board,i)==True):
make_move(copied_board,i,comp)
if(win(copied_board,comp)==True):
make_move(the_board,i,comp)
print("The AI beat you")
loop_break = 2
count = 1
break
else:
make_move(the_board,i,comp)
turn = "hum"
loop_break = 3
break
if loop_break == 2:
break
elif loop_break == 3:
continue
else:
for i in [8,4,6,2]:
if(valid_move(copied_board,i)==True):
make_move(copied_board,i,comp)
if(win(copied_board,comp)):
make_move(the_board,i,comp)
print("The AI beat you")
count = 1
loop_break = 4
break
else:
make_move(the_board,i,comp)
turn = "hum"
loop_break = 5
break
if loop_break == 4:
break
elif loop_break == 5:
continue
if count == 1:
again = input("Would you like to play again? y/n")
if again == "y":
continue
else:
system.exit()
I know that this is quite a long code, but I will point out the particular area where the error lies. You see, I am getting the following error message:
Traceback (most recent call last):
File "python", line 106
if (win(the_board,pla) == True):
^
IndentationError: unindent does not match any outer indentation level
More specifically, this part of the code:
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
Any help? I cannot get the code to work by any means!!
Try unindenting the previous seven lines of code by one level (the code in that while loop). This should make the indents work correctly. Also, it seems that there is an extra space before the if statement that is causing you errors. Remove this space as well. This would make that part of the code like this:
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
You need to indent the block under while (True): consistently. E.g.:
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
else:
turn = "comp"
printboard(the_board)
continue
The problem is, the if statement is one indentation back from the rest of the code. You want to align all the code and the error should go away.
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break

Categories

Resources