- 推薦自己的專欄:分享一些Python案例,將所學用出來
莊家的牌:♣ 10 ♦ Q
玩家的牌:♦ 4 ♥ 8
是否繼續拿牌(y/n,缺省爲y):y
玩家拿到的牌爲:♦ 4 ♥ 8 ♥ K
爆掉 玩家輸牌!
21點撲克牌遊戲概述
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點撲克牌遊戲設計思路
按下列規則模擬21點撲克牌遊戲:
- 計算機人工智能AI作爲莊家(House),用戶作爲玩家(Player) 。
- 遊戲開始時, 莊家從洗好的一副牌中發牌:第1張牌發給玩家, 第2張牌發給莊家,第3張牌發給玩家,第4張牌發給莊家。
- 然後,詢問玩家是否需要繼續“拿牌”,通過一次或多次“拿牌”,玩家嘗試使手中撲克牌的點數和接近21。如果玩家手中撲克牌的點數之和超過21,則玩家輸牌。
- 當玩家決定 “停牌”(即,不再“拿牌”),則輪到莊家使用下列規則(“莊家規則”)“拿牌”:如果莊家手中的最佳點數之和小於17,則必須“拿牌”:,如果點數之和大於或等於17,則“停牌”。如果莊家的點數之和超過21,則玩家獲勝。
- 最後, 比較玩家和莊家的點數。如果玩家的點數大,則獲勝。如果玩家的點數小,則輸牌。如果點數相同,則平局。但玩家和莊家的牌值都是21點,此時擁有blackjack (一張Ace 和一張點數爲10的牌)方獲勝。
程序的流程如下:
- 初始化一 副洗好的撲克牌,初始化莊家和玩家手中的牌爲空
調用函數get_shuffled_deck()
def get_shuffled_deck():
"""初始化包括52張撲克牌的列表,並混排後返回,表示一副洗好的撲克牌"""
# 花色suits和序號
suits = {'♣', '♠', '♦', '♥'}
ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'}
deck = []
# 創建一副52張的撲克牌
for suit in suits:
for rank in ranks:
deck.append(suit + ' ' + rank)
random.shuffle(deck)
return deck
- 依次給玩家和莊家各發兩張牌
調用函數deal_card()
def deal_card(deck, participant):
"""發一張牌給參與者participant"""
card = deck.pop()
participant.append(card)
return card
- 玩家拿牌: 詢問玩家是否繼續拿牌,如果是,繼續給玩家發牌(調用函數
deal_ card()
) ,並計算玩家牌點compute_total()
,如果大於21點,輸出“玩家輸牌!”信息,並返回。
def compute_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':11}
result = 0 #初始化點數和爲0
numAces = 0 #A的個數
# 計算點數和A的個數
for card in hand:
result += values[card[2:]]
if card[2] == 'A':
numAces += 1
#如果點數和>21,則嘗試把A當做1來計算
# (即減去10),多個A循環減去10,直到點數<=21
while result > 21 and numAces > 0:
result -= 10
numAces -= 1
return result
-
莊家拿牌:莊家(計算機人工智能AI)按“莊家規則”確定是否拿牌,如果是,繼續給莊家發牌(調用函數
deal_card()
) ,並計算莊家牌點compute_total()
,如果大於21點,輸出“玩家贏牌!”信息,並返回。 -
分別計算莊家和玩家的點數,比較點數大小,輸出輸贏結果信息。
語義化:
- shuffled deck,洗牌臺
- deal,發牌
random模塊的函數使用
- random.shuffle(lst) 將序列的所有元素隨機排序。
參數:lst 列表
列表的函數使用
- s.append(x) 把對象x追加到列表s的尾部
- s.pop(i) 彈出下標i處元素,當省略i時彈出列表的最後一個元素
21點撲克牌遊戲實現
import random
def get_shuffled_deck():
"""初始化包括52張撲克牌的列表,並混排後返回,表示一副洗好的撲克牌"""
# 花色suits和序號
suits = {'♣', '♠', '♦', '♥'}
ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'}
deck = []
# 創建一副52張的撲克牌
for suit in suits:
for rank in ranks:
deck.append(suit + ' ' + rank)
random.shuffle(deck)
return deck
def deal_card(deck, participant):
"""發一張牌給參與者participant"""
card = deck.pop()
participant.append(card)
return card
def compute_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':11}
result = 0 #初始化點數和爲0
numAces = 0 #A的個數
# 計算點數和A的個數
for card in hand:
result += values[card[2:]]
if card[2] == 'A':
numAces += 1
#如果點數和>21,則嘗試把A當做1來計算
# (即減去10),多個A循環減去10,直到點數<=21
while result > 21 and numAces > 0:
result -= 10
numAces -= 1
return result
def print_hand(hand):
for card in hand:
print(card, end = ' ')
print()
def blackjack():
"""21點撲克牌遊戲,計算機人工智能AI爲莊家,用戶爲玩家"""
# 初始化一副洗好的撲克牌,初始化莊家和玩家手中的牌爲空
deck = get_shuffled_deck()
house = [] # 莊家的牌
player = [] # 玩家的牌
# 依次給玩家和莊家各發兩張牌
for i in range(2):
deal_card(deck, player)
deal_card(deck, house)
# 打印一手牌
print('莊家的牌:', end = ''); print_hand(house)
print('玩家的牌:', end = ''); print_hand(player)
# 詢問玩家是否繼續拿牌,如果是,繼續給玩家發牌
answer = input('是否繼續拿牌(y/n,缺省爲y):')
while answer in ('', 'y', 'Y'):
card = deal_card(deck, player)
print('玩家拿到的牌爲:', end = ''); print_hand(player)
# 計算牌點
if compute_total(player) > 21:
print('爆掉 玩家輸牌!')
return
answer = input('是否繼續拿牌(y/n,缺省爲y):')
# 莊家(計算機人工智能)按“莊家規則”確定是否拿牌
while compute_total(house) < 17:
card = deal_card(deck, house)
print('莊家拿到的牌爲:', end =''); print_hand(house)
# 計算牌點
if compute_total(house) > 21:
print('爆掉 玩家贏牌!')
return
# 分別計算莊家和玩家的點數,比較點數大小,輸出輸贏結果信息
houseTotal, playerTotal = compute_total(house), compute_total(player)
if houseTotal > playerTotal:
print('莊家贏牌!')
elif houseTotal < playerTotal:
print('玩家贏牌!')
elif houseTotal == 21 and 2 == len(house) < len(player) : # 擁有blackjack的莊家贏牌
print('莊家贏牌!')
elif playerTotal == 21 and 2 == len(player) < len(house) : # 擁有blackjack的玩家贏牌
print('玩家贏牌!')
else:
print('平局!')
if __name__ == '__main__':
blackjack()
運行結果示例一:
莊家的牌:♣ 10 ♦ Q
玩家的牌:♦ 4 ♥ 8
是否繼續拿牌(y/n,缺省爲y):y
玩家拿到的牌爲:♦ 4 ♥ 8 ♥ K
爆掉 玩家輸牌!