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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41970795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 01:59:03  来源:igfitidea点击:

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

python

提问by Mushy0364

I was thinking about making a deck of cards for a card game. I could make a list of all of the cards (I don't really care about the suits), but I was wondering if there was a much easier way to do this.

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

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

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

I'm positive you could make a forloop to create 4 cards of the same value and add it to a list, but I was wondering if that was the best solution. I am not advanced enough to know about or create a Classwhich I have seen to be offered as other solutions, but I am open to explanations.

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

I have already made a dictionary defining the card values.

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

回答by Right leg

I propose you a solution with a basic class usage.

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

First, let's make a Cardclass:

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

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

Then, let's make a list of colors:

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

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

Finally, let's build your deck with a list comprehension:

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

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

The Cardclass is only a wrapper, just to manipulate cards instead of tuples, which feels more natural.

Card班是唯一的包装,只是为了操纵卡,而不是元组,感觉更自然。

In this current state, it's almost equivalent to renaming the tupletype... Basically, it only consists in a constructor, __init__, that sets the attributes of the instance.

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

So when I call Card(value, color)in the list comprehension, so for example Card(11, 'spades'), a new instance of the Cardclass is created, which has its valueattribute set to 11, and its colorattribute set to 'spades'.

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

I recommend you read some tutorial about OOP for an in-depth understanding of the concepts.

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



Now, you can try and improve this idea, for instance by using a more detailed valueslist instead of the range(1, 14):

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

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

回答by Chiheb Nexus

Another approach can be done using namedtuplefrom collectionsmodule, like this example:

另一种方法可以使用namedtuplefromcollections模块完成,如下例所示:

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]

And you can access to the values like this:

您可以访问这样的值:

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

回答by wasabi

First some utility functions:

首先是一些实用函数:

import random
from random import shuffle

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

Then a Card class:

然后是 Card 类:

class Card:

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

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

Then a Deck class:

然后是 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 )

回答by Sachin Konan

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

回答by Paul Rooney

You can represent your deck as a list of tuples. Which is a lighter weight alternative to classes. In dynamic languages like python, you will often do this to avoid the boilerplate code incurred by defining your own classes.

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

import itertools
import random

vals = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Hyman', '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))

You may wish to represent the card values by an integer, this could easily be achieved by altering the input list.

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

回答by greedy52

This solution uses enum class (package enum34).

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

Two enum classes represent the Suit and the Number with a custom strfunction. The Cardclass takes a Suit + a Number

两个枚举类使用自定义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

回答by Gene Burinsky

Could also do this:

也可以这样做:

card_deck = []

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

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

回答by fatalError

I think you're right, a for loopwould get the job done but might not be the most elegant solution. I've never programmed in Python so I don't know the exact syntax but I could give you a psuedo code rundown of a class that would get the job done.

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

回答by Giovanni G. PY

This code makes a deck of 40 card with two for loops. The deck is made of 40 strings in witch the last caracter [-1] is the color among c b s d (coppe, bastoni, spade and denari in an italian type of card deck). As the 10th card got 2 digit for the value number it is a good practise to get the value of the card using [:-1] so that it will take 1,2,3... until 9 and 10 when there is this card with 2 digit.

这段代码制作了一副 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

output:

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

输出:

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

回答by bps

I found a very useful tutorial for this:

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

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

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

It may look childish but it contains some really good-quality code

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

The code it contains looks something like this:

它包含的代码如下所示:

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")