以下を参考にして…。
ルール
- 初期カードは52枚。引く際にカードの重複は無いようにする
- プレイヤーとディーラーの2人対戦
- プレーヤーとディーラはそれぞれ所有金額を持ち、所有金額が0になったらゲームは終了
- プレイヤーは実行者、ディーラーは自動的に実行
- プレーヤーは所有金額内の掛け金をベットする
- プレイヤーとディーラーはそれぞれ、カードを2枚引く
- 引いたカードは画面に表示する。
- ディーラーの2枚目のカードは分からないようにする
- その後、先にプレイヤーがカードを引く。
- プレイヤーが21を超えていたらバースト、その時点でゲーム終了
- プレイヤーは、カードを引くたびに、次のカードを引くか選択できる
- プレイヤーが引き終えたら、その後ディーラーは、自分の手札が17以上になるまで引き続ける
- プレイヤーとディーラーが引き終えたら勝負。より21に近い方の勝ち
- JとQとKは10として扱う
- Aは1と11の両方の値を持ち、より強い”手”になるように値をとる
コード
import random
# Constants
SUITS = ('♡', '◇', '♠', '♣')
RANKS = ('A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K')
CARD_VAL = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'J':10, 'Q':10, 'K':10, 'A':11}
class Card(object):
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def __str__(self):
return self.suit + ' ' + self.rank
class Deck(object):
def __init__(self):
self.deck = []
for suit in SUITS:
for rank in RANKS:
self.deck.append(Card(suit,rank))
def shuffle(self):
random.shuffle(self.deck)
def deal(self):
dealt_card = self.deck.pop()
return dealt_card
class Hand(object):
def __init__(self):
self.cards = []
self.value = 0
self.aces = 0
def add_card(self, card):
self.cards.append(card)
self.value += CARD_VAL[card.rank]
if card.rank == 'A':
self.aces += 1
def adjust_for_ace(self):
while self.value > 21 and self.aces:
self.value -= 10
self.aces -= 1
class Money(object):
def __init__(self, total=1000):
self.total = total
self.player_money = 100
self.dealer_money = self.total-100
self.bet = 0
def player_win(self):
self.player_money += self.bet
self.dealer_money -= self.bet
def player_lose(self):
self.player_money -= self.bet
self.dealer_money += self.bet
def take_bet(money):
while True:
try:
money.bet = int(input(f'\nいくら賭けますか?\n最大で{money.player_money}賭けることができます。\n'))
except ValueError:
print('\n半角数字で入力してください。')
else:
if money.bet > money.player_money:
print(f"\nお金が足りません。")
else:
break
def hit(deck, hand):
hand.add_card(deck.deal())
hand.adjust_for_ace()
def ask_hit_or_stand(deck, hand, player_turn):
while True:
x = input("\nカードを引きますか?引くときは y 引かないときは n を半角で入力してください。")
if x == 'y':
hit(deck,hand)
elif x == 'n':
print("ディーラーのターンです。")
player_turn = False
return player_turn
else:
print("引くときは y 引かないときは n を半角で入力してください。")
continue
return player_turn
def show_cards_first(player, dealer):
print("\nディーラー:")
print('', dealer.cards[0])
print(" ??")
print("\nプレーヤー:", *player.cards, sep='\n ')
def show_cards_last(player, dealer):
print("\nディーラー:", *dealer.cards, sep='\n ')
print("ディーラーの合計:", dealer.value)
print("\nプレーヤー:", *player.cards, sep='\n ')
print("プレーヤーの合計", player.value)
def player_busts(player, dealer, money):
print("プレーヤーがバーストしました。")
money.player_lose()
def player_wins(player, dealer, money):
print("プレーヤーが勝ちました。")
money.player_win()
def dealer_busts(player, dealer, money):
print("ディーラーがバーストしました。")
money.player_win()
def dealer_wins(player, dealer, money):
print("ディーラーが勝ちました。")
money.player_lose()
def push(player, dealer):
print("プッシュです。")
def main():
player_turn = True
count_game = 0
count_win = 0
count_tie = 0
money = Money()
print(f'ブラックジャックです。\n\
プレーヤーは{money.player_money}の金額を持っています。\n\
ディーラーは{money.dealer_money}の金額を持っています。\n\
ディーラは17以上になるまで必ずカードを引きます。 \n\
エースは1か11としてカウントできます。')
while True:
count_game += 1
print('\nカードをシャッフルします。')
deck = Deck()
deck.shuffle()
# 賭ける
take_bet(money)
print('\nカードを配ります。')
player_hand = Hand()
player_hand.add_card(deck.deal())
player_hand.add_card(deck.deal())
dealer_hand = Hand()
dealer_hand.add_card(deck.deal())
dealer_hand.add_card(deck.deal())
# カードを見せる。
show_cards_first(player_hand, dealer_hand)
print('\nプレーヤーのターンです。')
while player_turn:
# プレーヤーがカードを引く。
player_turn = ask_hit_or_stand(deck, player_hand, player_turn)
show_cards_first(player_hand, dealer_hand)
# プレーヤーがバースト。
if player_hand.value > 21:
player_busts(player_hand, dealer_hand, money)
break
# プレーヤーがバーストしなければディーラーのターン。
if player_hand.value <= 21:
print('\nディーラーのターンです。')
# ディーラーは17以上にならなければカードを引き続ける。
while dealer_hand.value < 17:
hit(deck, dealer_hand)
# カードを見せる。
show_cards_last(player_hand,dealer_hand)
# ディーラがバースト
if dealer_hand.value > 21:
dealer_busts(player_hand, dealer_hand, money)
count_win += 1
# ディーラーの勝ち
elif dealer_hand.value > player_hand.value:
dealer_wins(player_hand, dealer_hand, money)
# プレーヤーの勝ち
elif dealer_hand.value < player_hand.value:
player_wins(player_hand, dealer_hand, money)
count_win += 1
# 引き分け
else:
push(player_hand,dealer_hand)
count_tie += 1
# プレーヤー破産でゲーム終了
if money.player_money <= 0:
print('プレーヤーは破産しました。')
break
# ディーラー破産でゲーム終了
if money.dealer_money <= 0:
print('ディーラーは破産しました。')
break
# 残金の表示
print(f"\nプレーヤーの残金は、{money.player_money}です。\nディーラ―の残金は、{money.dealer_money}です。")
# ゲームを続けるか?
new_game = input("続けて勝負しますか? 続けるときは y を半角で入力してください。 ")
if new_game == 'y':
player_turn=True
continue
else:
print("\nゲームを終了します。")
break
# 勝率の表示
print('\nあなたの勝率は{:.0%}でした。'.format((count_win + 0.5*count_tie) / count_game))
if __name__ == '__main__':
main()