①导入程序运行所需的包。
import random
import sys
import time
②定义扑克牌类,每个对象代表一张扑克牌。
class Card:
"""定义扑克牌类。每个对象代表一张扑克牌。
"""
def __init__(self, card_type, card_text, card_value):
"""初始化方法。
Parameters
-----
card_type : str
牌的类型。(红桃,黑桃,梅花,方片)
card_text : str
牌面显示的文本。(A,K,Q,J)
card_value : int
牌面真实的点数。(如A为1点或11点。K为10点等)
"""
self.card_type = card_type
self.card_text = card_text
self.card_value = card_value
③定义角色类,代表计算机与玩家。
class Role:
"""定义角色类,用来表示电脑(庄家)与我们用户(玩家)。"""
def __init__(self):
"""初始化方法"""
# 定义列表,用来保存当前角色手中的牌。初始牌为空。
self.cards = []
def show_card(self):
"""向控制台打印手中所有的牌。"""
for card in self.cards:
print(card.card_type, card.card_text, sep="", end="")
# 打印当前角色手中所有牌之后,再进行一个换行。
print()
def get_value(self, min_or_max):
"""获得当前角色手中牌的点数。(分为最小值与最大值)。
Parameters
-----
min_or_max : str,值为min或max。
当值为min时,返回的是最小点数。即所有的A当成是1时的点数。(用来判断是否爆牌的情况。)
当值为max时,返回在不爆牌的前提下,可表示的最大点数。此时A可能表示为11,也可能表示为1。
Returns
-----
value : int
返回手中牌的点数。(最小点数或最大点数。)
"""
# 总的点数
sum2 = 0
# 牌面中A的数量。(有几张A)
A = 0
for card in self.cards:
# 累计想加牌面所有的点数
sum2 += card.card_value
# 累计A的数量
if card.card_text == "A":
A += 1
if min_or_max == "max":
# 逐渐减少A的数量,选择一个小于等于21点的最大值。
for i in range(A):
# 在总的点数上减去10,相当于将A当成1点看待。(减去几个10,就相当于
# 是将几个A当成1点来看待。)
value = sum2 - i * 10
if value <= 21:
return value
# 如果把所有的A都当成1,则最大值与最小值是相同的。
return sum2 - A * 10
def burst(self):
"""判断是否爆牌,是返回True,否则返回False。
Returns
-----
b : bool
是否爆牌,爆牌返回True,否则返回False。
"""
# 判断是否爆牌,只需要判断最小值是否大于21点即可。
return self.get_value("min") > 21
④定义扑克牌管理类,负责管理52张牌对象,并能够进行发牌。
class CardManager:
"""扑克牌管理类。管理一整副扑克牌,并且能够进行发牌。"""
def __init__(self):
"""初始化方法"""
# 定义列表,用来保存一整副扑克牌(52张)
self.cards = []
# 定义所有牌的类型。
all_card_type = "♥♠♣♦"
# 定义所有牌面显示的文本
all_card_text = ["A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2"]
# 定义牌面文本对应的真实点数
all_card_value = [11, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2]
# 对牌面类型与牌面文本进行嵌套循环。
for card_type in all_card_type:
for index, card_text in enumerate(all_card_text):
# 创建Card类型的对象。(一张扑克牌)
card = Card(card_type, card_text, all_card_value[index])
# 将创建好的card对象加入到整副扑克牌当中。
self.cards.append(card)
# 洗牌操作
random.shuffle(self.cards)
def send_card(self, role, num=1):
"""给电脑或者玩家发牌。
Parameters
-----
role : Role
电脑或玩家对象。
num : int
发牌的张数。默认为1。
"""
for i in range(num):
card = self.cards.pop()
role.cards.append(card)
⑤创建各个类的对象,实现整个玩牌流程,能够进行要牌,停牌与爆牌判断,并能够比较胜负。
# 创建扑克牌管理器类
cards = CardManager()
# 创建电脑角色对象
computer = Role()
# 创建玩家角色对象
player = Role()
# 初始时,给庄家发一张牌,给玩家发两张牌。
cards.send_card(computer)
cards.send_card(player, 2)
# 显示庄家与玩家手中牌。
computer.show_card()
player.show_card()
# 询问玩家是否要牌,要则继续发牌,否则停牌。
while True:
# 询问玩家是否要牌,y:要牌,n:停牌。
choice = input("是否再要一张牌?【y/n】")
# 玩家选择要牌
if choice == "y":
# 向玩家发牌
cards.send_card(player)
# 发牌后,显示庄家与玩家手中的牌。
computer.show_card()
player.show_card()
# 判断每次玩家要牌后,是否爆牌。如果爆牌,则玩家负。
# 如果没有爆牌,则继续向玩家询问是否要牌。
if player.burst():
print("爆牌,您输了!")
# 退出程序
sys.exit()
# 否则,没有要牌,则退出循环。(停牌)
else:
break
# 玩家停牌之后,庄家发牌。庄家在小于17点时,必须一直要牌。在大于等于17点,小于等于21点时,必须停牌。
while True:
print("庄家发牌中……")
# 因为庄家发牌不需要向玩家那样进行询问,所以没有停顿时间。程序会显示非常快速。
# 为了能有一个很好的间隔性,我们在每次发牌时,暂停1秒。
time.sleep(1)
# 向庄家发牌
cards.send_card(computer)
# 更新显示庄家与玩家手中的牌。
computer.show_card()
player.show_card()
# 判断庄家是否爆牌。如果爆牌,则庄家负。
if computer.burst():
print("庄家爆牌,您赢了!")
sys.exit()
# 如果没有爆牌,则判断庄家的牌面值是否达到17点,如果达到17点,则庄家必须停牌,否则,庄家必须继续要牌。
elif computer.get_value("max") >= 17:
break
# 如果庄家与玩家都没有爆牌,则根据手中的牌面点数,比价大小。
# 获取在不爆牌的前提下,可表示的最大点数。
player_value = player.get_value("max")
computer_value = computer.get_value("max")
# 比较点数大小,多者胜出。如果一样大,则平局。
if player_value > computer_value:
print("您赢了!")
elif player_value == computer_value:
print("平均")
else:
print("您输了")
如何使用Python实现21点小游戏?
猜你喜欢
转载自blog.csdn.net/weixin_41524411/article/details/90242125
今日推荐
周排行