有人可以看一下我的代码并让我知道为什么当玩家的手牌小于21时,Ace值没有变为11?我在def checkvalue(self)
下的FOR循环中实现IF循环时遇到了困难。这是最好的方法吗?还是有更好的方法?
由于
import random
rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace']
suit = ['Diamonds', 'Clubs', 'Hearts', 'Spade']
card_val = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':1}
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __str__(self):
return str(self.rank) + ' of ' + str(self.suit)
def grab_suit(self):
return self.suit
def grab_rank(self):
return self.rank
def draw(self):
print(self.suit + self.rank)
class Deck(object):
def __init__(self):
self.cards = []
for i in rank:
for j in suit:
self.cards.append(Card(i,j))
def __str__(self):
return str([str(card) for card in self.cards])
def shuffle(self):
random.shuffle(self.cards)
def deal(self):
single_card = self.cards.pop()
return single_card
deck = Deck()
class Hand(object):
def __init__(self):
self.value = []
def hit(self):
self.value.append(deck.deal())
return self.value
def __str__(self):
return str([str(card) for card in self.value])
def checkvalue(self):
handvalue = 0
for card in self.value:
handvalue += card_val[card.grab_rank()]
if card.grab_rank() in self.value == 'Ace' and handvalue <= 11:
handvalue = handvalue + 10
return handvalue
playerhand = Hand()
答案 0 :(得分:2)
if card.grab_rank() in self.value == 'Ace'
是胡言乱语。或者更确切地说,它被解释为
if (card.grab_rank() in self.value) == 'Ace'
card
,这里指的是手中的最后一张牌(因为它在for
圈之外,在上面),而不是你手中的任何卡手。即使是这样,您也必须删除in self.value
支票。
让代码正常工作的最小变化是:
class Hand(object):
...
def checkvalue(self):
handvalue = 0
for card in self.value:
handvalue += card_val[card.grab_rank()]
if any(card.grab_rank() == 'Ace' for card in self.value) and \
handvalue <= 11:
handvalue += 10
return handvalue
另外,get_rank
和get_value
是愚蠢的。不要在Python中实现getter,只需使用属性访问(card.rank
和card.value
)。
请注意,您在这里有很多可以清理的东西。首先,卡片应该知道它们自己的价值,而不是必须查找全局表格才能找到它。
class Card(object):
valuetable = {'Jack': 10, 'Queen': 10, 'King': 10, 'Ace': 1}
valuetable.update({str(i): i for i in range(2, 10)})
# maybe write that out for clarity.
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
self.value = self.valuetable[self.rank] # look up once and save
然后您的checkvalue
功能变为
def checkvalue(self):
handvalue = sum(c.value for c in self.value)
if any(c.rank == 'Ace' for c in self.value) and handvalue <= 11:
handvalue += 10
return handvalue
如果重构继承模型并将checkvalue
转换为属性,这会变得更加简单。
class Hand(list):
# in other languages, I might literally define this as a type alias of `[]Card`
# in Python, inheriting from list is fine.
@property
def value(self):
total = [c.value for c in self]
if any(c.rank == 'Ace' for c in self) and total <= 11:
total += 10
return total
现在您拨打hand.value
而不是hand.value()
,这无论如何都更有意义。 value
不是现实世界中的行为 - 它不是动词而是动词。将其视为属性(或属性,这是@property
装饰器所做的)。
请注意,我不会在此处定义__init__
,因为当您从list
继承时,我们会对此进行定义,因此我不会定义__str__
它或多或少都是自己照顾的(如果你print
列表,它会调用所有成员str
,并且我不会定义{{1因为一只手真的不应该击中它自己。从封装的角度来看它是没有意义的(它现在依赖于一个名为hit
的对象,它有一个方法deck
)并且它对&#没有意义。 34;击球&#34;成为他们的责任。也许考虑......
deal
播放器点击,手牌没有。
答案 1 :(得分:1)
当您计算玩家手牌的价值时,您只需比较迭代到card
的最后self.value
,看看它是Ace
。
def checkvalue(self):
handvalue = 0
for card in self.value:
handvalue += card_val[card.grab_rank()]
# Because of how Python scoping works, the card you use here
# is the last card that `for card in self.value` iterated on
# You're not actually comparing every card in `self.value` to 'Ace'
# This conditional is also odd - you probably meant it to be an iteration
# over self.value to see if any card was an Ace
if card.grab_rank() in self.value == 'Ace' and handvalue <= 11:
handvalue = handvalue + 10
return handvalue
所以基本上,你想要计算手值,同时确定是否有任何卡是Ace
。
def checkvalue(self):
handvalue = 0
has_ace = False
for card in self.value:
handvalue += card_val[card.rank]
if card.rank == 'Ace':
has_ace = True
if has_ace and handvalue <= 11:
handvalue += 10
return handvalue
答案 2 :(得分:0)
你想要for循环中的if,否则你只会检查一张牌(手中的最后一张牌)。我们也只关心他们是否至少有一个ace,因为使用多个,因为11会破灭。
尝试:
def checkvalue(self):
handvalue = 0
has_ace = False
for card in self.value:
if card.grab_rank() == 'Ace':
has_ace = True
handvalue += card_val[card.grab_rank()]
if has_ace and handvalue <= 11:
handvalue += 10
return handvalue
关于其余代码的小注释:
你是否检查self.value是否等于&#39; Ace&#39; (假)然后如果card.grab.rank()在False中会出错。
您可能希望在弹出之前检查牌组中的牌组是否为空,否则会出错。