繁体   English   中英

创建一副纸牌的最佳方法是什么?

[英]What is the best way to create a deck of cards?

我正在考虑为纸牌游戏制作一副纸牌。 我可以列出所有的牌(我并不真正关心花色),但我想知道是否有更简单的方法来做到这一点。

cards = ['1','1','1','1'....]

我很肯定您可以创建一个for循环来创建 4 张具有相同值的卡片并将其添加到列表中,但我想知道这是否是最佳解决方案。 我不够先进,无法了解或创建一个我已经看到作为其他解决方案提供的Class ,但我愿意接受解释。

我已经制作了一个定义卡片值的字典。

我向您提出了一个具有基本类用法的解决方案。

首先,让我们创建一个Card类:

class Card:
    def __init__(self, value, color):
        self.value = value
        self.color = color

然后,让我们制作一个颜色列表:

colors = ['heart', 'diamonds', 'spades', 'clubs']

最后,让我们用列表理解来构建你的套牌:

deck = [Card(value, color) for value in range(1, 14) for color in colors]

Card类只是一个包装器,只是为了操作卡片而不是元组,感觉更自然。

在当前状态下,它几乎等同于重命名tuple类型......基本上,它只包含一个构造函数__init__ ,它设置实例的属性。

因此,当我在列表推导式中调用Card(value, color)时,例如Card(11, 'spades') ,会创建Card类的一个新实例,其value属性设置为11 ,其color属性设置为设置为'spades'

我建议您阅读一些有关 OOP 的教程,以深入了解这些概念。


现在,您可以尝试改进这个想法,例如使用更详细的values列表而不是range(1, 14)

values = ['ace', '2', ..., 'king']

另一种方法可以使用来自collections模块的namedtuple来完成,如下例所示:

from collections import namedtuple

Card = namedtuple('Card', ['value', 'suit'])
suits = ['hearts', 'diamonds', 'spades', 'clubs']
cards = [Card(value, suit) for value in range(1, 14) for suit in suits]

您可以访问这样的值:

print(cards[0])
>>> Card(value=1, suit='hearts')
print(cards[0].value, cards[0].suit)
>>> 1 hearts

您可以将您的牌组表示为元组列表。 这是班级的轻量级替代品。 在像 python 这样的动态语言中,您通常会这样做以避免因定义自己的类而产生的样板代码。

import itertools
import random

vals = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'jack', 'queen', 'king', 'ace']
suits = ['spades', 'clubs', 'hearts', 'diamonds']

deck = list(itertools.product(vals, suits))

random.shuffle(deck)

for val, suit in deck:
    print('The %s of %s' % (val, suit))

您可能希望用整数表示卡片值,这可以通过更改输入列表轻松实现。

values = ['2','3','4','5','6','7','8','9','10','Jack','Queen','King','Ace']
suites = ['Hearts', 'Clubs', 'Diamonds', 'Spades']
deck = [[v + ' of ' + s,v] for s in suites for v in values]

此解决方案使用枚举类(包 enum34)。

两个枚举类使用自定义str函数表示 Suit 和 Number。 Card类需要一个西装 + 一个数字

from enum import Enum          
from enum import unique        

@unique
class Suit(Enum):              
    Spade = 1
    Heart = 2
    Dimond = 3 
    Club = 4

    def __str__(self):
        return self.name

@unique
class Number(Enum):
    N1 = 1
    N2 = 2
    N3 = 3
    N4 = 4
    N5 = 5
    N6 = 6
    N7 = 7
    N8 = 8
    N9 = 9
    N10 = 10
    J = 11
    Q = 12
    K = 13 

    def __str__(self):
        if self.value <= 10:
            return str(self.value)          
        return self.name

class Card(object):
    def __init__(self, suit, number):
        self.suit = suit
        self.number = number

    def __str__(self):
        return '{} {}'.format(self.suit, self.number)

cards = [ Card(suit, number) for suit in Suit for number in Number ]
for card in cards:
    print card

首先是一些实用函数:

import random
from random import shuffle

def RANKS(): return [ "Ace", "2", "3", "4", "5", "6", "7","8", "9", "10", "Jack", "Queen", "King" ]
def SUITS(): return [ "Clubs", "Diamonds", "Hearts", "Spades" ]

然后是 Card 类:

class Card:

    def __init__( self, rank, suit ):
        self.rank = rank
        self.suit = suit

    def __str__( self ):
        return self.rank + " of " + self.suit

