溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python 中怎么實現(xiàn)隨機抽牌、排序、洗牌功能

發(fā)布時間:2021-08-12 14:50:41 來源:億速云 閱讀:328 作者:Leah 欄目:大數(shù)據(jù)

Python 中怎么實現(xiàn)隨機抽牌、排序、洗牌功能,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

創(chuàng)建一個紙牌類

一副撲克除去大王小王之外,剩下的 52 張紙牌以花色為基準(zhǔn)(梅花、方塊、黑桃、紅心)可分為 4 組,每組有 13 張牌組成;因此可創(chuàng)建兩個列表一個來存儲花色,一個存儲 13 個字符;通過兩個列表之間的隨機組合來生成 52 張紙牌,

代碼如下:

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]

代碼中通過 collections.namedtuple 模塊創(chuàng)建一個類來表示一幅紙牌,[’rank','suit'] 分別表示紙牌中的字符(2-10,J-A)和花色;

FranchDeck 類來建 52 張紙牌,其中有兩個特殊方法,len() 返回紙牌數(shù)量,__getitem__() 獲取 position(索引) 下的指定紙牌

# 用 Card 創(chuàng)建一張紙牌
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')

隨機抽取一張牌

這里借助 random 模塊實現(xiàn) 隨機 抽牌的功能

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

列表迭代、切片

因為 __getitem__ 方法 把 [] 操作交給 self._cards 列表 ,除了上面提到的 index 定位之外,F(xiàn)ranckDeck() 類還可實現(xiàn)切片、迭代操作;

# 切片操作

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

排序操作

常規(guī)來說,依據(jù)點數(shù)來判斷撲克牌的大小的話,2最小,A最大。實現(xiàn)點數(shù)排序是比較簡單的,在創(chuàng)建點數(shù)列表時是以上面提到順序進(jìn)行創(chuàng)建,排序時只需按照 點數(shù)所在 index 作為基準(zhǔn) 進(jìn)行排序即可,

除了 點數(shù)之外還有一個 花色也需要考慮,對于花色的話,需要建立一個映射基準(zhǔn)(也可以稱之為權(quán)重),不同花色賦予不同值;Python 的字典類型可以很方便地滿足我們的需要

# 創(chuàng)建一個字典映射
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 機制對列表進(jìn)行排序
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')

代碼解讀:

  • 1,代碼中利用字典加入了一個映射機制,黑桃為3,紅心為2,方塊次之,隨后梅花;

  • 2,創(chuàng)建 spades_high 函數(shù)來計算 每張牌的權(quán)重總值;

  • 3,利用 sorted() 函數(shù) key= spades_high 來作為排序基準(zhǔn),來實現(xiàn)撲克牌排序

洗牌操作

洗牌簡單來說就是對一副撲克牌重新進(jìn)行無規(guī)則地排序;正常情況random.shuffle 可以很方便地實現(xiàn)這個功能,但前提需要保證對象 滿足可變協(xié)議,這里 FranchDeck() 是不滿足的,直接使用的話會報錯:

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

對于上面問題,只需要要把 此類由 不變 變成 可變的 即可,創(chuàng)建一個函數(shù)賦值為 __setitem__ 屬性

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

這里抽取到打亂前后紙牌的前 5 個元素,已經(jīng)實現(xiàn) 洗牌 的功能了!

根據(jù)以上的代碼部分,可以進(jìn)一步開發(fā), 提前設(shè)計好 54 張撲克牌的可視化圖片,

Python 中怎么實現(xiàn)隨機抽牌、排序、洗牌功能

創(chuàng)建一個 key:value 映射關(guān)系,對撲克牌字符與可視化圖片之間創(chuàng)建一個映射關(guān)系,如下圖所示,把此關(guān)系集存儲到指定數(shù)據(jù)庫或文件中,方便后面使用時可直接調(diào)用

看完上述內(nèi)容,你們掌握Python 中怎么實現(xiàn)隨機抽牌、排序、洗牌功能的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI