|
|
import random
|
|
|
|
|
|
|
|
|
class Deck:
|
|
|
"""牌组类"""
|
|
|
|
|
|
def __init__(self):
|
|
|
self.cards = []
|
|
|
self.reset()
|
|
|
|
|
|
def reset(self):
|
|
|
"""重置并洗牌"""
|
|
|
suits = ['♠', '♥', '♣', '♦']
|
|
|
ranks = [
|
|
|
('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)
|
|
|
]
|
|
|
self.cards = [(suit, rank[0], rank[1]) for suit in suits for rank in ranks]
|
|
|
random.shuffle(self.cards)
|
|
|
|
|
|
def deal_card(self):
|
|
|
"""发一张牌"""
|
|
|
return self.cards.pop()
|
|
|
|
|
|
|
|
|
class Player:
|
|
|
"""玩家类"""
|
|
|
|
|
|
def __init__(self, name):
|
|
|
self.name = name
|
|
|
self.hand = []
|
|
|
self.score = 0
|
|
|
|
|
|
def add_card(self, card):
|
|
|
"""添加手牌"""
|
|
|
self.hand.append(card)
|
|
|
self.calculate_score()
|
|
|
|
|
|
def calculate_score(self):
|
|
|
"""计算当前分数(处理A的1/11逻辑)"""
|
|
|
self.score = sum(card[2] for card in self.hand)
|
|
|
aces = sum(1 for card in self.hand if card[1] == 'A')
|
|
|
|
|
|
# 如果爆牌且有A,将A视为1分
|
|
|
while self.score > 21 and aces > 0:
|
|
|
self.score -= 10
|
|
|
aces -= 1
|
|
|
|
|
|
def show_hand(self, hide_first=False):
|
|
|
"""显示手牌"""
|
|
|
if hide_first:
|
|
|
print(f"{self.name}的手牌: [隐藏牌], {self.hand[1][0]}{self.hand[1][1]}")
|
|
|
else:
|
|
|
cards = ' '.join([f"{card[0]}{card[1]}" for card in self.hand])
|
|
|
print(f"{self.name}的手牌: {cards} | 分数: {self.score}")
|
|
|
|
|
|
|
|
|
class BlackjackGame:
|
|
|
"""21点游戏类"""
|
|
|
|
|
|
def __init__(self):
|
|
|
self.deck = Deck()
|
|
|
self.player = Player("玩家")
|
|
|
self.dealer = Player("庄家")
|
|
|
|
|
|
def initial_deal(self):
|
|
|
"""初始发牌"""
|
|
|
for _ in range(2):
|
|
|
self.player.add_card(self.deck.deal_card())
|
|
|
self.dealer.add_card(self.deck.deal_card())
|
|
|
|
|
|
def player_turn(self):
|
|
|
"""玩家回合"""
|
|
|
while True:
|
|
|
self.player.show_hand()
|
|
|
if self.player.score >= 21:
|
|
|
return
|
|
|
|
|
|
action = input("要牌(H)还是停牌(S)? ").upper()
|
|
|
if action == 'H':
|
|
|
self.player.add_card(self.deck.deal_card())
|
|
|
elif action == 'S':
|
|
|
break
|
|
|
else:
|
|
|
print("无效输入,请输入H或S")
|
|
|
|
|
|
def dealer_turn(self):
|
|
|
"""庄家回合(自动逻辑)"""
|
|
|
self.dealer.show_hand()
|
|
|
while self.dealer.score < 17:
|
|
|
self.dealer.add_card(self.deck.deal_card())
|
|
|
self.dealer.show_hand()
|
|
|
|
|
|
def check_winner(self):
|
|
|
"""判断胜负"""
|
|
|
p_score = self.player.score
|
|
|
d_score = self.dealer.score
|
|
|
|
|
|
print("\n=== 最终结果 ===")
|
|
|
self.player.show_hand()
|
|
|
self.dealer.show_hand()
|
|
|
|
|
|
if p_score > 21:
|
|
|
print("玩家爆牌,庄家赢!")
|
|
|
elif d_score > 21:
|
|
|
print("庄家爆牌,玩家赢!")
|
|
|
elif p_score > d_score:
|
|
|
print("玩家赢!")
|
|
|
elif d_score > p_score:
|
|
|
print("庄家赢!")
|
|
|
else:
|
|
|
print("平局!")
|
|
|
|
|
|
def play_game(self):
|
|
|
"""开始游戏"""
|
|
|
print("=== 21点游戏 ===")
|
|
|
self.initial_deal()
|
|
|
|
|
|
# 显示庄家的明牌
|
|
|
self.dealer.show_hand(hide_first=True)
|
|
|
|
|
|
# 玩家回合
|
|
|
self.player_turn()
|
|
|
|
|
|
# 如果玩家没爆牌才进行庄家回合
|
|
|
if self.player.score <= 21:
|
|
|
self.dealer_turn()
|
|
|
|
|
|
self.check_winner()
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
while True:
|
|
|
game = BlackjackGame()
|
|
|
game.play_game()
|
|
|
if input("\n再玩一次?(Y/N) ").upper() != 'Y':
|
|
|
break |