然后是 Deck 类:

class Deck:

    def __init__( self ):
        self.contents = []
        self.contents = [ Card( rank, suit ) for rank in RANKS() for suit in SUITS() ]
        random.shuffle( self.contents )

我认为您是对的, for loop可以完成工作,但可能不是最优雅的解决方案。 我从来没有用 Python 编程,所以我不知道确切的语法,但我可以给你一个可以完成工作的类的伪代码纲要。

也可以这样做:

card_deck = []

for i in range(3,11):
    card_deck.extend([i]*4)

for c in ['Jack', 'Queen', 'King', 'Ace']:
    card_deck.extend([c]*4)

这段代码制作了一副 40 张卡片,带有两个 for 循环。 牌组由 40 条线组成,最后一个字符 [-1] 是 cbsd 中的颜色(意大利式牌组中的 coppe、bastoni、spad 和 denari)。 由于第 10 张卡的价值编号为 2 位数字,因此使用 [:-1] 获取卡的价值是一个很好的做法,这样就需要 1,2,3... 直到 9 和 10 2位数的卡。

class Cards:
    def __init__(self):
        self.deck = []                  # the deck is empty
        for n in range(1,11):           # numbers
            for c in "cbsd":            # colors
                self.deck.append(str(n) + c)  # a string for each card


deck = Cards()
deck.deck

输出:

['1c', '1b', '1s', '1d', '2c', '2b', '2s', '2d', '3c', '3b', '3s', '3d', ' 4c', '4b', '4s', '4d', '5c', '5b', '5s', '5d', '6c', '6b', '6s', '6d', '7c' , '7b', '7s', '7d', '8c', '8b', '8s', '8d', '9c', '9b', '9s', '9d', '10c', ' 10b', '10s', '10d']

我为此找到了一个非常有用的教程:

https://projects.raspberrypi.org/en/projects/deck-of-cards

它可能看起来很幼稚,但它包含一些非常优质的代码

它包含的代码如下所示:

class Card:

    """
    The Card class represents a single playing card and is initialised by passing a suit and number.
    """

    def __init__(self, suit, number):
        self._suit = suit
        self._number = number

    def __repr__(self):
        return self._number + " of " + self._suit

    @property
    def suit(self):

        """
        Gets or sets the suit of a card
        """

        return self._suit

    @suit.setter
    def suit(self, suit):
        if suit in ["hearts", "clubs", "diamonds", "spades"]:
            self._suit = suit
        else:
            print("That's not a suit!")

    @property
    def number(self):
        """
        Gets or sets the number of a card
        """
        return self._number

    @number.setter
    def number(self, number):
        valid = [str(n) for n in range(2,11)] + ["J", "Q", "K", "A"]
        if number in valid:
            self._number = number
        else:
            print("That's not a valid number")

“简单代码,52张牌组合的牌组列表”:

card_type=['Diamond', 'Heart', 'Spade', 'Clover']
card_number=['1','2','3','4', '5', '6', '7', '8', '9', 'J', 'Q', 'K']
for c in card_type:
    ...:     for n in card_number:
    ...:         deck.append([c,n])
deck = {}
//i represents order
// 0,1,2,3 represents suits
// 0,1,2,...,12 represents ranks 

for i in range(52):
  deck[i] = [i%4,i%13]

一种选择是使用“for 循环”为每个等级和花色创建一张卡片,然后分配值,并将所有数据放在每张卡片的元组中,并将所有卡片保留在列表中。

我使用以下代码在不使用类的情况下创建了一副纸牌:(请注意,我所赋予的值是针对二十一点游戏的,但您可以随意更改它)

ranks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
suits = ["Clubs", "Diamonds", "Hearts", "Spades"]
cards = []
def deck_of_cards():
    for rank in ranks:
        for suit in suits:
            a = rank
            b = suit
            if ranks.index(a) == 0:
                c = 11
            elif ranks.index(a) > 9:
                c = 10
            else:
                c = ranks.index(a) + 1
            new_card = (a, b, c)
            cards.append(new_card)

deck_of_cards()
cards = ["Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"]

deck = []

suits = ["Spades", "Diamonds", "Clubs", "Hearts"]
suit = 0
for card in range(52):
    if card >= 13 * (suit + 1):
        suit += 1
    deck.append(str(cards[card % 13] + "|" + suits[suit]))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM