#021 BlackJack 二十一點遊戲

不停來回修改修改修改…

剛剛好第21篇文章獻給21點遊戲App,一整個下午不停的修改終於完成拉!

遊戲規則說明

  • 莊家與玩家小於等於21點比大小
  • 各自最多五張牌
  • 兩張牌21點即為Black Jack 贏牌,可贏得下注賭金的1.5倍
  • 莊家如不足17點,需加牌直到超過或等於17點為止
  • 玩家選擇棄牌要付出一半的賭金
  • 超過21點為爆牌,玩家下注賭金歸莊家,莊家爆牌則賠賭金的1倍
  • 玩家與莊家均為兩張牌21點時,莊家贏
  • 平手時,玩家可拿回原下注賭金

運用程式

  • while / if else / for in / switch
  • struct
  • button tag
  • UIViewPropertyAnimator

花了一週醞釀的寶寶gif奉上~

解說部分程式

首先建立三個array,分別存放花色與數字以及儲存一整副牌的cards
記得撲克牌圖片的名稱要跟自己產出的suit&rank對應到

struct Card {
var suit : String
var rank : Int
}
let suits = ["club", "spade", "heart", "diamond"]
let ranks = Array(1...13)
var cards = [Card]()
for suit in suits {
for rank in ranks {
let card = Card(suit: suit, rank: rank)
cards.append(card)
}
}

下注按鈕

@IBAction func deal(_ sender: UIButton) {
//洗牌
cards.shuffle()
// 沒有賭金時按下注無反應
if betMoneyLabel.text != "0" {
for i in 0...4 {
self.playerCards[i].alpha = 0
}
//莊閒各第一張牌
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.5, delay: 0) {
self.playerCards[0].image = UIImage(named: self.cards[0].suit + "\(self.cards[0].rank)")
self.playerCards[0].alpha = 1
self.bankerCards[0].image = UIImage(named: "cardBack")
self.bankerCards[0].alpha = 1
}
//莊閒各第二張牌
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.8, delay: 0.5) {
self.playerCards[1].image = UIImage(named: self.cards[2].suit + "\(self.cards[2].rank)")
self.playerCards[1].alpha = 1
self.bankerCards[1].image = UIImage(named: self.cards[3].suit + "\(self.cards[3].rank)")
self.bankerCards[1].alpha = 1
}
//玩家牌計算
switch cards[0].rank {
case 11...13:
playerSumNumber = 10
case 2...10:
playerSumNumber = cards[0].rank
case 1:
playerSumNumber = 11
default:
break
}
switch cards[2].rank {
case 11...13:
playerSumNumber += 10
case 2...10:
playerSumNumber += cards[2].rank
case 1:
playerSumNumber += 11
default:
break
}
//莊家牌計算,只能先揭露第二張牌
switch cards[3].rank {
case 11...13:
bankerSumNumber = 10
case 2...10:
bankerSumNumber = cards[3].rank
case 1:
bankerSumNumber = 11
default:
break
}
//莊家真正的點數合
var realBankerSumNumber = 0
switch cards[1].rank {
case 11...13:
realBankerSumNumber = bankerSumNumber + 10
case 2...10:
realBankerSumNumber = bankerSumNumber + cards[1].rank
case 1:
realBankerSumNumber = bankerSumNumber + 11
default:
break
}
//拿到兩張A
if playerSumNumber == 22 {
playerSumNumber = 12
}
if realBankerSumNumber == 22 {
realBankerSumNumber = 12
}
var remainMoney = Int(remainMoneyLabel.text!)!
let betMoney = Int(betMoneyLabel.text!)!
//莊閒兩張牌21
if playerSumNumber == 21, realBankerSumNumber == 21 {
wordingLabel.text = "你輸了"
betMoneyLabel.text = "0"
showBankerHideCard()
bankerSum.text = "\(realBankerSumNumber)"
} else if playerSumNumber == 21 {
wordingLabel.text = "Black Jack"
betMoneyLabel.text = "0"
showBankerHideCard()
remainMoney += betMoney * 5 / 2
bankerSum.text = "\(realBankerSumNumber)"
} else if realBankerSumNumber == 21 {
wordingLabel.text = "你輸了"
betMoneyLabel.text = "0"
showBankerHideCard()
remainMoney -= betMoney
bankerSum.text = "\(realBankerSumNumber)"
} else {
wordingLabel.text = ""
bankerSum.text = "\(bankerSumNumber)"
}
playerSum.text = "\(playerSumNumber)"
remainMoneyLabel.text = "\(remainMoney)"
}
}

一開始先將所有牌的UIImageView隱藏,下注後再運用動畫顯示圖片
各自前兩張牌,運用switch判斷該牌面的數字,JQK時數字 = 10,A = 11,如果遇到兩張牌都是A時,總合等於12

  • 要牌function
    當總和小於等於11時,要的牌如果是A,A = 11,如果之前有拿到A,A=11 ; 當總和大於11時,如果之前有拿到A,A=1
  • 開牌function
    跟要牌很像,但總和小於17時,要再加一張牌,因此這邊使用了while迴圈

一開始我直接將J,Q,K 的rank 數字改成10去做總和的運算,導致後面UIImageName的顯示出現錯誤,會有同一張牌出現兩次的老千狀況,發現每次都是10這張牌出現老千,所以整個重新用switch判斷,用不更動rank原始資料的方式計算總和,總算是成功了,超級感動,六小時值得!

偷懶跟骰子遊戲用了同一組視覺風格,都是賭博遊戲嘛~

--

--