こんにちは、みやびのです。
本講座は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ポーカー作成講座






