Python makes a deck of playing cards, interesting case!

If you think the article is well written and want the data in the blog article, please pay attention to the official account: [Mr. Z's note], 50+ Python e-books and 200G + high-quality video materials have been prepared for you. The backstage reply keywords: 1024 available

Before see an example of the more interesting, so tidy for everyone to share this article on "fluent Python", the case was created by a Python class attributes to remove King, Wang after 52 playing cards, and to achieve a random draw Cards, sorting, shuffling and other functions;

Create a card class

Except for the king and the king, the remaining 52 cards can be divided into 4 groups based on suits (clubs, diamonds, spades, hearts), and each group consists of 13 cards; therefore, two lists can be created One to store suits and one to store 13 characters; 52 cards are generated by random combination between the two lists,

code show as below:

import collections

Card = collections.namedtuple("Card",['rank','suit'])

class FrenchDeck:
    ranks = [str(n) for n in range(2,11) ] + list("JQKA")
    suits = 'spades diamonds clubs hearts'.split()
    
    def __init__(self):
        self._cards = [Card(rank,suit) for suit in self.suits 
                       for rank in self.ranks]
    
    def __len__(self):
        return len(self._cards)
    
    def __getitem__(self, position):
        return self._cards[position]

Code by collections.namedtuplecreating a class to represent a card module, [’rank','suit']respectively card characters (2-10, JA) and colors;

The FranchDeck class is used to build 52 cards, of which there are two special methods, len() returns the number of cards, __getitem__() gets the specified card under position (index)

# 用 Card 创建一张纸牌
beer_card = Card('7','diamonds')
print(beer_card) # 打印输出

deck = FrenchDeck()
print('len is -----')
print(len(deck))

# 返回首张 纸牌
print(deck[0])

# 返回最后一张纸牌
print(deck[-1])


# Output

Card(rank='7', suit='diamonds')
len is -----
52
Card(rank='2', suit='spades')
Card(rank='A', suit='hearts')

Randomly draw a card

With this module implements random random draw function

from random import choice
# 利用 random.choice 随机抽取一张纸牌
print("random choice -----------")
print(choice(deck))

print(choice(deck))
print(choice(deck))

# Output

random choice -----------
Card(rank='8', suit='clubs')
Card(rank='5', suit='hearts')
Card(rank='5', suit='spades')

List iteration, slicing

Because the __getitem__ method passes the [] operation to the self._cards list, in addition to the index positioning mentioned above, the FranckDeck() class can also implement slicing and iteration operations;

# 切片操作

print('\nslice is --')
print(deck[:3])
print(deck[8:10])

print('\n迭代操作')
for card in deck[:3]:
    print(card)

print('\n 反迭代操作')
for card in reversed(deck[:3]):
    print(card)
    

# Output

slice is --
[Card(rank='2', suit='spades'), Card(rank='3', suit='spades'), Card(rank='4', suit='spades')]
[Card(rank='10', suit='spades'), Card(rank='J', suit='spades')]

迭代操作
Card(rank='2', suit='spades')
Card(rank='3', suit='spades')
Card(rank='4', suit='spades')

 反迭代操作
Card(rank='4', suit='spades')
Card(rank='3', suit='spades')
Card(rank='2', suit='spades')

Sort operation

Conventionally, if you judge the size of a playing card based on the number of points, 2 is the smallest and A is the largest. It is relatively simple to realize the point sorting. When creating the point list, it is created in the order mentioned above. When sorting, you only need to sort according to the index of the point as the benchmark .

In addition to points, there is also a suit that needs to be considered. For suits, we need to establish a mapping basis (also called weights) , and different suits are assigned different values; Python's dictionary type can meet our needs in many ways

# 创建一个字典映射
suit_values = dict(
    spades = 3,
    hearts = 2,
    diamonds = 1,
    clubs = 0
)
def spades_high(card):
    rank_value = FrenchDeck.ranks.index(card.rank) # 索引查询
    return rank_value*len(suit_values) + suit_values[card.suit] # index* 4 + suit.value

print('\nSorted ------------------')
# 利用 key = lambda 机制对列表进行排序
for card in sorted(deck,key = spades_high,reverse= True):
    print(card)
    
# Output

Sorted ------------------
Card(rank='A', suit='spades')
Card(rank='A', suit='hearts')
Card(rank='A', suit='diamonds')
Card(rank='A', suit='clubs')
Card(rank='K', suit='spades')
Card(rank='K', suit='hearts')
Card(rank='K', suit='diamonds')
Card(rank='K', suit='clubs')
Card(rank='Q', suit='spades')
Card(rank='Q', suit='hearts')
Card(rank='Q', suit='diamonds')

Code interpretation:

  • 1. The code uses a dictionary to add a mapping mechanism, spades are 3, hearts are 2, squares are second, followed by clubs;
  • 2. Create the spades_high function to calculate the total weight of each card;
  • 3. Use the sorted() function key=spades_high as the sorting benchmark to realize the sorting of playing cards

Shuffle operation

In simple terms, shuffle is to reorder a deck of playing cards irregularly; under normal circumstances, random.shuffle can achieve this function in many aspects, but the premise needs to ensure that the object meets the variable protocol. Here, FranchDeck() is not satisfied. If used directly, an error will be reported:

from random import shuffle
print('-------------------\n'*3)
deck  =FrenchDeck()
shuffle(deck)


# Output


    x[i], x[j] = x[j], x[i]
TypeError: 'FrenchDeck' object does not support item assignment

For the above problem, just make such a change becomes a variable to create a function assigned to __setitem__ property

from random import shuffle
print('-------------------\n'*3)


def set_deck(deck,position,card):
    deck._cards[position] = card

deck1 = FrenchDeck()
print('打乱前\n')
print(deck1[:5])
FrenchDeck.__setitem__ = set_deck
shuffle(deck1)

# Output


打乱前
Card(rank='2', suit='spades')
Card(rank='3', suit='spades')
Card(rank='4', suit='spades')
Card(rank='5', suit='spades')
Card(rank='6', suit='spades')

打乱后:
Card(rank='6', suit='diamonds')
Card(rank='4', suit='hearts')
Card(rank='Q', suit='diamonds')
Card(rank='K', suit='clubs')
Card(rank='8', suit='spades')

Here drawn into the first five elements before and after the upset of cards has been achieved shuffle function of!

According to the above code part, it can be further developed, and the visual pictures of 54 playing cards can be designed in advance.

Snipaste_2020-09-27_00-59-22.png

Create a key:value mapping relationship, create a mapping relationship between playing card characters and visual pictures, as shown in the figure below, store this relationship set in a specified database or file, and then call it directly after use

Snipaste_2020-09-27_01-06-46.png

You can create a small program for developing playing cards based on Python by following the advanced gameplay above!

Okay, the above is the entire content of this article. Finally, thank you for reading!

Guess you like

Origin blog.csdn.net/weixin_42512684/article/details/108820533