前回のおさらい
さて、前回は延長戦第2回となる、仮想プレーヤー2名での対戦でした。
playerクラスの設定や、手役ランクを設定して強弱判定などしていきました。
ただ、最後まとめで書いたように、ポーカなのに同一手役だとドローとなってしまっていました。
これは流石に微妙ですよね、同一手役の場合に、カードのハイスコアで勝敗を判断できるようにしてきたいと思います。
| 連載回数 | 実施内容 |
| 第5回 | ドロー5枚で手役の発生確率を計算してみよう |
| 第6回 | コードが汚い、さぁリファクタリングだ 〜初心者でも最低限やれるリファクタリング〜 |
| 第7回 | 仮想プレーヤーと対戦してみよう |
さぁ簡易対戦機能作成の最終回いってみたいと思います。
ゴールイメージ

ハイカードでも勝敗結果を表示できるようになりました。単純に手役ランクで勝利した場合、win:plyaerNameで結果表示していましたが、ハイカード勝利の場合、win_as_high: playerNameとして表示されるようにしています。サンプルではAのハイカードでplayer1が勝利していますね。
実際のコード
それでは実際のコードをみていきましょう。
mport random
import poker_hand_check4card_mark as pkg
class player:
def __init__(self, hand):
self._hand = hand
def hand_result(self):
return list(check_roll(self._hand).values())
class card:
def __init__(self, mark, num):
self.num = num
self.mark = mark
def straight_check(hand_nums):
#ストレートの判定
#1がある場合だけ、14とみなしてストレート判定(数値跨ぎ想定)
if 1 in hand_nums and 10 in hand_nums:
hand_nums.remove(1)
hand_nums.append(14)
#最大値と最小値の差が4になる、平均値の±1の値のカードが含まれる
max_num = max(hand_nums)
min_num = min(hand_nums)
ave_num = (max_num + min_num) / 2
if max_num - min_num == 4 and ave_num in hand_nums and ave_num - 1 in hand_nums and ave_num + 1 in hand_nums:
return True
def check_roll(cards):
hand = [card for card in cards]
hand_nums = [c.num for c in hand]
hand_marks = [c.mark for c in hand]
max_num = max(hand_nums)
if pkg.mark_check(hand_marks) == 5 and straight_check(hand_nums) != True:
return {"flash!!": 6}
elif len(set(hand_nums)) == 4 and pkg.pair_check(hand_nums) == 2:
return {"1ペア": 2}
elif len(set(hand_nums)) == 3 and pkg.pair_check(hand_nums) == 3:
return {"3カード": 4}
elif len(set(hand_nums)) == 3 and pkg.pair_check(hand_nums) == 2:
return {"2ペア": 3}
elif len(set(hand_nums)) == 2 and pkg.pair_check(hand_nums) == 4:
return {"4カード": 8}
elif straight_check(hand_nums) and pkg.mark_check(hand_marks) != 5:
return {"Straight!!": 5}
elif len(set(hand_nums)) == 2 and pkg.pair_check(hand_nums) == 3:
return {"フルハウス": 7}
elif straight_check(hand_nums) and pkg.mark_check(hand_marks) == 5:
if 1 in hand_nums and 10 in hand_nums:
return {"ロイヤルストレートフラッシュ": 10}
else:
return {"ストレートフラッシュ": 9}
else:
high = max(hand_nums)
roll = "high card:{}".format(high)
return {roll: 1}
def battle(player1, player2, hand, hand2, *args, **kwargs):
if player1 > player2:
return "win: player1"
elif player1 max_hand2:
return "win_as_high: player1"
elif max_hand
表示機能も含めて130行ぐらいになり、だいぶ長くなってきましたね。ただ、これまでひとつづつ積み上げてきたコードの累積なので、ほとんどみたことあるコードだと思います。
さて、いつもと同様変更点を中心に少し紹介します。
手役ランク勝負で引き分け時の対応を変えよう
さて、前回作成したbattle関数ですが、今回もここの変更からです。前回と比較しながらみていくとわかりやすいかと思いますので、参考に前回コードも載せておきます。
変更点は黄色マーカ部分です。これまでは手役結果だけで判断できたので、battle関数の引数は各プレーヤの手役ランクだけ引き渡していましたが、今回は追加でハイカードの大小も検証する必要があるため、同一関数ないに無理やり双方プレーヤのハンド情報を引数で渡しています。
【今回のコード】
def battle(player1, player2, hand, hand2, *args, **kwargs):
if player1 > player2:
return "win: player1"
elif player1 < player2:
return "win:player2"
else:
return max_num_battle(hand, hand2)
【前回のコード】
def battle(player1, player2, *args, **kwargs):
if player1 > player2:
return "win: player1"
elif player1
ハイカードの大小を検証するmax_num_battle関数の作成
手役ランクがドローだった場合に動作する、max_num_battle関数です。battle関数の最後に、battle関数で引数に渡されたhand/hand2の値を利用して検討していきます。hand/hand2にはobjが入ってくることを想定して、最初に各引数をリスト化して、最大値を取得しています。
その他は、普通の大小比較ですので、特段難しいことはないですかね。
def max_num_battle(hand, hand2):
max_hand = max([c.num for c in hand])
max_hand2 = max([c.num for c in hand2])
if max_hand > max_hand2:
return "win_as_high: player1"
elif max_hand
main関数内で、battleに渡す値を変えよう
##手役強弱結果表示
result = battle(player1=player1, player2=player2, hand=hand, hand2=hand2)
さて、引数が4つになって順番等はよくわからなくなってくる頃ですね。ということで、名前付きで引数を渡す形にしてみましょう。何が変わったかは、前回のコードと比較するとわかりやすいですね。
黄色のアンダーライン部分が引数に渡す際の名前としてのplayer/player2...となっています。他方で、赤色のアンダーライン部分が実際の引数で前回も利用したものになります。前回と今回で同一部分が赤色アンダーラインになりますので、イメージしやすいかと思います。
【前回のコード】
##手役強弱結果表示
result = battle(player1, player2)
print(result)
まとめ
さぁやっと仮想対戦が成り立つレベルまできました。みなさん本当にお疲れ様でした。
後は、暇な時にリファクタリング題材として、再度poker課題がお目見えすることになりますが、基本機能としては一旦ここまでで打ち止めにします。
超初級題材としては、最低限のレベルの問題だったかなと思います。ノンプロ研のpython初級コース入る前にやってみるにはちょうどいい(?)くらいな、と勝手に思って作ってましたが、実際はどうですかねw
興味がある方は、是非ノンプロ研にもご参加お待ちしております(回し者ではありませんし、一切リターンも入ってきませんw 私も単なる課金勢ですのでw)
![]()
Just a moment...
連載目次: python練習問題~poker手役判定編~

