您好,登錄后才能下訂單哦!
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 張撲克牌的可視化圖片,
創(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è)資訊頻道,感謝各位的閱讀!
免責(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)容。