#43 二十一點亞洲慈善撲克王大賽
Published in
9 min readAug 14, 2023
先來看一下成品~~~
遊戲規則說明
- 莊家與玩家小於等於21點比大小
- 各自最多五張牌
- 莊家如不足17點,需加牌直到超過或等於17點為止
- 玩家選擇棄牌要付出一半的賭金
- 超過21點為爆牌,玩家下注賭金歸零
- 平手時,玩家可拿回原下注賭金
- K、Q、J 和 10 牌都算作 10 點,A 牌算作1 點,其餘所有2 至9 牌均按其原數值計算
- 要牌:再拿一張牌、開牌:停止拿牌直接開牌顯示結果、棄排:選擇結束當局遊戲
技術項目:
- storyboard
- Swift 基本語法if else / for in
- 自訂 view controller 類別 & model 型別
- struct
- IBSegueAction & performSegue
畫面&程式:
- 先拉好storyboard跟IBOutlet
一張撲克牌UIView 顯示2個suit、1個rank
2. 自訂Card類別
3. 生成空的撲克牌組、電腦空的牌組、玩家空的牌組&變數設定
4. 生成空的52組牌,存在cards的陣列中
5. 電腦牌組的總和&玩家牌組的總和
6. 初始化遊戲開始狀態,使用 for in 迴圈在畫面上放上 5 張撲克牌,畫面顯示兩張牌面,其他用isHidden隱藏起來
7. 用button當作控制籌碼的按鈕,兩個btn按鈕連到同個@IBAction
8. 遊戲提醒框UIAlertController設定、確認賭金與籌碼是否為0,避免遊戲有bug(當未下賭金遊戲不能開始、籌碼為0結束遊戲)
9. 要牌,玩家可自行決定是否要加牌
//要牌
@IBAction func hit(_ sender: UIButton) {
//有下籌碼才可以開始要牌
if checkBetMoney()==true{
index = index+1
cards.shuffle()
playerCardView[index].isHidden = false
playerCards.append(cards[index])
playerRankLabel[index].text = playerCards[index].rank
playerSuit1Label[index].text = playerCards[index].suit
playerSuit2Label[index].text = playerCards[index].suit
playerSumLabel.text = "\(playerSum)"
//當卡牌為5張且<21點,過五關,獎金2倍;當卡牌=21點,贏回賭金;當卡牌>21,輸掉賭金
if checkOwnMoney() == true{
if index == 4 , playerSum<=21{
gameAlert(title: "恭喜過五關!", message: "贏回賭金兩倍!")
ownMoney += betMoney+betMoney+betMoney
betMoney -= betMoney
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}else if playerSum==21{
gameAlert(title: "恭喜!", message: "21點獲勝!")
ownMoney += betMoney+betMoney
betMoney -= betMoney
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}else if playerSum>21{
gameAlert(title: "爆掉了!", message: "超過21點!")
betMoney -= betMoney
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}
}
}
}
10. 開牌,玩家認為點數夠了可選擇停牌,點數即固定
//開牌,玩家認為點數夠了可選擇停牌,點數即固定
@IBAction func stand(_ sender: UIButton) {
if checkBetMoney()==true{
//當電腦牌面點數<=17,繼續抽牌
if cptSum<=17{
//當電腦牌面點數<=21繼續抽牌,且莊家<玩家時,繼續補牌最多5張
for i in 2...4{
if cptSum<=21{
computerCards.append(cards[i])
computerCardView[i].isHidden = false
computerRankLabel[i].text = computerCards[i].rank
computerSuit1Label[i].text = computerCards[i].suit
computerSuit2Label[i].text = computerCards[i].suit
computerSumLabel.text = "\(cptSum)"
//當電腦牌面點數=21,電腦獲勝
if cptSum == 21{
// ownMoney = ownMoney-betMoney
betMoney -= betMoney
gameAlert(title: "21點!", message: "電腦獲勝!")
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}//當電腦牌面點數>21,電腦輸玩家獲勝
else if cptSum>21{
ownMoney += betMoney+betMoney
betMoney -= betMoney
gameAlert(title: "電腦爆掉啦!", message: "恭喜玩家獲勝!")
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}//當電腦過五關且牌面比玩家大,電腦獲勝
else if i==4 && cptSum<=21 && cptSum>playerSum{
// ownMoney = ownMoney-betMoney
betMoney -= betMoney
gameAlert(title: "可惜了!電腦過五關!", message: "電腦獲勝!")
}
}
}
}else {
if cptSum<playerSum{
ownMoney += betMoney+betMoney
betMoney -= betMoney
gameAlert(title: "你比電腦大啦!", message: "玩家獲勝!")
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}else if cptSum>playerSum{
// ownMoney -= betMoney
betMoney -= betMoney
gameAlert(title: "哭哭!電腦比你大!", message: "電腦獲勝!")
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}else if cptSum == playerSum{
ownMoney = ownMoney+betMoney
betMoney -= betMoney
gameAlert(title: "電腦跟你點數一樣大!", message: "平手!!!")
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
}
}
}
}
11. 棄牌
//棄牌時,賭金只能回收一半,重新發牌
@IBAction func giveup(_ sender: UIButton) {
if checkBetMoney()==true{
ownMoney += betMoney/2
betMoney -= betMoney
chipsLabel.text = "\(ownMoney)"
betLabel.text = "\(betMoney)"
betMoneyLabel.text = "\(betMoney)"
gameStart()
}
}