文章目錄
在這篇文章中,我們將學習如何使用 Python 來開發一個隨機產生 5張撲克牌後,可以進一步利用前面所學來進行牌型判斷。透過這個過程,讀者講可掌握 Python 程式設計的核心概念及許多基本用法,同時可以利用運算思維的方式來進行專案分析。讀著若是第一次接觸,也可以考慮參考前 2 篇文章 – 「Python Projects|Poker (1) – 隨機產生 1 張撲克牌」、「Python Projects|Poker (2) – 隨機產生 5 張不重複的撲克牌」。而這些專案都架構在 Python for Beginners 系列文章中,歡迎有興趣的讀者參考。
- 專案目的:幫助初學者對函數處理(建立及使用)、流程控制(迴圈和條件判斷)、資料結構處理(含串列推導使用、集合及字典進行操作分析),進行專案實務的整合應用。
- 開發環境:可參考在 Google Colab 或 Jupyter Notebook 開發環境中練習。
- 使用環境:桌機或NB
- 參考資料:本專案使用的 Python 觀念可參考下面文章
(1). Python for Beginners (9)|串列 (List) 資料型態介紹與使用
(2). Python for Beginners (11)|集合 (Set) 資料型態介紹與使用
(3). Python for Beginners (12)|字典 (Dictionary) 資料型態介紹與使用
(4). Python for Beginners (13)|條件判斷式 – if 相關敘述及使用
(5). Python for Beginners (14)|迴圈控制 – while loops
(6). Python for Beginners (16)|函式 (Functions)
(7). Python for Beginners (17)|模組 (Module)及套件(Package)
(8). Python for Beginners
1. 學習目標
- 理解並使用 Python 的
random
模組來產生隨機數據。 - 學習如何操作和處理串列(List)數據。
- 理解和應用複雜的資料結構,如字典(Dictionary)和集合(Set)。
- 學習使用函數和控制結構(迴圈和條件式)來執行複雜邏輯判斷。
- 學習如何根據規則判斷撲克牌的牌型。
2. 運算思維
- 分解:將牌型判斷問題分解為識別不同牌型的多個子問題。
- 抽象:將撲克牌的牌型判斷過程抽象化,不考慮具體牌的細節定義函式,建立和使用函式(如
generate_poker_hands()
和evaluate_hands()
)來抽象化牌的生成和牌型的判斷過程。。 - 模式識別:識別牌型判斷中的共通模式,如計算相同數字的牌的數量。識別牌型的共同特徵,並思考如何根據數字和花色的出現次數來識別牌型。。
- 演算法設計:設計一個系統化的過程來判斷撲克牌的牌型。
3. 步驟說明
Step 1. 導入 random 模組
首先,我們需要使用 Python 的 random
模組來實現隨機性,這是生成隨機撲克牌的關鍵。
import random
Step 2. 定義撲克牌花色和數字
定義兩個串列(List):suits
和 nums
,它們分別代表撲克牌的四種花色(♠, ♥, ♦, ♣)和十三種數字(A、2 到 K)。
suits = ['♠', '♥', '♦', '♣'] # 花色
nums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] # 數字
Step 3. 建立「產生撲克牌函式」(5張)
- 我們需要一個函式
generate_poker_hands
來產生五張不重複的撲克牌。 - 在這個函式中,使用一個
while
迴圈持續產生撲克牌,直到我們得到五張不同的牌為止。 - 迴圈中使用
random.choice()
隨機選取花色和數字,組成一張牌。 - 檢查這張牌是否已在串列中,以避免重複,並確保最終得到 5 張不重複的牌。
def generate_poker_hands():
cards = []
while len(cards) < 5:
my_suit = random.choice(suits) # 隨機選擇花色
my_num = random.choice(nums) # 隨機選擇數字
card = my_suit + my_num # 組合成一張牌
if card not in cards: # 檢查是否重複
cards.append(card) # 添加到牌組中
return cards
Step 4. 建立「判斷撲克牌牌型函式」
card_suits
儲存了傳入牌的花色,card_nums
則儲存了數字。- 對數字進行排序,以便於判斷順子(Straight)。
- 使用
num_counts
字典來計算每個數字出現的次數,這對於判斷對子、三條、四條等牌型非常重要。 - 判斷同花(Flush):如果花色集合的長度為 1,則所有牌花色相同。
- 判斷順子(Straight):首先檢查是否有 5 個不同的數字(排除對子、三條等情況)。然後,檢查數字是否連續。對於特殊情況(A可以作為最高牌和最低牌),如
{'A', '2', '3', '4', '5'}
也被視為順子。 - 先檢查是否為同花順(Straight flush):同時滿足同花和順子的條件。
- 檢查其他牌型:四條(Four of a kind)、葫蘆(Full house)、同花(Flush)、順子(Straight)、三條(Three of a kind)、兩對(Two pair)、一對(One pair),以及散牌(High card)。
整理上述內容後,將牌型判斷的關鍵邏輯摘要如下:
- 順子(Straight):透過檢查排序後的數字是否連續來判斷。對於
A
的特殊處理(既可以作為最高牌也可以作為最低牌),增加了一個特定條件來判斷A
到5
的順子。 - 同花(Flush):檢查所有牌的花色是否相同。
- 同花順(Straight flush):同時滿足同花和順子的條件。
- 四條、三條、對子:根據數字的出現次數來判斷。例如,四條表示有一個數字出現了四次。
其函式定義可參考如下:
def classify_hand(cards):
card_suits = [card[0] for card in cards]
card_nums = [card[1:] for card in cards]
# 數字排序
card_nums_sorted = sorted(card_nums, key=lambda x: nums.index(x))
num_counts = {num: card_nums.count(num) for num in set(card_nums)}
is_flush = len(set(card_suits)) == 1
is_straight = False
if len(set(card_nums_sorted)) == 5:
indices = [nums.index(num) for num in card_nums_sorted]
if max(indices) - min(indices) == 4:
is_straight = True
elif set(card_nums_sorted) == {'A', '2', '3', '4', '5'}:
is_straight = True
if is_flush and is_straight:
return '同花順(Straight flush)'
elif 4 in num_counts.values():
return '鐵支(Four of a kind)'
elif 3 in num_counts.values() and 2 in num_counts.values():
return '葫蘆(Full house)'
elif is_flush:
return '同花(Flush)'
elif is_straight:
return '順子(Straight)'
elif 3 in num_counts.values():
return '三條(Three of a kind)'
elif list(num_counts.values()).count(2) == 2:
return '兩對(Two pair)'
elif 2 in num_counts.values():
return '一對(One pair)'
return '散牌(High card)'
Step 5. 呼叫「產生撲克牌函式」
呼叫前面定義的產生撲克牌函式 generate_poker_hands() 來隨機產生五張撲克牌。
cards = generate_poker_hands()
Step 6. 呼叫「判斷撲克牌牌型函式」
呼叫判斷撲克牌牌型函式 classify_hand(cards) 來判斷牌型。
hand_type = classify_hand(cards)
Step 7. 列印撲克牌及牌型
列印出隨機產生的 5 張撲克牌及其牌型。
print(f"隨機5張撲克牌是:{cards}")
print(f"牌型為:{hand_type}")
Step 8. 整合所有步驟及程式碼
將上述步驟程式碼整合後,並且試著執行數次,看看是否符合專案目標。你將完成隨機產生 5 張撲克牌及判斷型的專案。
# 導入 random 模組
import random
# 定義撲克牌花色和數字
suits = ['♠', '♥', '♦', '♣'] # 花色
nums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] # 數字
# 建立「產生撲克牌函式」(5張)
def generate_poker_hands():
cards = []
while len(cards) < 5:
my_suit = random.choice(suits) # 隨機選擇花色
my_num = random.choice(nums) # 隨機選擇數字
card = my_suit + my_num # 組合成一張牌
if card not in cards: # 檢查是否重複
cards.append(card) # 添加到牌組中
return cards
# 建立「判斷撲克牌牌型函式」
def classify_hand(cards):
card_suits = [card[0] for card in cards]
card_nums = [card[1:] for card in cards]
# 數字排序
card_nums_sorted = sorted(card_nums, key=lambda x: nums.index(x))
num_counts = {num: card_nums.count(num) for num in set(card_nums)}
is_flush = len(set(card_suits)) == 1
is_straight = False
if len(set(card_nums_sorted)) == 5:
indices = [nums.index(num) for num in card_nums_sorted]
if max(indices) - min(indices) == 4:
is_straight = True
elif set(card_nums_sorted) == {'A', '2', '3', '4', '5'}:
is_straight = True
if is_flush and is_straight:
return '同花順(Straight flush)'
elif 4 in num_counts.values():
return '鐵支(Four of a kind)'
elif 3 in num_counts.values() and 2 in num_counts.values():
return '葫蘆(Full house)'
elif is_flush:
return '同花(Flush)'
elif is_straight:
return '順子(Straight)'
elif 3 in num_counts.values():
return '三條(Three of a kind)'
elif list(num_counts.values()).count(2) == 2:
return '兩對(Two pair)'
elif 2 in num_counts.values():
return '一對(One pair)'
return '散牌(High card)'
# 呼叫「產生撲克牌函式」
cards = generate_poker_hands() # 生成5張隨機撲克牌
# 呼叫「判斷撲克牌牌型函式」
hand_type = classify_hand(cards) # 判斷牌型
# 列印撲克牌及牌型
print(f"隨機5張撲克牌是:{cards}") # 列印產生的撲克牌
print(f"牌型為:{hand_type}") # 列印判斷後的牌型
執行結果:
隨機5張撲克牌是:['♠8', '♦A', '♥A', '♠2', '♥5']
牌型為:一對(One pair)
隨機5張撲克牌是:['♠7', '♦7', '♣4', '♦9', '♥7']
牌型為:三條(Three of a kind)
4. 心得與結論
透過這個小專案,初學者將可學習如何使用 Python 來實作撲克牌的基本操作,從產生隨機撲克牌到判斷牌型。這不僅加深了讀者對 Python 編程的理解,也提升了解決實際問題的能力。透過實踐,我們能夠更好地掌握程式設計的邏輯和技巧,為更複雜的專案奠定基礎。
同時筆者以 Python for Beginners 系列文章為學基礎,先設計了 3 個簡單有趣,且循序漸進地的 Poker 專案,分別是「Python Projects|Poker (1) – 隨機產生 1 張撲克牌」、「Python Projects|Poker (2) – 隨機產生 5 張不重複的撲克牌」、以及本篇「Python Projects|Poker (3) – 判斷撲克牌的牌型」,可讓初學者以非常輕鬆有趣的方式融會貫通 Python 的程式設計。後續也會以此為基礎,持續發表相關專案給讀者。
讀者若想要多了解 Python 的一些基礎知識,可以參考 Python for Beginners 系列文章,當中完整介紹 Python 基礎知識,並運用大量範例及 Quiz 來協助讀者學習。如果讀者也想知道其他重要的科技知識,例如人工智慧、機器學習、深度學習及神經網路相關基礎知識,則可以參考這一本書【從 AI 到 生成式 AI:40 個零程式的實作體驗,培養新世代人工智慧素養】,它將帶領讀者在不會程式、不會數學也OK!的情況下,建立最完整的 AI 入門知識。
如果你喜歡這篇文章歡迎訂閱、分享(請載名出處)與追蹤,並持續關注最新文章。同時 FB 及 IG 也會不定期提供國內外教育與科技新知。