I have tried to create a BLACKJACK game using python (actually I'm learning python). Currently I have not setup bet command (that is written in my Account class). I only takes name from my Account class.
I have a main file : blackjack.py and two classes in files : deckofcards.py, account.py I am only accessing name from account class, so I wont be putting that long mess here.
blackjack.py :
from account import Account
player = Account('kalaLokia')
cards = DeckOfCards()
play = False
playershand = []
dealershand = []
action = ''
blackjack = False
def showCards(items, name):
'''
Shows {name}'s cards and hand value
'''
print(f"{name}'s hand: ")
print(f"\t{' - '.join(items)}")
print(f"Hand value: {cards.handValue(items)}")
def bust(hand):
'''
Whether a someone has busted or not
'''
if(cards.handValue(hand) > 21):
return True
return False
def dealersMove():
'''
Dealers move: executes when player calls "stand"
Dealer perform hit until he gets bust, wins or his hand value becomes >= 17
When hand value is >17 and players has greater value, dealer loses ;-)
'''
global blackjack
if(cards.handValue(dealershand) == 21):
print('Dealer got a BLACKJACK')
print('Dealer WINS')
return
elif(blackjack):
print(f'{player.name} got a BLACKJACK')
print(f'{player.name} WINS')
blackjack=False
return
while(not bust(dealershand)):
if(cards.handValue(dealershand) > cards.handValue(playershand)):
print('Dealer WINS')
showCards(dealershand, 'Dealer')
break
elif(cards.handValue(dealershand) == cards.handValue(playershand)):
print("It's a TIE!!\n Dealer WINS")
break
elif(cards.handValue(dealershand) > 17):
print(f'Dealer loses\n{player.name} has WON.')
print(f'{cards.handValue(playershand)} > {cards.handValue(dealershand)}')
break
dealershand.append(cards.hit())
else:
print(f'Dealer busts! \n{player.name} has WON the game.')
def start():
'''
The actiona that can be performed
'''
global blackjack
if(cards.handValue(playershand) == 21):
blackjack = True
dealersMove()
return
while(not bust(playershand)):
action = input(
f"{player.name}'s turn: Do you want to hit or stand ? ").lower()
if(action == 'hit'):
playershand.append(cards.hit())
showCards(playershand, player.name)
elif(action == 'stand'):
dealersMove()
break
else:
print('Please enter a valid action !')
else:
print(f'{player.name} has been BUSTED')
if __name__ == "__main__":
print(f'Hello {player.name}, Welcome to BlackJack Game')
# Tell game rules here, may be
response = input('Do you want to start the game (Y/n)? ').lower()
if(response != 'y'):
play = False
print('You have been exited the game')
else:
play = True
# Ask for bet amount later
while(play):
cards = DeckOfCards()
cards.shuffle()
print('Cards on the table is now shuffled')
playershand = list(cards.initiate())
dealershand = list(cards.initiate())
print(
f"{player.name}'s hand:\n {playershand[0]} - {playershand[1]}\nHand value: {cards.handValue(playershand)}\n")
print(f"Dealer's hand:\n {dealershand[0]} - ?\n")
start()
if(input('Do you want to play again (Y/n)?').lower() != 'y'):
print('The End')
play = False
deckofcards.py :
import random
class DeckOfCards():
'''
All talks here is about cards
'''
cards = {'A':11,'K':10,'Q':10,'J':10,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10}
def __init__(self):
'''
Initialize deck of cards
'''
self.deck = list(self.cards.keys())*4
def shuffle(self):
'''
Simply shuffles the deck of cards
'''
return random.shuffle(self.deck)
def handValue(self, hand):
'''
Calculates and returns the hand value, expecting a string value to be feeded.
'''
result = 0
for element in hand:
result = result + self.cards[element]
while('A' in hand and result > 21):
if(hand[0]=='A'):
result = result - 10
# Somehow this hand.pop is poping out from main value itself. Why ???
hand.pop(0)
if(hand == []):
break
return result
def hit(self):
'''
Pop out and returns the last card in the deck
'''
return self.deck.pop()
def initiate(self):
'''
Pop out 2 cards from the deck and return as a tuple
'''
return (self.deck.pop(), self.deck.pop() )
Issue:
When I have an ACE in my hand and my hand value is greater than 21, the while condition executes in the handValue
function (which is in DeckofCards class) as it is. Problem is, after that while
condition executes, playershand
(declared in main file) I just passed to this handValue
function gets empty. That is the hand.pop(0)
actually seems popping out value from main object playershand
itself (It seems me so).
When I press a hit after that, I get a single new card, all other cards are got popped out. I don't understand why it is so.
On hit(user enter hit) : actually I am passing playershand
(cards on the player hand, it's a list) to function showCards
(which is also in the main file) where it takes it as argument items and pass it to handValue
function in the class DeckOfCards
.
So why is it happening? even though I am passing playershand as an argument to other functions, how pop() function affecting playershand which has only access to hand object in the handValue class ?
I have my complete code in github repo to test out, the files in folder blackjack