こんにちは、みやびのです。
本講座はPythonistaを活用してポーカーゲームを作成する方法について解説するものです。(全5回を予定)
第1回となる今回は、Pythonでポーカーの基本となる処理を作成します。
本記事の内容は以下の通り。
・Pythonでポーカーを作成する場合の基本処理
・Pythonでポーカー作成の実装例と実行例
本記事を読めばPythonでポーカーを作る時にどんな処理を作成すればよいか理解できます。
目次
Pythonでポーカーを作成する場合の基本処理
まずはポーカーの基本処理をPythonで作成する方法を紹介します。
トランプゲームの基本処理
トランプの基本処理は以下の3つです。
・山札の作成
・シャッフル
・カードを引く処理
山札を作成する処理は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 |
トランプカードのデータは比較しやすいように以下の辞書型で作成します。
1 2 3 4 5 | card = { 'number' : number, # 数字 'symbol' : symbol, # マーク 'string' : symbol + str(number), # マーク + 数字の文字列。 } |
シャッフル処理の方法は以下の通り。
random.shuffle()を使うことで簡単に配列のシャッフルができます。
1 | random.shuffle(card_list) |
カードを引く処理は以下の通り。
pop(0)とした場合先頭の値を取り出します。
1 | 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カード(ペアカウントはアップしない)
後はフラグとカウントを見て条件をチェックしていきます。
上記条件をまとめたコードは以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | # 役のチェック処理 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でポーカー作成の実装例と実行例
これまでの処理を全てまとめたコードは以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | 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()) |
◆実行例
1 2 3 4 5 6 | Hearts5 Hearts9 Spades4 Clubs9 Hearts2 1ペア |
以上、Pythonでポーカーを作成する方法でした。
次回は今回作成したポーカーをPythonistaで画面表示する方法について紹介します。
次回>>第2回 Pythonistaでポーカーゲームを画面表示する
講座TOP>>Pythonista+sceneポーカー作成講座