“21点扑克牌游戏”又名黑杰克(Blackjack),是一种流行的扑克游戏。该游戏由两到六个人玩,使用除大小王之外的52张牌,游戏者的目标是使手中的牌的点数之和不超过21点且尽量大。 一手扑克牌的点数的计算规则如下:2至9牌,按其原点数计算;10、J、Q、K牌都算作10点(一般记作T,即Ten);A牌(Ace)既可以算作1点也可以算作11点,由玩家自己决定(当玩家停牌时,点数一律视为最大而尽量不爆,如A+K为21,A+5+8为14而不是24) 21点扑克牌游戏设计思路 计算机人工智能AI作为庄家(House),用户作为玩家(Player) 游戏开始时,庄家从洗好的一副牌中发牌:第1张牌发给玩家,第2张牌发给庄家,第3张牌发给玩家,第4张牌发给庄家 然后,询问玩家是否需要继续“拿牌”,通过一次或多次“拿牌”,玩家尝试使手中扑克牌的点数和接近21。(有些地方的规则有最多只能拿五张牌),在这设定了拿了五张牌后不能再拿牌了。 当玩家决定“停牌”(即,不再“拿牌”),则轮到庄家使用下列规则(“庄家规则”)“拿牌”:如果庄家手中的最佳点数之和小于17,则必须“拿牌”;如果点数之和大于或等于17,则“停牌”。 最后,判断输赢。如果庄家和玩家的点数都超过了21点,则平局。如果只有一方超过21点,则另一方赢大,则获胜。如果都没超过21点,则判断是否有一方拿了五张牌,如果两方都拿了五张牌,则再比较点数,大的赢。如果只用一方拿了五张牌,则这一方赢。再判断是否都是21点,是的话判断是否有人的牌是一张A牌加一张十点的牌,有的话该玩家赢。最后如果以上情况都没有出现的话,则比较点数,点数大的赢,点数相同则平局。 程序的流程
(1)初始化一副洗好的扑克牌(调用函数get_shuffled_deck()),初始化庄家和玩家手中的牌为空 (2)依次给玩家和庄家各发两张牌(调用函数deal_card()) (3)玩家拿牌:询问玩家是否继续拿牌,如果是,继续给玩家发牌(调用函数deal_card())。 (4)庄家拿牌:庄家(计算机人工智能AI)按“庄家规则”确定是否拿牌,如果是,继续给庄家发牌(调用函数deal_card())。 (5)分别计算庄家和玩家的点数,比较点数大小,输出输赢结果信息
import random
def get_shuffled_deck():
"""初始化包括52张扑克牌的列表,并混排后返回,表示一副洗好的扑克牌"""
suits = {'?','?','?','?'}#花色
ranks = {'2','3','4','5','6','7','8','9','J','Q','K','A'}#序号
deck = []
for suit in suits:
for rank in ranks:
deck.append(suit + " " + rank)
return deck
#random.shuffle(deck)#shuffule函数打乱字典顺序,由于字典已经是无序的,不需要打乱顺序
def deal_card(deck,participant):#deck为全部扑克牌,participant为参与者的身份的牌
card = deck.pop()#取出打乱后的扑克牌的最上面一张
participant.append(card)#加到参与者牌中
return participant
def card_total(hand):#计算手中牌数总和
values = {'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': 0}#牌为A时不加
result = 0 # 初始化点数和为0
count = 0 #A的个数
# 计算点数和A的个数
for card in hand:
if(card[2] == 'A'):#每张牌是一个花色加一个数字,所以从第二个位置开始,有算空格
count += 1
result += values[card[2:]]
for i in range(count):#加上A牌点数
if(result < 11):
result += 11
else:
result += 1
return result
def victory_card(player,houst):#判断输赢
if(card_total(player) > 21 and card_total(houst) > 21):#都超过了21点
print("平局")
elif(card_total(player) > 21):#玩家超过21点
print("庄家赢")
elif(card_total(houst) > 21):#庄家超过21点
print("玩家赢")
elif(len(player) == 5 and len(houst) == 5):#如果都拿了五张牌,则比较点数
if(card_total(player) > card_total(houst)):
print("玩家赢")
elif(card_total(player) == card_total(houst)):
print("平局")
elif(card_total(player) < card_total(houst)):
print("庄家赢")
elif(len(player) == 5):
print("玩家赢")
elif(len(houst) == 5):
print("庄家赢")
elif(card_total(player) == 21 and card_total(houst) == 21):#如果都是21点
if(A_ten(player) and A_ten(houst)):#判断是否有人牌是A+一张十点的
print("平局")
elif(A_ten(player)):
print("玩家赢")
elif(A_ten(houst)):
print("庄家赢")
else:
print("平局")
else:#不是五张牌,也没有人牌是一张A加一张十点的
if(card_total(player) > card_total(houst)):
print("玩家赢")
elif(card_total(player) < card_total(houst)):
print("庄家赢")
elif(card_total(player) == card_total(houst)):
print("平局")
def A_ten(play):#判断手中牌是否是一张A加一张点数十
count1 = 0
count = 0
if(len(play) != 2):
return False
for i in play:
if(i[2:] == 'A'):
count1 += 1
elif(i[2:] == '10'):
count += 1
elif(i[2:] == 'J'):
count += 1
elif(i[2:] == 'Q'):
count += 1
elif(i[2:] == 'K'):
count += 1
if(count == 1 and count1 == 1):
return True
if __name__ == '__main__':
deck = []
houst = []#庄家的牌
player = []#玩家的牌
deck = get_shuffled_deck()#初始化牌堆
for i in range(2):
deal_card(deck, player)#抽取玩家的前两张牌
deal_card(deck, houst)#抽取庄家的前两张牌
print("玩家的牌为:", player, end=" ")
print("总点数为:", card_total(player))
answer = input("是否继续拿牌?Y/N:")
while(answer == 'Y' or answer == 'y'):#判断玩家是否选择继续拿牌
print("玩家的牌为:",deal_card(deck,player),end=" ")
print("总点数为:",card_total(player))
if(len(player) == 5):#判断玩家牌拿牌是否超过5张,超过则不能拿牌了
print("已经拿了五张牌,无法继续拿牌!")
break
answer = input("是否继续拿牌?Y/N:")
while(True):#庄家拿牌
if(card_total(houst) > 17):#如果庄家的牌小于17点,则拿牌,大于17点则不拿牌
break
if(len(houst) == 5):#庄家拿了五张牌
break
deal_card(deck,houst)
print("庄家的牌为:",houst,end=" ")
print("总点数为:", card_total(houst))
victory_card(player,houst)
?
|