问题描述
我正在制作一款多人游戏二十一点,并且在获取代码(在 python 中)以向多个玩家分发独特的卡片时遇到了问题。下面的代码向所有玩家发了同一套牌。
以下是 2 个玩家的结果示例:
玩家 1 的第一张牌是红心四。 Player1 的第二张牌是九个俱乐部。 Player2 的第一张牌是红心四。 玩家 2 的第二张牌是梅花九。
我一直在审查代码并对交易卡的功能进行修改,例如通过使用 while 循环遍历每个玩家并将两张牌附加到他们的手上。然而,结果并没有什么不同。
代码如下:
"""This is a game of Blackjack."""
import random
"""Defining the attributes of the cards"""
suits = ('Hearts','Diamonds','Spades','Clubs')
ranks = ('Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace')
"""Class class must be able to understand the Suit and Rank of a card"""
class Card:
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
def __str__(self):
return self.rank + " of " + self.suit
"""Deck class must be able to:
Instantiate a new deck and hold as a list of card objects;
Shuffle a deck through a method call; and
Deal cards from the deck."""
class Deck:
def __init__(self):
self.all_cards = []
for suit in suits:
for rank in ranks:
created_card = Card(suit,rank)
self.all_cards.append(created_card)
def shuffle(self):
random.shuffle(self.all_cards)
def deal_one(self):
return self.all_cards.pop()
def __str__(self):
statement = ""
for card in self.all_cards:
statement = statement + card.rank + " of " + card.suit + "\n"
return statement
"""Hand class must be able to:
Store the hands of the player;
Compute the value of each hand"""
class Playerhand:
def __init__(self,name,hands=[[],[],[]]):
self.name = name
self.hands = hands
def num_of_hands(self):
num_of_hands = 0
for hand in self.hands:
if hand != []:
num_of_hands += 1
else:
pass
return num_of_hands
def show_first_card(self):
print("{}'s first card is {}".format(self.name,self.hands[0][0]))
print("{}'s second card is {}".format(self.name,self.hands[0][1]))
def value_of_hands(self):
value_of_hands = []
for hand in self.hands:
total_value = 0
values = {'Two':2,'Three':3,'Four':4,'Five':5,'Six':6,'Seven':7,'Eight':8,'Nine':9,'Ten':10,'Jack':10,'Queen':10,'King':10,'Ace':11}
check_for_aces = []
for card in hand:
if card.suit == 'Ace':
check_for_aces.append('Ace')
else:
pass
for card in hand:
total_value = total_value + values[card.rank]
for item in range(0,len(check_for_aces)):
if total_value > 21:
total_value = total_value - 10
else:
pass
value_of_hands.append(total_value)
return value_of_hands
"""Pre-game:
Asking for the number of players to CREATE A LIST OF PLAYERS ['Dealer','P1','P2',etc.] and a DICTIONARY OF WAGERS {"P1": $X,"P2": $Y,etc.}"""
def number_of_players():
number_of_players = input("How many players are we expecting? Please enter 1 to 7: ")
while number_of_players.isdigit() == False or int(number_of_players) not in range(1,8):
number_of_players = input("Only accepting integer values between 1 to 7. Please enter 1 to 7: ")
return int(number_of_players)
def check_float(potential_float):
try:
float(potential_float)
return True
except:
return False
def playername(no_of_players):
print("We are expecting {} player(s). We are going to start collecting information on player names and wager!".format(no_of_players))
player_list = ['Dealer']
for number in range(1,no_of_players+1):
name = input("Player {},what is your name? ".format(number))
while name in player_list:
name = input("Player {},your chosen name has been taken. Please give us an alternative: ")
player_list.append(name)
return player_list
def playerwager(player_list):
player_wager = {}
for number in range(1,len(player_list)):
wager = input("{},how much are you betting? Please input number: $ ".format(player_list[number]))
while check_float(wager) is False:
wager = input("{},please input a valid wager in number: $ ".format(player_list[number]))
wager = float(wager)
player_wager[player_list[number]] = wager
player_wager["Dealer"] = 0
return player_wager
def dealingcards(player_list):
newdeck = Deck()
newdeck.shuffle()
print(newdeck) # Remove in due course.
for player in player_list:
for item in range(0,2):
Playerhand(player).hands[0].append(newdeck.deal_one())
Playerhand(player).show_first_card()
#GAME ON
x = number_of_players()
playerlist = playername(x)
playerwager(playerlist)
dealingcards(playerlist)
解决方法
这部分代码有误:
for player in player_list:
for item in range(0,2):
Playerhand(player).hands[0].append(newdeck.deal_one())
Playerhand(player).show_first_card()
你必须存储玩家手牌,而不是在显示第一张牌时重新定义它:
playerhands = []
for player in player_list:
playerhands.append(Playerhand(player,hands=[[],[],[]]))
for item in range(0,2):
playerhands[-1].hands[0].append(newdeck.deal_one())
playerhands[-1].show_first_card()
编辑:这是问题的真正根源 "Least Astonishment" and the Mutable Default Argument
,虽然 Heiner 走在正确的轨道上,但我通过调试器发现这样做:
ph = Playerhand(player)
神秘地没有清理手。数据似乎几乎是静态的。但是,一个简单的创可贴修复如下:
for player in player_list:
ph = Playerhand(player)
ph.hands[0] = []
for item in range(0,2):
card = newdeck.deal_one()
ph.hands[0].append(card)
ph.show_first_card()
两手牌从来没有清零,这就是为什么他们一直输出同一手牌。