[英]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.