我设置了card、deck、hand、player、dealer和game类。游戏类的存在是为了将大量的逻辑排除在接口(main.py)之外。告诉我对此有什么想法。
我还没有运行吡咯烷酮或PEP8检查,所以请记住这一点!
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:
hit = game.hit_or_stand() #player can't bust
if player.hand.best_hand <= 21 and dealer.hand.best_hand != 21:
game.dealer.play_out_hand(game.deck)
game.dealer.reveal_hand()
game.player.show_hand()
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)
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()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
self.deck = deck
self.pot = 0
def play_again(self):
choice = input('Press "p" to play again or "q" to quit: ').lower()
return choice == 'p'
def hit_or_stand(self):
choice = input('Press "h" to Hit, or "s" to stand: ').lower()
return choice == 'h'
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.pot
def new_turn(self):
self.dealer.hand.reset_hand()
self.player.hand.reset_hand()
self.deck = Deck()
self.deck.shuffle()
self.dealer.hand.new_hand(self.deck)
self.player.hand.new_hand(self.deck)
self.pot = 0
def place_bet(self, amount):
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: "))class Player:
"""The player of the blackjack game.
Responsibilities:
* Holds a hand
* Can bet
* Can hit
* Can display hand
Collaborators:
*Uses a hand of cards
"""
def __init__(self, name, stack = 100, hand = None):
if hand is None:
hand = Hand([])
self.name = name
self.hand = hand
self.cards = hand.hand
self.stack = stack
def hit(self, deck):
self.hand.draw(deck)
def bet(self, amount):
chips = self.stack
new_chips = chips - amount
self.stack = new_chips
return self.stack
def show_hand(self):
print("{name}'s hand: {hand} ({value})".format(name = self.name,
hand = self.hand,
value = self.hand.best_hand))from hand import Hand
from player import Player
class Dealer():
"""The dealer of the blackjack game. The dealer doesn't actually deal
cards, but holds a hand for the purpose of the game.
Responsibilities:
* Holds a Hand of Cards
* Hits until 17 or more, if over 21 returns bust
* Has facedown card
Collaborators
* Gets a hand of cards from the deck
"""
def __init__(self, hand = None):
if hand == None:
hand = Hand([])
self.name = "Dealer"
self.hand = hand
def hit(self, deck):
self.hand.draw(deck)
def play_out_hand(self, deck):
while self.hand.soft_total < 17:
if self.hand.hard_total >= 17 and self.hand.hard_total <= 21:
return self.hand.hard_total
break
self.hand.draw(deck)
return self.hand.soft_total
def show_hand(self):
print("{name}'s hand: XX {hand}".format(name = self.name, hand = self.hand.hand[1]))
def reveal_hand(self):
print("{name}'s hand: {hand} ({value})".format(name = self.name,
hand = self.hand,
value = self.hand.best_hand))from card import Card
from random import shuffle
#assign unicode chararcters for each suit
Clubs, Diamonds, Hearts, Spades = u'\u2663', u'\u2666', u'\u2665', u'\u2660'
SUITS = (Clubs, Diamonds, Hearts, Spades)
RANKS = (2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A')
class Deck:
"""A playing card deck.
Responsibilities:
* Can hold cards.
* New deck should have all 52 cards.
* Should allow others to draw cards.
* Should be able to reshuffle itself
* Should be able to report its current size
Collaborators:
* Can hold cards.
* Can be put into shoe for dealing and shuffling
"""
def __init__(self):
self._cards = [Card(rank, suit)
for rank in RANKS
for suit in SUITS]
def draw(self):
"""Take a card off the top of the deck and return it"""
return self._cards.pop()
def shuffle(self):
"""Shuffles cards in the deck"""
shuffle(self._cards)
return self
def __eq__(self, other):
return self._cards == other._cards
def __len__(self):
return len(self._cards)
def __str__(self):
deck_list = [str(card) for card in self._cards]
return ", ".join(deck_list)
def __repr__(self):
return self.__str__()class Hand:
"""An assortment of cards
Responsibilitites:
* Can hold x cards
* Has a hard or soft total for hand, aces depend on hand
* Can add cards to hand
* Check if hand is busted (over 21)
Collaborators:
* A Hand is made up of Cards
* A Player and Dealer can hold a hand
* The shoe can deal to the hand
"""
def __init__(self, hand):
self.hand = hand
@property
def hard_total(self):
hard_total = 0
for card in self.hand:
if type(card.rank) == str:
if card.rank == 'A':
hard_total += 11
else:
hard_total += 10
else:
hard_total += card.rank
return hard_total
@property
def soft_total(self):
soft_total = 0
for card in self.hand:
if type(card.rank) == str:
if card.rank == 'A':
soft_total += 1
else:
soft_total += 10
else:
soft_total += card.rank
return soft_total
@property
def best_hand(self):
if self.hard_total > 21:
return int(self.soft_total)
else:
return int(self.hard_total)
def bust(self):
if self.soft_total > 21:
return True
else:
return False
def draw(self, deck):
card = deck.draw()
self.hand.append(card)
def new_hand(self, deck):
self.draw(deck)
self.draw(deck)
def reset_hand(self):
self.hand = []
print(self.hand)
def __str__(self):
hand_list = [str(card) for card in self.hand]
return str(', '.join(hand_list))
def __repr__(self):
return self.__str__()from collections import namedtuple
"""A playing card.
Responsibilities:
* Has a rank and suit
Collaborators:
* Collected into a Deck
* Collected into a Hand for each player and a Hand for the dealer.
"""
class Card(namedtuple('card', ['rank', 'suit'])):
__memory__ = () #assure instance is stored as a tuple in memory
def __str__(self):
return "{}{}".format(self.rank, self.suit)
def __repr__(self):
return self.__str__()发布于 2015-01-25 08:38:17
我还没有运行吡咯烷酮或PEP8检查,所以请记住这一点!
嗯,你为什么没有呢?这是个反问句。你应该运行这些程序,而你关于没有运行的声明无论如何也无助于评审者,除非有人认为你是故意的粗心。
这有点奇怪:
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)
if分支打印一些东西,else分支不.快速查看一下game.check_for_winner:
def check_for_winner(自我,经销商,玩家):如果self.player.hand.best_hand < self.dealer.hand.best_hand:返回(“你输了”) elif self.dealer.hand.best_hand < self.player.hand.best_hand:打印(“你赢了!”)self.player.stack += self.pot *2 elif self.dealer.hand.best_hand == self.player.hand.best_hand: print("Push!")self.player.stack += self.pot
该方法有时返回字符串,有时打印字符串。你应该让它表现得始终如一。这可能是一个错误,您的意思是print而不是return。但即使如此,这也不太好:游戏结果的打印分为两部分:main和game。最好让main完全负责这件事,把逻辑放在一个地方。
另外,最后一个elif应该是一个简单的else。
在game.place_bet中,这真的很奇怪:
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: "))
为什么多次调用int(amount),多次将字符串解析为整数?最好只做一次并保存在一个变量中。
stack是一个奇怪的名字,一个锅或赌注。这尤其糟糕,因为在编程过程中,“堆栈”一词会产生特定的数据结构,从而使代码具有误导性和难以阅读的功能。即使“堆栈”在“黑杰克”(我不知道)中是正确且最明显的术语,我还是建议找一些其他的词。
这有点让人困惑:
game.dealer.reveal\_hand() game.player.show\_hand()
“显示”和“揭示”是同义词,这使这些陈述令人困惑。当我必须打开两个函数的实现来了解它们的不同之处时,这是不太好的。
new_turn in game可能会产生误导。这真的是个新游戏。但这也会误导人,因为以" new“开头的方法通常会返回某物的新实例。reset_game会更好。
我知道这是黑杰克,目标必须是21,但有时候如果我们用一个不同的数字,比如31,扰乱系统,看看游戏动态如何变化,那就很有趣了。为了使将来的扩展更容易,我将21放入一个全局常量中,并将其命名为BLACKJACK。在任何情况下,我认为这是一个很好的自然反应,发展总是用常数变量代替重复的事物。
https://codereview.stackexchange.com/questions/78515
复制相似问题