snippetpythonMinor
Implement Blackjack in Python with OOP
Viewed 0 times
implementwithpythonoopblackjack
Problem
I feel the best way to learn is practice. I have written a simple Blackjack game in Python which supports multiple-players and functionality like Hit, Stand, Surrender, Split and Double_Down. I need some help to review my code, in order to remove any redundant code, simplify the implementation, and improve the code quality over all.
Please let me know your thoughts, any feedback is welcome.
```
import random
SUITS = ['Clubs', 'Spades', 'Hearts', 'Diamonds']
RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
MAX_PLAYERS = 8
MAX_BALANCE = 1000
chip_balance = 0
class Card(object):
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
if rank == 'A':
self.point = 11
elif rank in ['K', 'Q', 'J']:
self.point = 10
else:
self.point = int(rank)
self.hidden = False
def __str__(self):
if self.hidden:
return '[X]'
else:
return '[' + self.suit + ' ' + self.rank + ']'
def hide_card(self):
self.hidden = True
def reveal_card(self):
self.hidden = False
def is_ace(self):
return self.rank == 'A'
class Deck(object):
def __init__(self):
self.cards = [Card(suit, rank) for suit in SUITS for rank in RANKS]
self.shuffle()
def __str__(self):
cards_in_deck = ''
for card in self.cards:
cards_in_deck = cards_in_deck + str(card) + ' '
return cards_in_deck
def shuffle(self):
random.shuffle(self.cards)
def deal_card(self):
card = self.cards.pop(0)
return card
class Hand(object):
def __init__(self):
self.hand = []
def add_card(self, card):
self.hand.append(card)
return self.hand
def get_value(self):
aces = 0
value = 0
for card in self.hand:
if card.is_ace():
aces += 1
value += card.point
Please let me know your thoughts, any feedback is welcome.
```
import random
SUITS = ['Clubs', 'Spades', 'Hearts', 'Diamonds']
RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
MAX_PLAYERS = 8
MAX_BALANCE = 1000
chip_balance = 0
class Card(object):
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
if rank == 'A':
self.point = 11
elif rank in ['K', 'Q', 'J']:
self.point = 10
else:
self.point = int(rank)
self.hidden = False
def __str__(self):
if self.hidden:
return '[X]'
else:
return '[' + self.suit + ' ' + self.rank + ']'
def hide_card(self):
self.hidden = True
def reveal_card(self):
self.hidden = False
def is_ace(self):
return self.rank == 'A'
class Deck(object):
def __init__(self):
self.cards = [Card(suit, rank) for suit in SUITS for rank in RANKS]
self.shuffle()
def __str__(self):
cards_in_deck = ''
for card in self.cards:
cards_in_deck = cards_in_deck + str(card) + ' '
return cards_in_deck
def shuffle(self):
random.shuffle(self.cards)
def deal_card(self):
card = self.cards.pop(0)
return card
class Hand(object):
def __init__(self):
self.hand = []
def add_card(self, card):
self.hand.append(card)
return self.hand
def get_value(self):
aces = 0
value = 0
for card in self.hand:
if card.is_ace():
aces += 1
value += card.point
Solution
The code generally looks good.
The inheritance hierarchy is weird:
The difference in naming convention between properties (e.g.
For
… which also gets rid of the extra space at the end of any non-empty deck.
For
The function name
Winning double your bet for a Blackjack is unusually generous. Customarily, you only earn 1.5× your bet.
The inheritance hierarchy is weird:
Dealer is a Hand? I would rather say that a dealer has a hand. Player is a Dealer? That sounds backwards — rather, a dealer is a player.The difference in naming convention between properties (e.g.
isBust) and method calls (e.g. get_value()) is annoying. You should use the is_bust convention uniformly. I would expect card.is_ace to be a property, rather than card.is_ace().For
Deck.__str__(), you could writedef __str__(self):
return ' '.join(str(card) for card in self.cards)… which also gets rid of the extra space at the end of any non-empty deck.
Deck.deal_card() should just be return self.cards.pop(). Dealing from the start of the array requires every card to be shifted over — that's a lot of unnecessary copying.For
Hand.get_value(), you should probably use sum():def get_value(self):
value = sum(card.point for card in self.cards)
aces = sum(card.is_ace for card in self.cards)
while (value > 21) and aces:
value -= 10
aces -= 1
return valueThe function name
report() suggests that it merely prints the outcome. It's a bit surprising that it does more: it also awards the winnings. Therefore, award_winnings() would be a better name.Winning double your bet for a Blackjack is unusually generous. Customarily, you only earn 1.5× your bet.
Code Snippets
def __str__(self):
return ' '.join(str(card) for card in self.cards)def get_value(self):
value = sum(card.point for card in self.cards)
aces = sum(card.is_ace for card in self.cards)
while (value > 21) and aces:
value -= 10
aces -= 1
return valueContext
StackExchange Code Review Q#85751, answer score: 4
Revisions (0)
No revisions yet.