patternpythonMinor
OO Blackjack game design
Viewed 0 times
designgameblackjack
Problem
I have set up
I haven't ran pyflakes or a PEP8 checker on it yet, so keep that in mind!
main.py
game.py
```
from dealer import Dealer
from player import Player
from hand import Hand
from card import Card
from deck import Deck, Clubs, Diamonds, Hearts, Spades
class Game:
"""Information about the game.
Responsibilities:
* Check for winner
* Handles betting and bankroll
* Resets the game and hands
Collaborators
* Checks the player and dealer's hand amounts and compares them
"""
def __init__(self, dealer, player, deck):
self.dealer = dealer
self.player = player
sel
card, deck, hand, player, dealer, and game classes. The game class is there to keep a lot of the logic out of the interface (main.py). Let me know any thoughts on that.I haven't ran pyflakes or a PEP8 checker on it yet, so keep that in mind!
main.py
from game import Game
from card import Card
from deck import Deck
from hand import Hand
from player import Player
from dealer import Dealer
name = input("Please enter your name: ")
dealer = Dealer()
player = Player(name)
deck = Deck()
game = Game(dealer, player, deck)
game_loop = True
while game_loop:
game.new_turn()
print("You have {} dollars".format(game.player.stack))
print("How much would you like to bet?")
game.place_bet(input("> "))
game.dealer.show_hand()
game.player.show_hand()
hit = game.hit_or_stand()
while hit and not game.player.hand.bust():
game.player.hit(game.deck)
game.player.show_hand()
if game.player.hand.best_hand 21:
print("Dealer busts!, you win!")
game.player.stack += game.pot * 2
else:
game.check_for_winner(game.dealer, game.player)
else:
if dealer.hand.best_hand == 21:
print("Dealer has blackjack! You lose!")
else:
print("Your hand is over 21, you lose!!")
if player.stack < 1:
print("You are out of money! Game over!")
break
game_loop = game.play_again()game.py
```
from dealer import Dealer
from player import Player
from hand import Hand
from card import Card
from deck import Deck, Clubs, Diamonds, Hearts, Spades
class Game:
"""Information about the game.
Responsibilities:
* Check for winner
* Handles betting and bankroll
* Resets the game and hands
Collaborators
* Checks the player and dealer's hand amounts and compares them
"""
def __init__(self, dealer, player, deck):
self.dealer = dealer
self.player = player
sel
Solution
I haven't ran pyflakes or a PEP8 checker on it yet, so keep that in mind!
Uhm, why haven't you? That's a rhetorical question. You should have run those,
and your statement of having not run doesn't help the reviewer in anyway,
except that one might think you're deliberately careless.
Strange things
This is a bit odd:
The
Taking a quick look at
The method sometimes returns a string, sometimes prints a string.
You should make it behave consistently.
It's probably a typo, you meant to
But even so,
this is not good:
the printing of game results is split in two places:
It would be better to keep
having the logic in one place.
Also, the last
In
Why call
Naming
It's especially bad because in programming the term "stack" evokes a specific data structure, making the code misleading and harder to read.
Even if "stack" is the correct and single best obvious term in Black Jack (I don't know), I suggest to find something else.
This is a bit confusing:
"show" and "reveal" are synonyms, which makes these statements confusing.
It's not great when I have to open the implementation of two functions to see the difference of what they do.
It's really a new game.
But that would be misleading too,
because a method starting with "new" usually returns a new instance of something.
Other things
I know this is Black Jack and the goal to reach must be 21,
but it would be fun sometimes to mess with the system and see how the game dynamics change if we use a different number, like 31.
To make such future extensions easier,
I'd put 21 in a global constant, and call it for example
In any case I think it's a good natural reflex to develop to always replace repeated things with constant variables.
Uhm, why haven't you? That's a rhetorical question. You should have run those,
and your statement of having not run doesn't help the reviewer in anyway,
except that one might think you're deliberately careless.
Strange things
This is a bit odd:
if game.dealer.hand.best_hand > 21:
print("Dealer busts!, you win!")
game.player.stack += game.pot * 2
else:
game.check_for_winner(game.dealer, game.player)The
if branch prints something, the else branch doesn't...Taking a quick look at
game.check_for_winner:def check_for_winner(self, dealer, player):
if self.player.hand.best_hand < self.dealer.hand.best_hand:
return("You Lose")
elif self.dealer.hand.best_hand < self.player.hand.best_hand:
print("You Win!")
self.player.stack += self.pot * 2
elif self.dealer.hand.best_hand == self.player.hand.best_hand:
print("Push!")
self.player.stack += self.potThe method sometimes returns a string, sometimes prints a string.
You should make it behave consistently.
It's probably a typo, you meant to
print instead of return.But even so,
this is not good:
the printing of game results is split in two places:
main and game.It would be better to keep
main fully in charge of that,having the logic in one place.
Also, the last
elif should really be a simple else.In
game.place_bet this is really strange:try:
int(amount)
if int(amount) <= self.player.stack:
self.player.stack -= int(amount)
self.pot += int(amount)
else:
self.place_bet(input("Not enough funds! You have {} dollars. "
"Place a bet: ".format(self.player.stack)))
except ValueError:
self.place_bet(input("Place a bet: "))Why call
int(amount) multiple times, re-parsing a string to integer multiple times? Better do it once and save in a variable.Naming
stack is a strange name for a pot or bet. It's especially bad because in programming the term "stack" evokes a specific data structure, making the code misleading and harder to read.
Even if "stack" is the correct and single best obvious term in Black Jack (I don't know), I suggest to find something else.
This is a bit confusing:
game.dealer.reveal_hand()
game.player.show_hand()"show" and "reveal" are synonyms, which makes these statements confusing.
It's not great when I have to open the implementation of two functions to see the difference of what they do.
new_turn in game can be misleading.It's really a new game.
But that would be misleading too,
because a method starting with "new" usually returns a new instance of something.
reset_game would be better.Other things
I know this is Black Jack and the goal to reach must be 21,
but it would be fun sometimes to mess with the system and see how the game dynamics change if we use a different number, like 31.
To make such future extensions easier,
I'd put 21 in a global constant, and call it for example
BLACKJACK.In any case I think it's a good natural reflex to develop to always replace repeated things with constant variables.
Code Snippets
if game.dealer.hand.best_hand > 21:
print("Dealer busts!, you win!")
game.player.stack += game.pot * 2
else:
game.check_for_winner(game.dealer, game.player)def check_for_winner(self, dealer, player):
if self.player.hand.best_hand < self.dealer.hand.best_hand:
return("You Lose")
elif self.dealer.hand.best_hand < self.player.hand.best_hand:
print("You Win!")
self.player.stack += self.pot * 2
elif self.dealer.hand.best_hand == self.player.hand.best_hand:
print("Push!")
self.player.stack += self.pottry:
int(amount)
if int(amount) <= self.player.stack:
self.player.stack -= int(amount)
self.pot += int(amount)
else:
self.place_bet(input("Not enough funds! You have {} dollars. "
"Place a bet: ".format(self.player.stack)))
except ValueError:
self.place_bet(input("Place a bet: "))game.dealer.reveal_hand()
game.player.show_hand()Context
StackExchange Code Review Q#78515, answer score: 4
Revisions (0)
No revisions yet.