# Python 撲克牌模擬遊戲教學 這篇文章分享如何使用 Python 製作一個簡易的撲克牌模擬遊戲,適合初學者練習類別(class)、發牌邏輯與迴圈模擬。 --- # 用 Python 實作撲克牌玩家系統:物件導向設計介紹 本文將教你如何用 Python 建立一個撲克牌博弈模擬系統的核心類別,包括玩家(Player)、莊家(Dealer)、與賭徒(Gambler)的物件導向設計。 --- ## 🎴 玩家類別設計:Player, Dealer, Gambler 撲克牌遊戲中,不同角色有不同特性。本節使用 Python 類別繼承機制,建立三個類別: - `Player`:基本玩家,具有名字、金額、預設下注金額 - `Dealer`:莊家,繼承自 Player,並加入莊家止損限制 - `Gambler`:賭徒,繼承自 Player,並加入賭徒的預算限制 ### 🧩 程式碼範例: ```python class Player: def __init__(self, name, money, defaultbet): self.name = name self.money = money self.defaultbet = defaultbet class Dealer(Player): def __init__(self, name, money, defaultbet, limit): super().__init__(name, money, defaultbet) self.limit = limit class Gambler(Player): def __init__(self, name, money, defaultbet, budget): super().__init__(name, money, defaultbet) self.budget = budget ``` 範例檔案內容如下: ## 📂 玩家資料載入:從 CSV 建立 Dealer 與 Gambler 玩家資訊通常來自外部資料來源,例如資料庫或 `.csv` 檔案。以下程式碼範例示範如何從 `players.csv` 讀取內容,並依照欄位建立 `Dealer` 和多位 `Gambler` 物件。請注意第 2 行是莊家,第 3 行開始是玩家。 ```python with open("players.csv", "r") as file: lines = file.readlines() dealer_info = lines[1].strip().split(",") dealer1 = Dealer(dealer_info[1], int(dealer_info[2]), int(dealer_info[4]), int(dealer_info[3])) players = [] for i in range(2, len(lines)): info = lines[i].strip().split(",") player = Gambler(info[1], int(info[2]), int(info[4]), int(info[3])) players.append(player) ``` ## 🧠 撲克牌比牌邏輯:get_hand_score() 比賽過程中,需要判斷每位玩家手上的 5 張牌所組成的牌型強度,例如是否為同花順、鐵支或兩對等。本函式 `get_hand_score()` 接收一組手牌,回傳一個二元組 `(等級, 主值)`,用以排序與比較。 - 等級對應如下: - 8:同花順 - 7:鐵支(Four of a kind) - 6:葫蘆(Full House) - 5:同花(Flush) - 4:順子(Straight) - 3:三條(Three of a kind) - 2:兩對(Two pair) - 1:一對(One pair) - 0:高牌(High card) --- ### 🧩 程式碼範例: ```python face_rank = { '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'Jack': 11, 'Queen': 12, 'King': 13, 'Ace': 14 } def get_hand_score(hand): values = [] suits = [] for card in hand: values.append(face_rank[card.face]) suits.append(card.suit) values.sort(reverse=True) counts = {} for v in values: counts[v] = counts.get(v, 0) + 1 count_list = sorted(counts.values(), reverse=True) same_suit = all(s == suits[0] for s in suits) if values == [14, 5, 4, 3, 2]: is_straight = True values = [5, 4, 3, 2, 1] else: is_straight = all(values[i-1] == values[i] + 1 for i in range(1, 5)) if same_suit and is_straight: return (8, values[0]) if count_list == [4, 1]: return (7, [v for v in counts if counts[v] == 4][0]) if count_list == [3, 2]: return (6, [v for v in counts if counts[v] == 3][0]) if same_suit: return (5, values[0]) if is_straight: return (4, values[0]) if count_list == [3, 1, 1]: return (3, [v for v in counts if counts[v] == 3][0]) if count_list == [2, 2, 1]: return (2, max(v for v in counts if counts[v] == 2)) if count_list == [2, 1, 1, 1]: return (1, [v for v in counts if counts[v] == 2][0]) return (0, values[0]) ``` ## 🎮 撲克遊戲主迴圈與勝負判斷 模擬進行 1000 回合撲克牌發牌與比對,條件如下: - 當莊家的資金歸零或全部玩家破產,遊戲提前結束 - 每回合玩家與莊家各發 5 張牌 - 使用 `get_hand_score()` 評估牌力,進行金錢結算 - 若莊家當回合損失超過其 `limit`,則立即停止本回合 最後統計誰的錢最多,作為最終勝利者。 --- ### 🧩 程式碼範例: ```python from deck import DeckOfCards for i in range(1000): all_dead = True for player in players: if player.money > 0: all_dead = False if dealer1.money <= 0 or all_dead: break deck = DeckOfCards() deck.shuffle() dealer1.hand = [] for player in players: player.hand = [] for j in range(5): dealer1.hand.append(deck.deal_card()) for player in players: player.hand.append(deck.deal_card()) dealer_score = get_hand_score(dealer1.hand) dealer_lost = 0 for player in players: if player.money <= 0: continue player_score = get_hand_score(player.hand) if player_score > dealer_score: player.money += dealer1.defaultbet dealer1.money -= dealer1.defaultbet dealer_lost += dealer1.defaultbet elif player_score < dealer_score: player.money -= player.defaultbet dealer1.money += player.defaultbet if dealer_lost >= dealer1.limit: break print(dealer1.name, dealer1.money) for p in players: print(p.name, p.money) print('-'*20) highest = dealer1.money for player in players: if player.money > highest: highest = player.money print("贏家是:") if dealer1.money == highest: print(dealer1.name) for player in players: if player.money == highest: print(player.name) ``` --- ## 🏁 結語與延伸挑戰 透過本篇文章,我們完整實作了一個以 Python 撲克牌為題材的小型模擬遊戲,從資料建模、檔案讀取、牌型評估到勝負邏輯一應俱全。 你可以嘗試進一步擴充這個專案,例如: - 設計更詳細的下注策略與風險模型 - 加入圖形化介面或回合記錄 - 引入統計模擬觀察玩家勝率變化 希望這篇教學對你理解 Python 類別設計與模擬流程有所幫助! > 📬 如果你有任何想法或改進建議,也歡迎留言交流 🙌