大家好,波哥又来给大家推荐好东西啦!
如果大家有需要帮忙推荐的工具、框架、应用、脚本可以在文章下方留言,留言中被点赞、推荐回复较多的,波哥就会帮各位提前安排哦!
游戏介绍
21点(Blackjack)是赌场中极为流行的纸牌游戏,玩家的目标是尽量使手牌的点数总和接近21点,但不能超过。Ace(A牌)可以根据需求计为1或11,K、Q、J均为10点,其余牌面按点数计算。游戏分为玩家和庄家两个角色,玩家可以选择“要牌”或“停牌”,而庄家则必须在点数不足17时继续“要牌”。
面向对象设计: 本代码通过类的设计,将游戏中的各个实体(如牌、手牌、筹码等)进行了模块化封装,增强了代码的可读性和复用性。
Card类:表示扑克牌,定义了牌的花色和点数,并通过__str__方法实现直观的显示效果。
Deck类:表示一副完整的扑克牌,实现了生成牌堆、洗牌以及发牌的功能。
Hand类:表示玩家或庄家的手牌,支持添加新牌和调整Ace的点数。
Chips类:记录玩家的筹码信息,支持筹码增减的操作。
逻辑控制和交互:
玩家通过命令行与程序互动,如输入下注金额、选择是否继续要牌等。
使用全局变量playing控制游戏的进行状态,使代码逻辑清晰。
函数封装与复用:
功能性函数如take_bet(处理玩家下注)、hit_or_stand(控制玩家操作)等,封装了具体的逻辑,避免代码冗余。
显示牌面的函数show_some和show_all,分别在游戏不同阶段展示必要信息。
游戏主循环:
主函数blackjack_game负责完整的游戏流程,包括初始化、玩家操作、庄家操作、结算结果以及筹码更新。
外层循环允许玩家在余额未耗尽时选择继续游戏或退出。
代码书写技巧解析
简洁性与可读性:
通过类和函数封装,将复杂逻辑分解为小模块,提升了代码可维护性。
使用清晰的变量命名和注释,使代码含义一目了然。
用户输入校验:
在take_bet函数中,检查用户输入是否合法,确保下注金额不超过余额且为有效整数。
处理玩家选择时,要求输入有效选项,防止程序因错误输入而中断。
随机性处理:
通过random.shuffle实现洗牌功能,模拟真实扑克牌的随机性。
异常处理:
利用try-except块捕获无效输入,防止程序崩溃,并提示用户重新输入。
灵活性与扩展性:
Ace的点数调整逻辑,使游戏能够正确处理特殊情况。
筹码的动态管理,为游戏增加了策略性。
代码
import random
# 定义扑克牌的花色、点数和点数对应的值
suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
values = {'Two': 2, 'Three': 3, 'Four': 4, 'Five': 5, 'Six': 6, 'Seven': 7, 'Eight': 8,
'Nine': 9, 'Ten': 10, 'Jack': 10, 'Queen': 10, 'King': 10, 'Ace': 11}
playing = True # 控制游戏状态
class Card:
"""
定义牌类,表示扑克牌的基本结构
包括花色(suit)和点数(rank)
"""
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def __str__(self):
return f"{self.rank} of {self.suit}"
class Deck:
"""
定义牌堆类,生成一副完整的扑克牌并支持洗牌和发牌
"""
def __init__(self):
self.deck = [Card(suit, rank) for suit in suits for rank in ranks]
def shuffle(self):
"""洗牌"""
random.shuffle(self.deck)
def deal(self):
"""发一张牌"""
return self.deck.pop()
class Hand:
"""
定义手牌类,包含玩家或庄家的牌以及相关的点数逻辑
"""
def __init__(self):
self.cards = [] # 当前手中的牌
self.value = 0 # 当前点数总和
self.aces = 0 # Ace 的数量,用于特殊点数调整
def add_card(self, card):
self.cards.append(card)
self.value += values[card.rank]
if card.rank == 'Ace':
self.aces += 1
def adjust_for_ace(self):
"""
如果点数超过21且有Ace,将Ace的点数从11调整为1
"""
while self.value > 21 and self.aces:
self.value -= 10
self.aces -= 1
class Chips:
"""
定义筹码类,记录玩家当前余额和下注金额
"""
def __init__(self, total=100):
self.total = total # 玩家初始筹码数量
self.bet = 0 # 当前下注金额
def win_bet(self):
self.total += self.bet
def lose_bet(self):
self.total -= self.bet
# 功能函数
def take_bet(chips):
"""
提示玩家下注,并校验输入的合法性
"""
while True:
try:
chips.bet = int(input(f"您的余额是 {chips.total}。请输入您的下注金额: "))
if 0 < chips.bet <= chips.total:
break
print(f"无效金额!下注金额应在 1 到 {chips.total} 之间。")
except ValueError:
print("无效输入!请输入一个整数。")
def hit(deck, hand):
"""玩家要牌"""
hand.add_card(deck.deal())
hand.adjust_for_ace()
def hit_or_stand(deck, hand):
"""
提示玩家选择要牌或停牌
"""
global playing
while True:
choice = input("是否要牌?输入 '1' 要牌,输入 '0' 停牌: ").strip()
if choice == '1':
hit(deck, hand)
break
elif choice == '0':
print("您选择停牌。庄家操作中...")
playing = False
break
else:
print("无效输入,请重新输入。")
def show_some(player, dealer):
"""
显示玩家和庄家的部分手牌
"""
print("\n庄家的手牌:")
print(" [隐藏的牌]", dealer.cards[1])
print("\n您的手牌:", *player.cards, sep='\n ')
def show_all(player, dealer):
"""
显示玩家和庄家的全部手牌
"""
print("\n庄家的手牌:", *dealer.cards, sep='\n ')
print("庄家的点数 =", dealer.value)
print("\n您的手牌:", *player.cards, sep='\n ')
print("您的点数 =", player.value)
def check_winner(player, dealer, chips):
"""
判断游戏结果并处理筹码
"""
if player.value > 21:
print("您爆牌了!")
chips.lose_bet()
elif dealer.value > 21:
print("庄家爆牌!")
chips.win_bet()
elif player.value > dealer.value:
print("您赢了!")
chips.win_bet()
elif player.value < dealer.value:
print("庄家获胜!")
chips.lose_bet()
else:
print("平局!")
# 游戏主循环
def blackjack_game():
"""主游戏逻辑"""
global playing
print("\n欢迎来到 21 点游戏!\n")
print("规则: 尽量接近 21 点,但不能超过。Ace 可以算作 1 或 11。\n")
deck = Deck()
deck.shuffle()
player_hand = Hand()
dealer_hand = Hand()
player_hand.add_card(deck.deal())
player_hand.add_card(deck.deal())
dealer_hand.add_card(deck.deal())
dealer_hand.add_card(deck.deal())
player_chips = Chips()
take_bet(player_chips)
show_some(player_hand, dealer_hand)
while playing:
hit_or_stand(deck, player_hand)
show_some(player_hand, dealer_hand)
if player_hand.value > 21:
break
if player_hand.value <= 21:
while dealer_hand.value < 17:
hit(deck, dealer_hand)
show_all(player_hand, dealer_hand)
check_winner(player_hand, dealer_hand, player_chips)
print("\n您的当前余额为:", player_chips.total)
return player_chips.total
while True:
final_balance = blackjack_game()
if final_balance > 0:
new_game = input("是否再来一局?输入 '1' 开始新游戏,输入 '0' 退出: ").strip()
if new_game == '1':
playing = True
continue
print("感谢参与游戏!祝您好运!")
break
整个交互根据玩家输入和游戏逻辑动态变化,最终打印结果并退出游戏。
欢迎来到 21 点游戏!
规则: 尽量接近 21 点,但不能超过。Ace 可以算作 1 或 11。
您的余额是 100。请输入您的下注金额:
> 20
庄家的手牌:
[隐藏的牌]
Seven of Hearts
您的手牌:
Ace of Spades
Nine of Diamonds
是否要牌?输入 '1' 要牌,输入 '0' 停牌:
> 0
您选择停牌。庄家操作中...
庄家的手牌:
Seven of Hearts
Five of Clubs
庄家的点数 = 12
庄家的手牌:
Seven of Hearts
Five of Clubs
Queen of Diamonds
庄家的点数 = 22
您的手牌:
Ace of Spades
Nine of Diamonds
您的点数 = 20
庄家爆牌!
您赢了!
您的当前余额为: 120
是否再来一局?输入 '1' 开始新游戏,输入 '0' 退出:
> 0
感谢参与游戏!祝您好运!
这份21点游戏代码通过面向对象的设计和功能性函数封装,实现了一个完整、交互性强的游戏系统。无论是从代码简洁性、逻辑清晰度还是用户体验角度,这份代码都具有良好的示范意义。通过进一步优化交互细节和逻辑结构,可以使代码更具扩展性和实用性。
觉得不错别忘了给波哥一键三连哦!