проверить, содержит ли список 4 элемента одинакового значения - PullRequest
1 голос
/ 22 декабря 2010

Итак, я снова застрял на проблеме новичка: D

Я пытаюсь объединить текстовую игру "лови рыбу" с компьютером.

Хорошо, так что 1 карта на самом деле является кортежем элементов из двух списков.

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

Затем это добавляется в колоду, перетасовывается и еще много чего, а затем раздается в руки. (я думаю, что получил большую часть из книги thinkpython. Много узнал о структуре классов и наследовании в процессе.)

Так что одна рука может выглядеть вот так

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

Как видите, эта рука содержит четыре одинаковых ранга, так что это 1 очко для игрока. Но как я могу проверить, содержит ли рука четыре экземпляра какого-либо предмета в списке рангов? Нужно ли перебирать каждый элемент в списке или есть простой и понятный способ?


EDIT
Большое спасибо за все ответы, ребята. : D Но я получаю ошибку атрибута, когда пытаюсь использовать «split» для предметов в руке. Думаю, мне следовало опубликовать больше кода, который я использую.

Полный код и обратная связь здесь
http://pastebin.com/TwHkrbED

Что-то не так с тем, как методы определены в Карте? Я часами бродил, пытаясь заставить его работать, но не повезло.

EDIT2
Внесены некоторые изменения в часть, генерирующую колоду. Теперь вся колода представляет собой список кортежей и намного меньше кода.

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 ]

4 голосов
/ 22 декабря 2010

Я мог бы предложить небольшой рефакторинг: представлять каждую карту в руке как кортеж (rank, suit).Итак, ваш пример руки будет:

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)

Редактировать: Переключение на использование sum в функции get_points, которая мне кажется более понятной.

Работая с этими функциями и примером руки, которую вы дали, вы получаете вывод примерно так:*

1 голос
/ 22 декабря 2010

Вот один из способов:

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 - это истина, если в руке четыре карты одного ранга.

0 голосов
/ 22 декабря 2010

Новый встроенный класс Counter, добавленный в Python 2.7 к модулю стандартной библиотеки collections, делает это довольно простым.

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 2']

from collections import Counter

counts = Counter(card.split()[1] for card in hand)
four_of_a_kind = [rank for rank,count in counts.iteritems() if count == 4]
print 'four_of_a_kind:', four_of_a_kind
# four_of_a_kind: ['2']
0 голосов
/ 22 декабря 2010

Немного более общий, чем у Джастина:

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']

С возможностью видеть, какое звание имеет набор.

0 голосов
/ 22 декабря 2010

Если вы ищете расширенную функциональность:

hand = ['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts 2']
hand_ranks = [i.split()[1] for i in x]
fourofakind = {}
for i in set(hand_ranks):
    fourofakind[i] = (hand_ranks.count(i) == 4)

Дадит вам ранг карт (dict) карт (карт в руке) в зависимости от того, есть ли у вас 4 этого ранга.

...