階段三
分段實作
七個函式,一次寫一小步
每個函式前面都有一頁「語法熱身」,忘記的先看那頁
熱身
寫 create_deck 之前,先複習兩件事
① 空 list + append:東西一個一個加進去
fruits = [] # 先開一個空的
fruits.append("蘋果") # ['蘋果']
fruits.append("香蕉") # ['蘋果', '香蕉']
print(len(fruits)) # 2
② 兩層 for:外層跑一次,內層全部跑一輪
for a in ["X", "Y"]:
for b in [1, 2, 3]:
print(a + str(b))
# X1 X2 X3 Y1 Y2 Y3 ← 共 2 × 3 = 6 個
連起來想
4 種花色 × 13 種牌面 = 52 張。這正好就是兩層 for 迴圈的形狀。
create_deck — 步驟 1/4
先把兩個素材準備好
用兩個 list 分別存「四種花色」跟「十三種牌面」。
# 目標:印出來要長這樣
['♠', '♥', '♦', '♣']
['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
4 13
suits = ["♠", "♥", "♦", "♣"]
ranks = ["A", , "3", "4", "5", "6", "7", "8", "9", , "J", "Q", "K"]
print(suits)
print(len(suits), len(ranks))
"2"
2
"10"
10
牌面要用字串 存。之後查點數表時 key 是 "2",寫成數字 2 會查不到。
提示
顯示答案
兩個變數,各自是一個 list。牌面全部都用字串 存(包含數字,"2" 不是 2),這樣等一下查點數表才不會出問題。
suits = ["♠", "♥", "♦", "♣"]
ranks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
print(suits)
print(ranks)
print(len(suits), len(ranks))
create_deck — 步驟 2/4
先做出「一個花色」的 13 張
用一層 for 迴圈,把 13 個牌面都接上 "♠",放進 deck。
# 預期輸出:
['A♠', '2♠', '3♠', '4♠', '5♠', '6♠', '7♠', '8♠', '9♠', '10♠', 'J♠', 'Q♠', 'K♠']
13
deck = []
for r in ranks:
deck. ( )
print(deck)
print(len(deck))
append
add
insert
r + "♠"
"♠" + r
r, "♠"
"♠" + r 會變成 ♠A,花色跑到前面去了。
提示
顯示答案
先開一個空的 deck = [],然後跑過 ranks 裡的每一個牌面,把「牌面 + 花色」append 進去。字串用 + 就能接起來。
deck = []
for r in ranks:
deck.append(r + "♠")
print(deck)
print(len(deck))
create_deck — 步驟 3/4
四個花色,一次做完 52 張
在剛剛的迴圈外面 再包一層,跑過每一種花色。
# 預期輸出:
52
前 5 張:['A♠', '2♠', '3♠', '4♠', '5♠']
最後 1 張:K♣
deck = []
for s in :
for r in :
deck.append( )
print(len(deck))
print(deck[0:5])
suits
ranks
r + s
s + r
deck
外層跑花色、內層跑牌面。順序顛倒的話 牌的排列會變成 A♠ A♥ A♦…,不是一個花色一疊。
提示
顯示答案
外層跑 suits,內層跑 ranks。內層那段就是步驟 2 寫好的東西,只是把寫死的 "♠" 換成外層的變數。不要在迴圈裡面才 deck = [] ,那樣每換一個花色就會清空一次。
suits = ["♠", "♥", "♦", "♣"]
ranks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
deck = []
for s in suits:
for r in ranks:
deck.append(r + s)
print(len(deck))
print("前 5 張:", deck[0:5])
print("最後 1 張:", deck[-1])
補充:第五章的一行寫法
deck = [r + s for s in suits for r in ranks] 結果一模一樣。
看得懂就好,用迴圈寫沒有比較差 —— 迴圈版每一步在幹嘛看得更清楚。
create_deck — 步驟 4/4
包成函式,順便洗牌
把上面整段包成 create_deck(),洗好牌之後 return 出來。
# 呼叫方式:
deck = create_deck()
print(len(deck))
print(deck[0:5])
# 預期輸出(順序每次都不一樣):
52
['7♦', 'K♠', '2♣', 'A♥', '10♦']
import random
def create_deck():
deck = []
for s in ["♠", "♥", "♦", "♣"]:
for r in ["A","2","3","4","5","6","7","8","9","10","J","Q","K"]:
deck.append(r + s)
random. (deck)
deck
deck = create_deck()
print(len(deck), deck[0:3])
shuffle
choice
sample
return
print
break
shuffle 是直接把 deck 洗亂 ,不會回傳新的 list,所以不要寫 deck = random.shuffle(deck)。
提示
顯示答案
洗牌要用 random 模組,程式最上面加一行 import random,然後 random.shuffle(deck)。 注意:shuffle 是直接把 deck 洗亂 ,它不會回傳新的 list,所以不要 寫 deck = random.shuffle(deck)。
import random
def create_deck():
suits = ["♠", "♥", "♦", "♣"]
ranks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
deck = []
for s in suits:
for r in ranks:
deck.append(r + s)
random.shuffle(deck)
return deck
deck = create_deck()
print(len(deck))
print(deck[0:5])
熱身
寫 deal 之前:pop() 在做什麼?
pop() 會「拿走並交回」最後一個
deck = ["A♠", "2♠", "3♠"]
card = deck.pop() # card 拿到 "3♠"
print(card) # 3♠
print(deck) # ['A♠', '2♠'] ← 只剩兩張了
為什麼抽牌剛好用 pop()
抽一張牌本來就是兩件事同時發生:牌堆少一張 + 手上多一張 。
pop() 一次做完,配上 append() 剛好就是完整的發牌動作。
合起來就是一次發牌
hand.append(deck.pop()) # 從牌堆拿走一張,直接放進手牌
deal — 步驟 1/2
先寫「抽一張」
寫一個 deal(deck, hand),從 deck 抽一張放進 hand。
# 呼叫方式:
deck = ["A♠", "2♠", "3♠"]
hand = []
deal(deck, hand)
print(hand)
print(deck)
# 預期輸出:
['3♠']
['A♠', '2♠']
def deal(deck, hand):
hand. (deck. ())
deck = ["A♠", "2♠", "3♠"]
hand = []
deal(deck, hand)
print(hand)
print(deck)
append
pop
remove
insert
add
pop() 會「拿走並交回 」最後一個;remove() 只刪掉,不會把牌交給你。
提示
顯示答案
函式裡只要一行。而且這個函式不需要 return —— 因為它是直接去改 hand 這個 list,改完外面就看得到了。
def deal(deck, hand):
hand.append(deck.pop())
deck = ["A♠", "2♠", "3♠"]
hand = []
deal(deck, hand)
print(hand)
print(deck)
deal — 步驟 2/2
加上「一次抽 n 張」
開局要一次發 2 張。加上參數 n,預設是 1 。
# 呼叫方式:
deck = create_deck()
player = []
deal(deck, player, 2) # 發兩張
deal(deck, player) # 沒寫 n,預設發一張
print(len(player))
print(len(deck))
# 預期輸出:
3
49
def deal(deck, hand, ):
for i in :
hand.append(deck.pop())
deck = create_deck()
player = []
deal(deck, player, 2)
deal(deck, player)
print(len(player), len(deck))
n=1
n
n=0
range(n)
range(1, n)
range(0)
預設值寫成 n=1,這樣 deal(deck, hand) 不寫張數時就是發一張。
提示
顯示答案
「重複做 n 次」→ 用 for i in range(n)。預設值寫在參數後面:n=1。
def deal(deck, hand, n=1):
for i in range(n):
hand.append(deck.pop())
deck = create_deck()
player = []
deal(deck, player, 2)
deal(deck, player)
print(len(player))
print(len(deck))
熱身
寫 hand_value 之前:兩個必備技巧
① 用 dict 查點數
values = {"A": 11, "K": 10, "Q": 10, "J": 10, "9": 9}
print(values["K"]) # 10
print(values["9"]) # 9 ← key 是字串 "9",不是數字 9
② 把花色切掉:card[:-1]
card = "K♠"
print(card[:-1]) # K ← 從頭取到「最後一個之前」
print(card[-1]) # ♠ ← 最後一個
card = "10♥"
print(card[:-1]) # 10 ← 兩位數也切得對!
為什麼不用 card[0]
"10♥"[0] 會得到 "1",不是 "10",10 點的牌全部都會算錯。
從後面切 才安全,因為花色永遠只有一個字。
hand_value — 步驟 1/4
先算最單純的:只有數字牌
假設手牌裡沒有 A、J、Q、K,把點數加總 return 出來。
# 呼叫方式:
print(hand_value(["7♠", "5♥"]))
print(hand_value(["2♦", "3♣", "9♠"]))
# 預期輸出:
12
14
def hand_value(hand):
values = {"2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10}
total = 0
for card in hand:
rank = card[ ]
total = total + values[ ]
total
print(hand_value(["7♠", "5♥"]), hand_value(["2♦", "3♣", "9♠"]))
:-1
0
-1
rank
card
return
print
card[0] 遇到 "10♥" 只會拿到 "1",10 點的牌全部算錯;card[-1] 拿到的是花色。
提示
顯示答案
先開一個 total = 0,跑過手牌每一張,把花色切掉、查表拿到點數、加進 total。 最後別忘了 return total。
def hand_value(hand):
values = {"2":2, "3":3, "4":4, "5":5, "6":6,
"7":7, "8":8, "9":9, "10":10}
total = 0
for card in hand:
rank = card[:-1]
total = total + values[rank]
return total
print(hand_value(["7♠", "5♥"]))
print(hand_value(["2♦", "3♣", "9♠"]))
hand_value — 步驟 2/4
加上 J、Q、K
三張都是 10 點。這步只要改 dict ,迴圈完全不用動。
# 呼叫方式:
print(hand_value(["K♠", "Q♥"]))
print(hand_value(["J♦", "5♣"]))
# 預期輸出:
20
15
def hand_value(hand):
values = {"2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10,
"J": , "Q": , "K": }
total = 0
for card in hand:
total = total + values[card[:-1]]
return total
print(hand_value(["K♠", "Q♥"]), hand_value(["J♦", "5♣"]))
10
10
10
11
1
0
這一步只要改 dict ,迴圈一個字都不用動 —— 這就是用 dict 而不是 if/elif 的好處。
提示
顯示答案
在 values 裡多加三個 key:"J"、"Q"、"K",值都是 10。其他一個字都不用改 —— 這就是用 dict 而不是 if/elif 的好處。
def hand_value(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}
total = 0
for card in hand:
rank = card[:-1]
total = total + values[rank]
return total
print(hand_value(["K♠", "Q♥"]))
print(hand_value(["J♦", "5♣"]))
hand_value — 步驟 3/4
A 先全部當 11,順便數有幾張
加上 "A": 11,並用一個變數 aces 記錄手上有幾張 A。
# 呼叫方式:
print(hand_value(["A♠", "K♥"]))
print(hand_value(["A♠", "A♥", "9♦"]))
# 這步的預期輸出(還沒處理爆牌,所以第二筆是錯的,正常):
21
31
def hand_value(hand):
values = {"A": , "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8,
"9":9, "10":10, "J":10, "Q":10, "K":10}
total = 0
aces =
for card in hand:
rank = card[:-1]
total = total + values[rank]
if rank == :
aces = aces + 1
return total
print(hand_value(["A♠", "K♥"]), hand_value(["A♠", "A♥", "9♦"]))
11
1
0
1
"A"
A
這一步還沒處理爆牌,所以第二筆會印出 31,是正常的。
提示
顯示答案
在迴圈裡多一個判斷:如果這張的 rank 是 "A",就 aces = aces + 1。 記得 aces = 0 要放在迴圈外面 ,跟 total 一樣。
def hand_value(hand):
values = {"A":11, "2":2, "3":3, "4":4, "5":5, "6":6,
"7":7, "8":8, "9":9, "10":10,
"J":10, "Q":10, "K":10}
total = 0
aces = 0
for card in hand:
rank = card[:-1]
total = total + values[rank]
if rank == "A":
aces = aces + 1
return total
print(hand_value(["A♠", "K♥"]))
print(hand_value(["A♠", "A♥", "9♦"]))
hand_value — 步驟 4/4
爆了就把 A 改成 1
在 return 之前補上那段 while(就是階段二選過的答案)。
# 呼叫方式:
print(hand_value(["A♠", "K♥"]))
print(hand_value(["A♠", "9♥", "5♦"]))
print(hand_value(["A♠", "A♥", "9♦"]))
print(hand_value(["A♠", "A♥", "K♦"]))
print(hand_value(["K♠", "Q♥", "J♦"]))
# 預期輸出:
21
15
21
12
30
def hand_value(hand):
values = {"A":11, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8,
"9":9, "10":10, "J":10, "Q":10, "K":10}
total = 0
aces = 0
for card in hand:
rank = card[:-1]
total = total + values[rank]
if rank == "A":
aces = aces + 1
while total > 21 :
total = total -
aces = aces - 1
return total
print(hand_value(["A♠","K♥"]), hand_value(["A♠","9♥","5♦"]),
hand_value(["A♠","A♥","9♦"]), hand_value(["A♠","A♥","K♦"]),
hand_value(["K♠","Q♥","J♦"]))
and
or
aces > 0
aces == 0
10
11
沒有 aces > 0 的話,K♠ Q♥ J♦(30 點、沒有 A)會被一路減到 0。
提示
顯示答案
一張 A 從 11 變 1,總點數就是 減 10 ,同時「還能改的 A」也少一張。 條件要兩個同時成立:還在爆牌,而且還有 A 可以改。
def hand_value(hand):
values = {"A":11, "2":2, "3":3, "4":4, "5":5, "6":6,
"7":7, "8":8, "9":9, "10":10,
"J":10, "Q":10, "K":10}
total = 0
aces = 0
for card in hand:
rank = card[:-1]
total = total + values[rank]
if rank == "A":
aces = aces + 1
while total > 21 and aces > 0:
total = total - 10
aces = aces - 1
return total
最後一筆很重要
["K♠","Q♥","J♦"] 要得到 30 ,不是 0。
因為 aces 是 0,while 一次都不會跑 —— 沒有 A 就不該亂減。
熱身
寫 show_hand 之前:把 list 印成一句話
直接 print 一個 list 很醜
hand = ["A♠", "K♥"]
print(hand) # ['A♠', 'K♥'] ← 中括號跟引號都跑出來了
用迴圈把它接成一個字串
hand = ["A♠", "K♥"]
text = ""
for card in hand:
text = text + card + " "
print(text) # A♠ K♥
再用 f-string 排版
name = "你"
print(f"{name}:{text}({hand_value(hand)} 點)")
# 你:A♠ K♥ (21 點)
show_hand — 步驟 1/2
基本版:印出名字、手牌、點數
# 呼叫方式:
show_hand("你", ["A♠", "K♥"])
show_hand("莊家", ["7♦", "5♣", "9♠"])
# 預期輸出:
你:A♠ K♥ (21 點)
莊家:7♦ 5♣ 9♠ (21 點)
def show_hand(name, hand):
text = ""
for card in hand:
text =
print(f"{name}:{text}({ } 點)")
show_hand("你", ["A♠", "K♥"])
show_hand("莊家", ["7♦", "5♣", "9♠"])
text + card + " "
card + " "
text + " "
hand_value(hand)
hand_value
total
少了前面的 text +,每一圈都會把之前接好的字蓋掉,最後只剩最後一張牌。
提示
顯示答案
收兩個參數:name 和 hand。先用迴圈把手牌接成一個字串,再用 f-string 一次印出來。 點數直接呼叫剛剛寫好的 hand_value(hand) ,不用重寫一次 —— 函式可以呼叫函式。
def show_hand(name, hand):
text = ""
for card in hand:
text = text + card + " "
print(f"{name}:{text}({hand_value(hand)} 點)")
show_hand("你", ["A♠", "K♥"])
show_hand("莊家", ["7♦", "5♣", "9♠"])
show_hand — 步驟 2/2
加上「蓋一張牌」
加參數 hide_second,預設 False。如果是 True,只顯示第一張,其他用 ? 代替,而且不能洩漏點數 。
# 呼叫方式:
show_hand("莊家", ["7♦", "J♣"], True)
show_hand("莊家", ["7♦", "J♣"])
# 預期輸出:
莊家:7♦ ?
莊家:7♦ J♣ (17 點)
def show_hand(name, hand, ):
if :
print(f"{name}:{hand[0]} ?")
else:
text = ""
for card in hand:
text = text + card + " "
print(f"{name}:{text}({hand_value(hand)} 點)")
show_hand("莊家", ["7♦", "J♣"], True)
show_hand("莊家", ["7♦", "J♣"])
hide_second=False
hide_second=True
hide_second
hand[0]
name
預設值要是 False —— 平常都是全部顯示,只有玩家回合時的莊家才傳 True。
提示
顯示答案
用 if hide_second: 分成兩條路。蓋牌那條只要印 hand[0] 加上 ?,不要印點數 ,不然玩家就偷看到答案了。
def show_hand(name, hand, hide_second=False):
if hide_second:
print(f"{name}:{hand[0]} ?")
else:
text = ""
for card in hand:
text = text + card + " "
print(f"{name}:{text}({hand_value(hand)} 點)")
熱身
寫 player_turn 之前:while True + break
「一直重複,直到某件事發生」
while True: # 條件永遠成立 = 無限重複
ans = input("要繼續嗎?(y/n) ")
if ans == "n":
break # 跳出迴圈
print("繼續!")
為什麼玩家回合要用 while
因為不知道玩家會抽幾次 —— 可能一次都不抽,也可能連抽五張。
次數不確定的重複用 while;次數確定(像發兩張牌)才用 for。
記得
沒有 break 的 while True 會跑到天荒地老。寫下 while True 的同時就先想好怎麼跳出去。
player_turn — 步驟 1/3
先做最笨的版本:一直抽到爆
先不管玩家想不想抽,就一路抽到超過 21 為止。目的是先把迴圈的形狀寫對。
# 呼叫方式:
deck = create_deck()
hand = []
deal(deck, hand, 2)
player_turn(deck, hand)
# 預期輸出(例):
你:5♠ 3♥ (8 點)
你:5♠ 3♥ 7♦ (15 點)
你:5♠ 3♥ 7♦ K♣ (25 點)
爆牌了!
def player_turn(deck, hand):
:
show_hand("你", hand)
if hand_value(hand) > 21:
print("爆牌了!")
deal(deck, hand)
deck = create_deck()
hand = []
deal(deck, hand, 2)
player_turn(deck, hand)
while True
for i in range(3)
if True
break
continue
return
用 continue 的話爆牌後不會停,會一直抽到牌堆空掉才出錯。
提示
顯示答案
每一圈做三件事:顯示手牌 → 檢查爆了沒 → 抽一張 。爆了就 print 訊息然後 break。
def player_turn(deck, hand):
while True:
show_hand("你", hand)
if hand_value(hand) > 21:
print("爆牌了!")
break
deal(deck, hand)
player_turn — 步驟 2/3
讓玩家自己決定抽或停
用 input() 問玩家:輸入 h 抽牌、輸入 s 停牌(停牌就跳出迴圈)。
# 預期畫面:
你:5♠ 3♥ (8 點)
要抽牌(h)還是停牌(s)?h
抽到:7♦
你:5♠ 3♥ 7♦ (15 點)
要抽牌(h)還是停牌(s)?s
你選擇停牌。
def player_turn(deck, hand):
while True:
show_hand("你", hand)
if hand_value(hand) > 21:
print("爆牌了!")
break
choice = ("要抽牌(h)還是停牌(s)?")
if choice == "h":
deal(deck, hand)
print(f"抽到:{hand[ ]}")
else:
print("你選擇停牌。")
deck = create_deck()
hand = []
deal(deck, hand, 2)
player_turn(deck, hand)
input
print
str
-1
0
1
break
continue
剛抽到的那張是手牌的最後一張 ,所以是 hand[-1]。
提示
顯示答案
把「無條件 deal」改成 if choice == "h": 才 deal,else: 就 break。 剛抽到的那張是手牌的最後一張 → hand[-1]。
def player_turn(deck, hand):
while True:
show_hand("你", hand)
if hand_value(hand) > 21:
print("爆牌了!")
break
choice = input("要抽牌(h)還是停牌(s)?")
if choice == "h":
deal(deck, hand)
print(f"抽到:{hand[-1]}")
else:
print("你選擇停牌。")
break
player_turn — 步驟 3/3
補上:剛好 21 點就不用再問了
如果總點數剛好等於 21 ,直接印出恭喜並結束回合 —— 再抽一定爆,沒有必要問。
# 預期畫面:
你:A♠ K♥ (21 點)
Blackjack!
# 三種結束方式:
# 1. 爆牌 2. 剛好 21 3. 玩家自己選停牌
def player_turn(deck, hand):
while True:
show_hand("你", hand)
total = hand_value(hand)
if total > 21:
print("爆牌了!")
break
if total 21:
print("Blackjack!")
break
choice = input("要抽牌(h)還是停牌(s)?")
if choice == "h":
deal(deck, hand)
else:
break
deck = create_deck()
hand = []
deal(deck, hand, 2)
player_turn(deck, hand)
==
>=
>
=
用 = 是「把 21 存進 total」,不是比較,Python 會直接報語法錯誤。
提示
顯示答案
在爆牌判斷旁邊 再加一個 if hand_value(hand) == 21:,印訊息後 break。 建議先用一個變數 total = hand_value(hand) 接起來,這樣同一圈就不用重算三次。
def player_turn(deck, hand):
while True:
show_hand("你", hand)
total = hand_value(hand)
if total > 21:
print("爆牌了!")
break
if total == 21:
print("Blackjack!")
break
choice = input("要抽牌(h)還是停牌(s)?")
if choice == "h":
deal(deck, hand)
print(f"抽到:{hand[-1]}")
else:
print("你選擇停牌。")
break
dealer_turn
莊家回合:沒得選,未滿 17 就抽
莊家比玩家簡單 —— 不用問,規則直接寫成迴圈條件就好。
# 呼叫方式:
dealer_turn(deck, dealer_hand)
# 預期畫面:
--- 莊家翻牌 ---
莊家:7♦ 5♣ (12 點)
莊家抽了:4♠
莊家:7♦ 5♣ 4♠ (16 點)
莊家抽了:K♥
莊家:7♦ 5♣ 4♠ K♥ (26 點)
莊家爆牌了!
def dealer_turn(deck, hand):
print("--- 莊家翻牌 ---")
show_hand("莊家", hand)
while hand_value(hand) :
deal(deck, hand)
show_hand("莊家", hand)
if hand_value(hand) > 21:
print("莊家爆牌了!")
deck = create_deck()
hand = []
deal(deck, hand, 2)
dealer_turn(deck, hand)
<
>
<=
17
21
16
莊家沒有選擇權,規則直接寫進 while 條件就好,不需要 break 。
提示
顯示答案
這裡不用 while True !因為結束條件很明確:「點數到 17 就停」。 直接把規則寫進條件:while hand_value(hand) < 17:,不用 break。
def dealer_turn(deck, hand):
print("--- 莊家翻牌 ---")
show_hand("莊家", hand)
while hand_value(hand) < 17:
deal(deck, hand)
print(f"莊家抽了:{hand[-1]}")
show_hand("莊家", hand)
if hand_value(hand) > 21:
print("莊家爆牌了!")
比較一下
玩家回合要 while True + break,因為「何時結束」由人決定;
莊家回合可以直接把規則寫進 while 條件,因為結束時機是算得出來的 。
熱身
寫 judge 之前:if/elif 的順序會影響結果
elif 只有在前面全部不成立時才會檢查
score = 95
if score >= 60:
print("及格") # ← 這裡就成立了
elif score >= 90:
print("優等") # ← 永遠跑不到!
# 輸出:及格
對 judge 的意義
「玩家爆牌」必須最先判斷 。
因為玩家 25 點、莊家 20 點時,如果先比大小就會判玩家贏 —— 但他早就爆了。
judge
判斷勝負:五種情況
先想清楚順序 ,再寫 if/elif。
# 呼叫方式:
judge(["K♠","Q♥","5♦"], ["10♣","9♠"]) # 玩家 25 爆
judge(["K♠","9♥"], ["10♣","5♠","K♦"]) # 莊家 25 爆
judge(["K♠","9♥"], ["10♣","8♠"]) # 19 vs 18
judge(["K♠","8♥"], ["10♣","8♠"]) # 18 vs 18
# 預期輸出:
你:25 點 vs 莊家:19 點
你爆牌了,莊家贏!
...
def judge(player_hand, dealer_hand):
p = hand_value(player_hand)
d = hand_value(dealer_hand)
print(f"你:{p} 點 vs 莊家:{d} 點")
if p :
print("你爆牌了,莊家贏!")
d > 21:
print("莊家爆牌,你贏了!")
elif :
print("你贏了!")
elif d > p:
print("莊家贏!")
:
print("平手!")
judge(["K♠","Q♥","5♦"], ["10♣","9♠"])
judge(["K♠","8♥"], ["10♣","8♠"])
> 21
< 21
elif
if
p > d
d > p
else
「玩家爆牌」一定要最先判斷 。順序顛倒的話,玩家 25 點對莊家 20 點會被判玩家贏。
提示
顯示答案
判斷順序:① 玩家爆了嗎 → ② 莊家爆了嗎 → ③ 玩家比較大 → ④ 莊家比較大 → ⑤ 剩下的就是平手 。 先把兩邊點數各存成一個變數,程式會好讀很多。
def judge(player_hand, dealer_hand):
p = hand_value(player_hand)
d = hand_value(dealer_hand)
print("--- 結算 ---")
print(f"你:{p} 點 vs 莊家:{d} 點")
if p > 21:
print("你爆牌了,莊家贏!")
elif d > 21:
print("莊家爆牌,你贏了!")
elif p > d:
print("你贏了!")
elif d > p:
print("莊家贏!")
else:
print("平手!")