21点游戏
import random
import sys
import time
"""定义扑克牌类,每个对象代表一张扑克牌
"""
class Card:
def __init__(self,card_tpye,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_tpye = card_tpye
self.card_text = card_text
self.card_value = card_value
"""
定义角色类,用来表示庄家(电脑),用户(玩家)
"""
class Role:
def __init__(self):
"""初始化方法"""
#定义列表,用来保存当前角色手中的牌,初始牌为空,保存的类型为Card对象
self.cards = []
#向控制台打印手中所有的牌
def show_card(self):
for card in self.cards:
print(card.card_tpye,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 = 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):
value = sum2 -i * 10
if value <= 21:
return value
return sum2 - A * 10
def burst(self):
"""判断是否爆牌
Return
------
b:bool
是否爆牌,爆牌返回true,否则返回false
"""
#判断是否爆牌,只需要判断最小值是否大于21点即可
return self.get_value("min") > 21
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_type,card_text,all_card_value[index])
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()
#初始时,给庄家发1张牌,给玩家发两张牌
cards.send_card(computer)
cards.send_card(player,num=2)
#显示庄家与玩家手中的牌
computer.show_card()
player.show_card()
#询问玩家是否要牌,如果玩家要牌,则继续发牌,否则停牌
while(True):
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之间停牌,大于21点爆牌
while(True):
print("庄家发牌中……")
#因为庄家不需要询问是否发牌,所以建立时间间隔
time.sleep(1)
#向庄家发牌
cards.send_card(computer)
#显示庄家与玩家的牌
computer.show_card()
player.show_card()
#判断庄家是否爆牌
if computer.burst():
print("庄家爆牌,您赢了")
sys.exit()
#如果没有爆牌,则判断庄家的牌面值
elif computer.get_value("max") >=17:
break
#如果庄家和玩家都没有爆牌则比较点数大小
player_value = player.get_value()
computer_value = computer.get_value()
#比较大小,多者胜出
if player_value > computer_value :
print("您赢了")
elif player_value == computer_value:
print("和棋")
else:
print("您输了")
网友评论