前一段时间我用Javascript构建了一个简单的扑克游戏,并且认为我在Python中从零开始。这是迄今为止的代码(您可以跳到最后来解决问题):
#imports
import random
#basics
values = range(2,15)
suits = ['Clubs','Spades','Diamonds','Hearts']
#card object
class Card:
def __init__(self,suit,value,name):
self.suit = suit
self.value = value
self.name = name
if self.value < 11:
self.name = str(self.value) + ' of'
if self.value == 11:
self.name = 'Jack of'
if self.value == 12:
self.name = 'Queen of'
if self.value == 13:
self.name = 'King of'
if self.value == 14:
self.name = 'Ace of'
#deck
deck = []
#load and shuffle deck
for s in suits:
for v in values:
deck.append(Card(s,v,'o'))
random.shuffle(deck)
#load hands
your_hand = random.sample(deck,7)
for card in your_hand:
deck.remove(card)
#determine hands
def find_matches(hand):
class Match:
def __init__(self,value,amount):
self.value = value
self.amount = amount
matches = [Match(card.value,hand.count(card.value)) for card in hand]
for x in matches:
print x.value,x.amount
find_matches(your_hand)
是的,我意识到它并不完美(建议总是受到赞赏!)。我的问题是提供可靠的匹配功能。我已经尝试了一些不同的方法,但是对于每个元素,hand.count(card.value)
为{0}。问题是count方法接受哪些参数的问题?或者它是我的代码的一个方面?
感谢您的帮助!
答案 0 :(得分:2)
hand.count(card.value)
将检查卡片中card.value
出现的次数。这是0,因为该值是一个数字,并且在牌组中没有数字,只有Card
s。
您可以sum(card.value == 5 for card in hand)
获取hand
card.value == 5
所在的卡片数量。这是有效的,因为a == b
具有布尔值True
或False
,它们在数值上分别等于1
和0
。
所以它遍历手(for card in hand
),进行比较(card.value == 5
)并总结True
的数量,虽然它是内联的,所以存储了一个列表在记忆中。
答案 1 :(得分:2)
hand.count(card.value)
的问题在于它计算手中有多少Card
个对象等于其中一个对象的整数值,因为你比较两个不同的对象,它总是为零。一个简单的解决方法是将所有整数卡值提取到一个单独的列表中,并使用count()
方法代替:
def find_matches(hand):
class Match:
def __init__(self, value, amount):
self.value = value
self.amount = amount
values = [card.value for card in hand] # list of extracted card values
matches = [Match(card.value, values.count(card.value)) for card in hand]
for x in matches:
print x.value, x.amount
通过此更改,它将执行以下操作:
10 1
4 1
9 1
3 1
12 2
12 2
6 1
更类似于Pythonic的方法是使用带有生成器表达式的collections.Counter
类:
from collections import Counter
counter = Counter(card.value for card in your_hand)
print '{} unique values: {}'.format(len(counter), counter)
同一只手会给你:
6 unique values: Counter({12: 2, 3: 1, 4: 1, 6: 1, 9: 1, 10: 1})
我认为在评估指针时使用它会更容易(它是字典的子类)。
答案 2 :(得分:2)
你的问题得到了很好的解答,所以这里还有其他一些评论:
首先,if
中的Card.__init__()
的snaky链更好地被字典查找取代。喜欢这样做:
value2name = dict((val, str(val)) for val in values)
for val, name in (11, 'Jack'), (12, "Queen"), (13, "King"), (14, "Ace"):
value2name[val] = name
设置values
后,将所有__init__()
替换为:
self.name = value2name[value] + " of " + suit
然后some_card.name
将显示为(例如):
King of Spades
5 of Spades
Ace of Hearts
[etc]
其次,如果您使用random.shuffle()
,则使用random.sample()
也没有意义 - 反之亦然。只使用一个。由于您可能希望以后剥离其他人,shuffle()
会更好。在洗牌后,可以非常有效地从牌组中移除7张随机牌:
your_hand = deck[-7:]
del deck[-7:]
在CPython中,从列表的 end 中删除切片非常有效。实际上,实现只是记录列表的大小现在因删除的元素数量而变小 - 不需要重新排列。
要获得另外7张牌,请执行相同的操作。或者把它放在一个函数中:
def deal(deck, n):
if n <= 0:
raise ValueError("n must be > 0")
if n > len(deck):
raise ValueError("asked for more cards than remain")
result = deck[-n:]
del deck[-n:]
return result
然后:
your_hand = deal(deck, 7)
后。
玩得开心! : - )