检查列表是否包含4个相同值的元素

1 投票
5 回答
2576 浏览
提问于 2025-04-16 08:52

我又遇到一个新手问题了 :D

我正在尝试制作一个与电脑对战的文字版“抓鱼”游戏。

这里面一张牌其实是由两个列表中的元素组成的一个元组。

suits = ['Clubs', 'Diamonds', 'Spade', 'Hearts']
ranks = [None, 'ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'jack', 'queen', 'king']

然后这些牌会被放到一个牌堆里,洗牌,然后发到每个人的手里。(大部分内容我都是从《Think Python》这本书里学来的。在这个过程中,我学到了很多关于类结构和继承的知识。)

所以一手牌可能看起来是这样的:

['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts 2']

你可以看到,这手牌里有四张同样点数的牌,所以玩家得了1分。

但我该怎么检查这手牌里是否有四张相同点数的牌呢?我需要逐个检查列表里的每个元素,还是有更简单的方法呢?


编辑
非常感谢大家的回答。 :D

不过当我尝试对手里的牌使用“split”时,出现了属性错误。看来我应该多发一些我正在运行的代码。

完整代码和错误信息在这里
http://pastebin.com/TwHkrbED

在Card类的方法定义上有什么问题吗?我已经折腾了好几个小时想让它工作,但一直没有成功。

编辑2
我对生成牌堆的部分做了一些修改。现在整个牌堆是一个元组的列表,代码也少了很多。

thedeck=[]
class Deckofcards:
    suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
    ranks = ['Ace', '2', '3', '4', '5', 
        '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King']
    def __init__(self):
        for i in self.suits:
            for a in self.ranks:
                thedeck.append((i, a))

看起来之前的方法太复杂了,但我也不太确定。明天我会看看,添加实际的游戏部分。

5 个回答

0

比Justin的内容更一般一些:

suits = ['Clubs', 'Diamonds', 'Spade', 'Hearts']
ranks = [None, 'ace', '2', '3', '4', '5', '6', '7', \
'8', '9', '10', 'jack', 'queen', 'king']

hand = ['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts king']
rankshand = [i.split()[1] for i in hand]

fourofakind = [hr for hr in ranks if rankshand.count(hr)==4]
threeofakind = [hr for hr in ranks if rankshand.count(hr)==3]
pair = [hr for hr in ranks if rankshand.count(hr)==2]

fourofakind
[]
threeofakind
['2']
pair
['king']

可以查看哪个等级已经被设置。

1

这里有一种方法:

x = ['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts 2']
ranks = [i.split()[1] for i in x]
fourofakind = any(ranks.count(i)==4 for i in set(ranks))

fourofakind 的意思是,如果手中有四张同样点数的牌,那么它的值就是 True(真)。

4

我建议稍微改一下结构:把每张牌用一个包含(点数, 花色)的元组来表示。这样你给的例子手牌就变成了:

hand = [('2', 'Clubs'),
        ('king', 'Diamonds'),
        ('2', 'Diamonds'),
        ('2', 'Spades'),
        ('2', 'Hearts')]

接着,我建议再写几个辅助函数,帮助你计算手牌的价值:

from collections import defaultdict

def get_counts(hand):
    """Returns a dict mapping card ranks to counts in the given hand."""
    counts = defaultdict(int)
    for rank, suit in hand:
        counts[rank] += 1
    return counts

def get_points(hand):
    """Returns the number of points (ie, ranks with all 4 cards) in the given
    hand."""
    return sum(1 for count in get_counts(hand).itervalues() if count == 4)

编辑:get_points函数中改用了sum,我觉得这样更清晰。

使用这些函数和你给的例子手牌,你会得到这样的输出:

>>> get_counts(hand)
defaultdict(<type 'int'>, {'king': 1, '2': 4})

>>> get_points(hand)
1

撰写回答