我正在尝试编写我的第一个Python项目blackjack。建议我将每个类及其方法编写在不同的文件中,以便代码更易于管理。我将代码分成更小的文件并使用 import 语句。
当我运行代码时,我收到以下错误消息:
缺少 1 个必需的位置参数。Chips.place_bet()
。self
我认为
self
是,请原谅双关语,不言自明。我不需要为 self
赋值。我想知道这是否是导入问题。
我正在尝试激活我的
place_bet
功能,以便我可以要求用户输入下注的筹码数量。谁能告诉我如何做到这一点?
我的代码分布在这些文件中:
import random
from player import Player
from hand import Hand
from chips import Chips
from deck import Deck
from card import Card
# import helper_functions
# Blackjack/
# ├── app/
# │ ├── card.py
# │ ├── chips.py
# │ ├── deck.py
# │ ├── hand.py
# │ ├── player.py
# │ ├── main.py
# │ ├── helper_functions.py
# Gameplay and Outline of Project
# Welcome message and rules
print("Welcome to Blackjack! The rules for blackjack can be found here. https://www.youtube.com/watch?v=PljDuynF-j0")
print("The object of this blackjack game is to make it to 100 chips. You will start with 25 chips.")
# Establish player name
print("Please insert your player name: ")
player_name = input()
print('Please insert your player name ' + player_name)
print("Lets get started" + player_name + "please place your bet!")
# Place the bets BEFORE the cards are dealt. Pure risk.
place_bet()
# . Deal 2 cards to user and dealer
# . print a message explaining the total hand value of the user. ask player to hit/stay?
# . If the player busts print player busts. if the player is under 21 ask them again to hit or stay.
# . If stay, move on to dealers turn.
# . If the hand is less than 17 have him hit, if it is over 17 have the dealer stay.
# . If the dealer stays print the dealers hand total. IF the dealers hand total is greater than the player the dealer wins.
# . if the dealer busts print the message he busts and the player wins and the player gets the chips.
# 1. Ask dealer to hit/stay?
# 2. If hit, deal 2 cards
# 3. If broke or blackjack deliver message
# 4. If stay, compare hands
# 5. If users hand is closer to 21, (user wins)
# 6. If dealers hand is closer to 21, (user loses)
def main():
player = Player('strikeouts27', 500,)
dealer = Player()
player_chips = Chips()
dealer_chips = Chips()
cards = Card()
deck = Deck()
if __name__ == '__main__':
main()
class Card:
"""Card class"""
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __repr__(self):
return f'{self.__class__.__name__}(rank={self.rank}, suit={self.suit})'
class Chips:
"""Chip class manages chip balance"""
def __init__(self, balance):
self.balance = balance
self.bet = 0
def place_bet(self):
while True:
total = input(f'How much do you bet? (1-{self.balance}):\n> ')
# return True if a digit string. false otherwise. hover over the method for visual studio code to show you.
if not total.isdigit():
continue
total = int(total)
if total > self.balance:
print('You do not have enough')
continue
return total
def add_value(self, value):
"""Add value to chip total"""
self.balance += value
def deduct_value(self, value):
"""Deduct value from chip total"""
self.balance -= value
def display_chips(player, dealer):
print(f'player chips: ${player.chips.balance}')
print(f'dealer chips: ${dealer.chips.balance}')
# Displays player and dealer chip count
class Card:
#"""Card class"""
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __repr__(self):
return f'{self.__class__.__name__}(rank={self.rank}, suit={self.suit})'
class Deck:
"""Deck class, represents 52 cards"""
def __init__(self):
self.ranks = [str(n) for n in range(2, 11)] + list('jqka')
self.suits = ["hearts", "diamonds", "clubs", "spades"]
self.cards = [Card(rank, suit)
for suit in self.suits for rank in self.ranks]
random.shuffle(self.cards)
# dunder method rewrites what pythons default method to show better information about itself.
def __repr__(self):
return f'{self.__class__.__name__}({self.cards})'
def __len__(self):
return len(self.cards)
def __getitem__(self, item):
return self.cards[item]
def shuffle(self):
"""shuffles deck of cards"""
random.shuffle(self.cards)
class Hand:
"""Hand class to hold the cards for the player and the dealer"""
def __init__(self, cards=None):
self.cards = [] if cards is None else cards
self.value = 0
self.aces = 0
def add_to_hand(self, card):
"""Adds a cards to self.cards."""
self.cards.append(card)
def display_hand(self):
hashtable = {'hearts': 9829, 'diamonds': 9830,
'spades': 9824, 'clubs': 9827}
return [[i.rank, chr(hashtable.get(i.suit))] for i in self.cards]
def display_hand_two(player, dealer):
# Displays player and dealer hand
print(
f'players Hand: {player.hand.display_hand()} --> total {player.total}')
print(
f'dealer Hand: {dealer.hand.display_hand()} --> total {dealer.total}')
class Player:
"""Player class"""
def __init__(self, name, chips, hand):
self.name = name
self.chips = chips
self.hand = hand
@property
def total(self):
"""Returns the value of the cards. Face cards equal 10, aces can equal
11 or 1, this function picks best case"""
value = 0
aces_count = 0
# Each card is a tuple in a list:
cards = [card for card in self.hand.cards]
for card in cards:
if card.rank == 'a':
aces_count += 1
elif card.rank in 'kqj':
# Face cards are worth 10 points
value += 10
else:
# Numbered cards are worth their value.
value += int(card.rank)
# Add value of aces - 1 per ace
value += aces_count
for i in range(aces_count):
# If another 10 can be added,then do it!
if value + 10 <= 21:
value += 10
return value
@staticmethod
def get_move():
"""returns player choice to hit or stand"""
move = input('>>> (H)it, (S)tand ?:\n> ').lower()
return move
def main():
# Instantiate Deck
deck = Deck()
# shuffle deck
deck.shuffle()
# Instantiate player and dealer chips
player_chips = Chips(500)
dealer_chips = Chips(500)
while True:
# Instantiate player and dealer hand
player_hand = Hand()
dealer_hand = Hand()
# Instantiate player and dealer
player = Player('seraph', player_chips, player_hand)
dealer = Player('codecademy', dealer_chips, dealer_hand)
# Check if player has enough money
if player_chips.balance <= 0:
print('need more money')
# Then place bet
bet = player_chips.place_bet()
# player draws 2 cards
player.hand.add_to_hand(deck.cards.pop())
player.hand.add_to_hand(deck.cards.pop())
# Dealer draws cards
dealer.hand.add_to_hand(deck.cards.pop())
dealer.hand.add_to_hand(deck.cards.pop())
# display player ann dealers hand
display_hand(player, dealer)
# Begin game
while True:
if player.total > 21:
break
# Get the player's moves
player_move = player.get_move()
if player_move == 'h':
new_card = deck.cards.pop()
rank, suit = new_card.rank, new_card.suit
player.hand.add_to_hand(new_card)
print(f'You drew a {rank} of {suit}')
display_hand(player, dealer)
if player.total > 21:
print('You busted...')
# Busted
continue
if player_move == 's':
break
# Get the dealer's moves
if dealer.total <= 21 and not player.total > 21:
while dealer.total <= 17:
print('Dealer hits...')
new_card = deck.cards.pop()
dealer.hand.add_to_hand(new_card)
if dealer.total > 21:
break
if dealer.total > 21:
print('Dealer Busted - You win!')
display_hand(player, dealer)
player.chips.add_value(bet)
dealer.chips.deduct_value(bet)
display_chips(player, dealer)
elif player.total > 21 or player.total < dealer.total:
print('You lost!')
display_hand(player, dealer)
player.chips.deduct_value(bet)
dealer.chips.add_value(bet)
display_chips(player, dealer)
elif player.total == dealer.total:
print("It's a tie! Money is returned")
if __name__ == '__main__':
main()
几个问题:
文件
class.py
是多余的。它没有被导入,只定义了一个已经在card.py
中定义的类。
有两个
main
函数定义。一入blackjack.py
,一入player.py
。第一个定义了玩家“strikeouts27”,而另一个定义了“seraph”、“codecademy”。第二个似乎更发达,并且使用的内容比player.py
中的内容更多,因此实际上应该将其移至blackjack.py
中。
与上一点相关:
blackjack.py
具有在任何函数之外执行的代码。这与将驱动程序代码放入函数中的模式相反 main
。最好将所有相关驱动程序代码移至位于 main
中的一个 blackjack.py
函数内。但是,该代码看起来还没有完成,并且 main
中已经存在的代码更加成熟。我想你只需要main
(较大的)中的代码。
与上一点相关:
blackhack.py
中的代码调用了一个未定义的函数place_bet
。有一个具有该名称的方法,但没有具有该名称的独立函数。为了调用该方法,您首先需要一个 Chips
的实例,所以就像我在上一个项目符号中提到的那样,我建议删除此代码,包括在那里创建的 input
。也许您只是想保留其中的介绍性 print
陈述,并将其移至 main
。
random
在deck.py
中使用,但在blackjack.py
中导入。如果您将该 deck.py
语句移至 import
文件,这将使 deck.py
更加独立。
display_hand_two
不应该是 Hand
类的 方法。它甚至不需要
self
类型的 Hand
参数。相反,这应该是 blackjack.py
中的一个独立函数。
在
main
中,您有多个像display_hand(player, dealer)
这样的调用,但display_hand
不是一个独立的函数,而是一个方法。您真正想做的是调用 display_hand_two(player, dealer)
,要使其工作,您必须将 display_hand_two
设为独立函数,如上一个要点中所述。
如果您实施所有这些更改,您的代码将运行。