0

不久前,我用 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。计数方法将接受哪些参数的问题?还是与我的代码的一个方面有关?

谢谢你的帮助!

4

3 回答 3

2

你的问题得到了很好的回答,所以这里有一些其他的评论:

首先,ifs in的蛇形链Card.__init__()最好用字典查找代替。喜欢这样做:

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()没有必要使用- ,反之亦然。只用一个。既然你以后可能想剥掉其他手,那就更好了。洗牌后,可以非常有效地从牌库中取出 7 张随机牌,如下所示:random.sample()shuffle()

your_hand = deck[-7:]
del deck[-7:]

从列表末尾删除切片在 CPython 中非常有效。实际上,实现只是记录了列表的大小现在减去了删除元素的数量——不需要重新排列。

要获得另外 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)

之后。

玩得开心!:-)

于 2013-09-22T18:32:43.597 回答
2

hand.count(card.value)card.value将检查在牌组中出现了多少次。Card那是 0,因为该值是一个数字,并且在牌组中没有数字,只有s。

你可以在哪里sum(card.value == 5 for card in hand)得到卡的数量。这是有效的,因为有一个布尔值or ,它们在数值上分别等于和。handcard.value == 5a == bTrueFalse10

所以它遍历hand(for card in hand),进行比较(card.value == 5)并总结Trues的数量,尽管它是内联的,所以一个列表存储在内存中。

于 2013-09-22T15:06:15.903 回答
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})

我认为这对你来说在评估手时会更容易使用(它是一个字典子类)。

于 2013-09-22T15:35:18.583 回答