You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
3.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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