HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Command-line blackjack for up to 6 players in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
lineplayersforpythoncommandblackjack

Problem

Here is command-line blackjack for up to 6 players (not including dealer). Would love any and all feedback!

```
"""
This is the code for a blackjack game.
"""

from random import shuffle
from time import sleep

def get_valid_response(query, valid_responses):
response = raw_input(query)
if response.lower() not in [r.lower() for r in valid_responses]:
print "That is not a valid response. Try again."
response = get_valid_response(query, valid_responses)

return response

class Player:
def __init__(self, name, game):
self.cards = []
self.name = name
self.busted = False
self.game = game

def receive_card(self, card, is_face_up = True):
card.is_face_up = is_face_up
self.cards.append(card)

def cards_string(self):
return [card.to_string() for card in self.cards]

def raw_points(self):
return sum([card.points() for card in self.cards])

def points(self):
total = self.raw_points()
# Check if we should reduce the value of aces
if total > 21:
ace_indices = [index for index, card in enumerate(self.cards) if card.rank == 'A']
for ace_index in ace_indices:
self.cards[ace_index].secondary_value = True
if self.raw_points() <= 21:
return self.raw_points()

return total

def ask_for_decision(self):
return get_valid_response("\nAttention {}!\nYou have {}. This totals {} points.\nWould you like to 'hit' or 'stay'? ".
format(self.name, self.cards_string(), self.points()),
["hit", "stay"])

def bust(self):
print "\n{}, you have busted with {}. This totals {}!\n".format(self.name, self.cards_string(), self.points())
self.busted = True

def hit(self):
self.game.deck.deal_card_to(self)
if self.points() <= 21:
self.play()
else:

Solution

Code gives good overall impression.

Some micro-level suggestions:

  • get rid of recursion in get_valid_response: all that will be safer with while-loop and break, usual pattern in Python



  • remove [] in sum: generator will work just fine unless you are using very old Python.



  • it's better to inherit from object. Your code uses classic classes at the moment.



  • conversions to lower case at the border (near the input) will make your code cleaner.



  • there are some PEP8 code style violations (eg, spaces around keyword argument) - check with a tool



Regarding object decomposition, classes, especially the Game class, mixes logic and presentation. But may be it's not a problem if the game is not intended to be part of a larger system, where other UI modalities will be used.

To decouple logic and presentation, well-known design approaches can be used, for example (but not necessarily!), MVC or similar. In short and oversimplifying, there will be VC-classes, dedicated to user interfaces (input/output), and M-classes, holding the model - mostly current classes, stripped of prints/inputs and representation concerns. You can also go four-tier (if it does not feel as overkill): presentation, business logic, data access, database. Specific choice depends on the larger system you think your software will be part of. It may well be that 2 layers are enough for your purposes for now (presentation + the rest).

For concrete example, instead of doing print, call i/o class methods, concerned with game communication. This way, specific way your code does it will not be tightly coupled with the rest of the game logic. You will be able to do, say, client-server for your game. Of course, which way communication is initiated, who pushes and who pulls data, will require some thinking. May well be in your architecture, that UI will call underlying game model objects.

Context

StackExchange Code Review Q#148900, answer score: 3

Revisions (0)

No revisions yet.