================================================================
注意:本文參考“巧妙的Python數據結構玩法|實戰德州撲克”的相關內容,並在此基礎之上完成模擬撲克對戰游戲。
原文網址:http://mp.weixin.qq.com/s/JQ0zJGf7Tz49Xn78x7Z40g
================================================================
我們寫了兩個模塊:poker_game.py和comparing_cards.py。其中模塊comparing_cards.py主要實現的功能是手牌類型的識別,等級划分,以及大小的比較。該模塊的實現,主要是參考上面提到的文章里的內容,根據需要進行了一定的改動。可以參考該文章進行理解和閱讀,我們主要關注第二個模塊poker_game.py,也就是實現模擬對戰的模塊。
模塊comparing_cards.py的代碼如下:
"""手牌排序""" def card_ranks(cards): ranks = ['0123456789TJQKA'.index(r) for r,s in cards] ranks.sort(reverse=True) #reverse實現降序排序 return ranks
"""判讀順子""" #注意,用set(ranks)實際上執行了一次唯一化操作,在將列表轉換為集合的過程中,相同的元素只保留了一個,下同 def judge_straight(cards): ranks = card_ranks(cards) return ( max(ranks)-min(ranks) ) == 4 and len( set(ranks) )==5 """判斷是否為同花""" def judge_flush(cards): hand_flush = [s for r,s in cards] return len( set(hand_flush) ) == 1 """判斷炸彈,三帶二""" #因為return會終止函數,所以如果在判斷成對(即n=2)的時候,如果ranks中含有兩對,結果只返回第一對,這也是后面判斷成對的時候,為什么還出現lowpair的原因 def judge_kind(n,ranks): for r in ranks: if ranks.count(r) == n: return r return None """判讀兩對""" #reversed()函數是返回序列seq的反向訪問的迭代子。參數可以是列表,元組,字符串,不改變原對象。 #list(reversed(ranks))返回列表的反向排序的列表 #map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次作用到序列的每個元素,並把結果作為新的list返回。 def two_pair(ranks): pair = judge_kind(2,ranks) lowpair = judge_kind(2,list(reversed(ranks))) if pair and lowpair!=pair: return (pair,lowpair) else: return None
"""對九種牌型的總的排序""" def hand_rank(hand): if type(hand)==tuple: hand = hand[1] ranks = card_ranks(hand) if judge_straight(hand) and judge_flush(hand): #同花順 cards_type = "同花順" return (9,max(ranks)),hand,cards_type elif judge_flush(hand): #同花 cards_type = "同花" return (8,ranks),hand,cards_type elif judge_kind(4,ranks): #炸彈 cards_type = "炸彈" return (7,judge_kind(4,ranks),judge_kind(1,ranks)),hand,cards_type elif judge_kind(3,ranks) and judge_kind(2,ranks): #三帶二 cards_type = "三帶二" return (6,judge_kind(3,ranks),judge_kind(2,ranks)),hand,cards_type elif judge_straight(hand): #順子 cards_type = "順子" return (5,max(ranks)),hand,cards_type elif judge_kind(3,ranks): #三條 cards_type = "三條" return (4,judge_kind(3,ranks),ranks),hand,cards_type elif two_pair(ranks): #兩對 cards_type = "兩對" return (3,two_pair(ranks),ranks),hand,cards_type elif judge_kind(2,ranks): #一對 cards_type = "一對" return (2,judge_kind(2,ranks),ranks),hand,cards_type else: #單張 cards_type = "單張" return (1,ranks),hand,cards_type """判斷撲克大小""" #命名參數key,其為一個函數,用來指定取最大值的方法 def poker(hands): return(max(hands,key=hand_rank))
模塊poker_game.py的代碼如下:
import random #生成隨機數 import comparing_cards """隨機生成己方手牌""" def drawing_cards(): #獲取手牌數字 str_tool1 = '0123456789TJQKA' num1 = [random.randint(2,13) for _ in range(5)] poker_number = [str_tool1[x] for x in num1] #獲取手牌花色 str_tool2 = '0SCDH' num2 = [random.randint(1,4) for _ in range(5)] poker_suit = [str_tool2[x] for x in num2] #生成手牌組合(列表) cards = [poker_number[x]+poker_suit[x] for x in range(5)] return cards #生成四個人的手牌 P1 = drawing_cards() P2 = drawing_cards() P3 = drawing_cards() P4 = drawing_cards() #判斷牌面等級、類型 P1_type = comparing_cards.hand_rank(P1) P2_type = comparing_cards.hand_rank(P2) P3_type = comparing_cards.hand_rank(P3) P4_type = comparing_cards.hand_rank(P4) print("每個人的手牌是:") print('P1',P1_type) print('P2',P2_type) print('P3',P3_type) print('P4',P4_type) winner = comparing_cards.poker((P1_type,P2_type,P3_type,P4_type)) print("獲勝的人的手牌是:") print(winner)
在這里,隨機生成四副手牌,判斷每副手牌的類型並比較大小,選出在四副手牌中獲勝的一方。這里使用了一個很簡單的模擬,並沒有進行更為復雜的設計,當然可以結合德州撲克的游戲規則,進一步設定條件要求,完善該游戲。