こんにちは、みやびのです。
本講座はPythonistaを活用してポーカーゲームを作成する方法について解説するものです。(全5回を予定)
第1回となる今回は、Pythonでポーカーの基本となる処理を作成します。
本記事の内容は以下の通り。
・Pythonでポーカーを作成する場合の基本処理
・Pythonでポーカー作成の実装例と実行例
本記事を読めばPythonでポーカーを作る時にどんな処理を作成すればよいか理解できます。
Pythonでポーカーを作成する場合の基本処理
まずはポーカーの基本処理をPythonで作成する方法を紹介します。
トランプゲームの基本処理
トランプの基本処理は以下の3つです。
・山札の作成
・シャッフル
・カードを引く処理
山札を作成する処理は以下の通り。
for symbol in symbol_list: for number in range(1, 14): card = { 'number' : number, 'symbol' : symbol } # マークと数字を合体させる # 11以上と1は置き換え if number == 1: card['string'] = symbol + 'A' elif number == 11: card['string'] = symbol + 'J' elif number == 12: card['string'] = symbol + 'Q' elif number == 13: card['string'] = symbol + 'K' else: # 10以下ならそのまま card['string'] = symbol + str(number) # カードをリストに追加 card_list.append(card) self.card_list = card_list
トランプカードのデータは比較しやすいように以下の辞書型で作成します。
card = { 'number' : number, # 数字 'symbol' : symbol, # マーク 'string' : symbol + str(number), # マーク + 数字の文字列。 }
シャッフル処理の方法は以下の通り。
random.shuffle()を使うことで簡単に配列のシャッフルができます。
random.shuffle(card_list)
カードを引く処理は以下の通り。
pop(0)とした場合先頭の値を取り出します。
card_list.pop(0)
具体的な手順については「【Python】random.shuffle()の活用例」をお読みください。
ポーカーの役
ポーカーの役を知るために最低限必要な情報は、
・フラッシュが成立しているかどうか?
・ストレートが成立しているかどうか?
・同じ数字は枚数あるか?
・ペアの数はいくつあるか?
・数字が「10,J,Q,K,A」か?
の5つです。
上記情報がわかればポーカーの役を全て表現することができます。
ポーカーの役と条件は以下の通り。
役 | 条件 |
ロイヤルストレートフラッシュ | 「ストレート」かつ「フラッシュ」かつ「数字が10,J,Q,K,A」 |
ストレートフラッシュ | 「ストレート」かつ「フラッシュ」 |
4カード | 同じ数字が4枚 |
フルハウス | 「3カード」かつ残り2枚が「1ペア」 |
フラッシュ | 全て同じマーク |
ストレート | 連続した数字。「数字が10,J,Q,K,A」の場合もストレートが成立 |
3カード | 同じ数字が3枚 |
2ペア | 同じ数字のペアが2つ |
1ペア | 同じ数字のペアが1つ |
ぶた | どの役も成立しない |
役の比較チェックループ
まずはループで1枚ずつ比較して4つの条件をチェックします。
・フラッシュが成立しているかどうか?
・ストレートが成立しているかどうか?
・同じ数字は枚数あるか?
・ペアの数はいくつあるか?
昇順に並べかえると「同じ数字」と「連続した数字」が並ぶので隣同士の比較だけで全チェックができるのでループは4回ですみます。
◆フラッシュが成立しているかどうか?
・フラッシュフラグをTrueにしておく
・直前のカードと現在のカードを比較してマークが違う場合はFalseにする
・同じ場合はそのまま
・最終的にTrueのままならフラッシュ成立
◆ストレートが成立しているかどうか?
・ストレートフラグをTrueにしておく
・直前のカードと現在のカードを比較して連続した数字の場合は継続。違う場合はフラグを落とす
・直前のカードがAかつ現在のカードが10の場合は継続(10,J,Q,K,Aの可能性があるため)
・最終的にTrueのままならストレート成立
◆同じ数字は枚数あるか?
・直前のカードと現在のカードを比較して同じ数字の場合はマッチカウントをカウントアップ
・違う数字の場合はマッチカウントを0に戻す
◆違う数字及び最終ループでやること
・マッチカウントが1の場合はペアカウントをカウントアップ
・マッチカウントが2の場合は3カード(ペアカウントはアップしない)
・カウントが3の場合は4カード(ペアカウントはアップしない)
後はフラグとカウントを見て条件をチェックしていきます。
上記条件をまとめたコードは以下の通り。
# 役のチェック処理 def check_poker_hand(self): # ペア数 pair_count = 0 # 同じ数字のカウント match_count = 0 # 同じ数字の枚数(3カード,4カードチェック用) match_number = 0 # フラッシュの有無フラグ flash_flag = True # ストレートの有無フラグ straight_flag = True # 数字の昇順に並び替える cards = sorted(self.draw_cards, key=lambda x:x['number']) # 比較チェックループ(2枚目から) for i in range(1,5): # 前の数字が同じかチェック if cards[i]['number'] == cards[i - 1]['number']: match_count += 1 # 最終ループチェック if i == 4: if match_count == 1: pair_count += 1 # 3カード以上の場合 elif match_count > 1: match_number = match_count + 1 else: # 違う数字の場合 if match_count == 1: pair_count += 1 # 3カード以上の場合 elif match_count > 1: match_number = match_count + 1 match_count = 0 # 同じマークが続いているかチェック if flash_flag == True and cards[i]['symbol'] != cards[i - 1]['symbol']: flash_flag = False # 数字が連続しているかチェック if straight_flag == True and cards[i]['number'] != cards[i - 1]['number'] + 1: if cards[i]['number'] != 10 or cards[i-1]['number'] != 1: straight_flag = False # 最終手札チェック if straight_flag == True and flash_flag == True: if cards[0]['number'] == 1 and cards[4]['number'] == 13: # ロイヤルストレートフラッシュ hand = 'ロイヤルnストレートフラッシュ' else: # ストレートフラッシュ hand = 'ストレートフラッシュ' elif match_number > 2: if match_number == 4: # 4カード hand = '4カード' else: if pair_count > 0: # フルハウス hand = 'フルハウス' else: # 3カード hand = '3カード' elif flash_flag == True: # フラッシュ hand = 'フラッシュ' elif straight_flag == True: # ストレート hand = 'ストレート' elif pair_count > 0: if pair_count > 1: # 2ペア hand = '2ペア' else: # 1ペア hand = '1ペア' else: # なし hand = 'ぶた' return hand
Pythonでポーカー作成の実装例と実行例
これまでの処理を全てまとめたコードは以下の通り。
import random class TrumpGame: def make_card_list(self): # マークのリスト symbol_list = ['Clubs', 'Hearts', 'Spades', 'Diamonds'] # カードリスト card_list = [] # カードのデータを作成 for symbol in symbol_list: for number in range(1, 14): card = { 'number' : number, 'symbol' : symbol } # マークと数字を合体させる # 11以上と1は置き換え if number == 1: card['string'] = symbol + 'A' elif number == 11: card['string'] = symbol + 'J' elif number == 12: card['string'] = symbol + 'Q' elif number == 13: card['string'] = symbol + 'K' else: # 10以下ならそのまま card['string'] = symbol + str(number) # カードをリストに追加 card_list.append(card) self.card_list = card_list def shuffle(self): # カードをシャッフルする random.shuffle(self.card_list) # 手札を作成する def reset_draw_cards(self, number): card_list = self.make_card_list() self.shuffle() self.draw_cards = [] for i in range(0, number): self.draw_cards.append( self.card_list.pop(0) ) # 役のチェック処理 def check_poker_hand(self): # ペア数 pair_count = 0 # 同じ数字のカウント match_count = 0 # 同じ数字の枚数(3カード,4カードチェック用) match_number = 0 # フラッシュの有無フラグ flash_flag = True # ストレートの有無フラグ straight_flag = True # 数字の昇順に並び替える cards = sorted(self.draw_cards, key=lambda x:x['number']) # 比較チェックループ for i in range(1,5): # 前の数字が同じかチェック if cards[i]['number'] == cards[i - 1]['number']: match_count += 1 # 最終ループチェック if i == 4: if match_count == 1: pair_count += 1 # 3カード以上の場合 elif match_count > 1: match_number = match_count + 1 else: # 違う数字の場合 if match_count == 1: pair_count += 1 # 3カード以上の場合 elif match_count > 1: match_number = match_count + 1 match_count = 0 # 同じマークが続いているかチェック if flash_flag == True and cards[i]['symbol'] != cards[i - 1]['symbol']: flash_flag = False # 数字が連続しているかチェック if straight_flag == True and cards[i]['number'] != cards[i - 1]['number'] + 1: if cards[i]['number'] != 10 or cards[i-1]['number'] != 1: straight_flag = False # 最終手札チェック if straight_flag == True and flash_flag == True: if cards[0]['number'] == 1 and cards[4]['number'] == 13: # ロイヤルストレートフラッシュ hand = 'ロイヤルnストレートフラッシュ' else: # ストレートフラッシュ hand = 'ストレートフラッシュ' elif match_number > 2: if match_number == 4: # 4カード hand = '4カード' else: if pair_count > 0: # フルハウス hand = 'フルハウス' else: # 3カード hand = '3カード' elif flash_flag == True: # フラッシュ hand = 'フラッシュ' elif straight_flag == True: # ストレート hand = 'ストレート' elif pair_count > 0: if pair_count > 1: # 2ペア hand = '2ペア' else: # 1ペア hand = '1ペア' else: # なし hand = 'ぶた' return hand if __name__ == '__main__': tg = TrumpGame() tg.reset_draw_cards(5) for card in tg.draw_cards: print(card['string']) print(tg.check_poker_hand())
※判定に冗長な部分があるのでリファクター予定
◆実行例
Hearts5 Hearts9 Spades4 Clubs9 Hearts2 1ペア
以上、Pythonでポーカーを作成する方法でした。
次回は今回作成したポーカーをPythonistaで画面表示する方法について紹介します。
次回>>第2回 Pythonistaでポーカーゲームを画面表示する
講座TOP>>Pythonista+sceneポーカー作成講座