1. 動機
クラスについて学びたいと思い,トランプカードを用いるゲームならばよい練習になるのではないかと考えたこと.
2. バカラのルール
プレイヤーとバンカーが2枚ずつカードを引き,数の和下一桁を得点とする.ただし,Aは1,絵札は0として扱う.以下のルールによりお互い3枚目のカードを引くか決定し,最終的な点数が大きい方の勝利とする.
(ルール)
2枚ずつカードを引いた時点におけるプレイヤーとバンカーの得点を,それぞれ $ S_p, \ S_b $ とする.
-
$ \min (S_p, \ S_b) \leq 5 $ かつ $ \max (S_p, \ S_b) \leq 7 $ のとき,前者の式を満たす方一人(プレイヤー優先)が引く
-
- でプレイヤーの引いたカード $ X $ が $ \left \lfloor \dfrac {X - 9 \cdot \left \lfloor \dfrac {X}{8} \right \rfloor}{2} \right \rfloor + 3 \geq S_b $ を満たすとき,バンカーも引く
3. 実装
トランプカードはスートとランクという2つの属性をもつので, suit
および rank
というインスタンス変数を設定したクラスを for
文で呼び出すと山を生成できます.
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
deck = [Card(i, j) for i in ['Clb', 'Dmd', 'Hrt', 'Spd'] for j in range(1, 14)]
deck.pop(0)
で引いたカードはオブジェクトなので, .suit
でスートに, .rank
でランクにアクセスできます.
カードの得点を求める式は,素直に書くと
self.score = self.rank if self.rank < 10 else 0
ですが,せっかくよい方法を思いついたので
self.score = min(self.rank, 10) % 10
としました.
4. コード
from math import floor
from random import shuffle
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
self.score = min(self.rank, 10) % 10
deck = [Card(i, j) for i in ['Clb', 'Dmd', 'Hrt', 'Spd'] for j in range(1, 14)]
shuffle(deck)
p1, p2 = deck.pop(0), deck.pop(0); p_score = (p1.score + p2.score) % 10
b1, b2 = deck.pop(0), deck.pop(0); b_score = (b1.score + b2.score) % 10
print(f'\nPlayer\'s hand: {p1.suit} {p1.rank: >2}, {p2.suit} {p2.rank: >2}')
print(f'Banker\'s hand: {b1.suit} {b1.rank: >2}, {b2.suit} {b2.rank: >2}')
if p_score <= 5 and b_score <= 7:
p3 = deck.pop(0); p_score = (p_score + p3.score) % 10
print(f'\nPlayer hit another card: {p3.suit} {p3.rank: >2}')
if floor((p3.score - 9 * floor(p3.score / 8)) / 2) + 3 >= b_score:
b3 = deck.pop(0); b_score = (b_score + b3.score) % 10
print(f'Banker hit another card: {b3.suit} {b3.rank: >2}')
elif 7 >= p_score > 5 >= b_score:
b3 = deck.pop(0); b_score = (b_score + b3.score) % 10
print(f'\nBanker hit another card: {b3.suit} {b3.rank: >2}')
print(f'\nPlayer\'s score: {p_score}\nBanker\'s score: {b_score}')
if p_score > b_score:
print('\nPlayer Wins!')
elif b_score > p_score:
print('\nBanker Wins!')
else:
print('\nTie!')
5. 実行結果
Player's hand: Clb 11, Hrt 3
Banker's hand: Spd 6, Dmd 11
Player hit another card: Dmd 8
Player's score: 1
Banker's score: 6
Banker Wins!
6. 終わりに
今回プログラムを書くにあたり最も苦労したのは,プレイヤーとバンカーが3枚目のカードを引く条件を式で表すことです.これの説明にはほとんどの場合表が用られるのですが, if
文を多用するのは避けたかったので,頑張って式に落とし込みました.