This is not Blackjack…
while, switch, 回傳東西的function, nested loop, struct, AVPlayerLooper, shuffle, array, alert…
成品:對於無法完成完整玩法而屈服的自己深感遺憾…😔
▲但本來就不打算(也不知怎)做八副牌混合與使牌減少,一樣不完整啦😅
▲Blackjack屬一澳洲特別回憶,路人還分紅道謝因他壓我會拿到對😂
▲簡化版沒Split, Double, Insurance, Five card Charlie, 除Blackjack, A算1點
▲玩家 Blackjack 莊家不是時莊家馬上輸不用至 17 點,因沒別的玩家要比
▲非美式 Blackjack 所以無蓋牌,使用 PUSH 因字數比 Stand off 少較合圖
▲決定放棄後難度瞬間大跌,如有神助迅速完成!結果網誌卡好久😑
前置作業
▲找教我玩的朋友把規則再搞清楚一次順便回味一起在澳洲發生的事😂
▲找什麼圖都不滿意,除那三行弧形文字和手,全用keynote自己做(累)
▲Storyboard 版面配置
▲較特別是按籌碼後想它出現在下注圓圈內,因此放很多 ImageView
新增 Swift File 用
struct
定義 Card 型別 :花色與點數設為字串
import Foundationstruct Card {
var suit : String
var rank : String
}
重複放音樂:彼得完整教學於此
▲加入 AVFoundation 函式庫
▲利用 AVPlayerLooper 重複播放
▲下 5 行寫於 ViewDidLoad 內
➞生成 AVQueuePlayer 物件
➞利用 Bundle.man 取得APP資料夾內音樂檔(之前我們匯入的)彼得教學
➞利用 AVPlayerItem 生成要播放的音樂
➞生成 AVPlayerLooper,傳入剛生成的 player & item
➞開始播放音樂
import AVFoundationvar looper: AVPlayerLooper?let player = AVQueuePlayer()
let fileUrl = Bundle.main.url(forResource: "Kenny Rogers - The Gambler", withExtension: "mp3")!
let playerItem = AVPlayerItem(url: fileUrl)
looper = AVPlayerLooper(player: player, templateItem: playerItem)
player.play()
拉 IBOutlet,其中莊家 5 張牌是拉 Outlet Collection為陣列
▲紅線部份本為空行,但太長照不起來便以刪空行畫紅線來呈現
▲取名時第一個字不能為數字…只好採用英文序數
52 張撲克牌製成:巢狀迴圈 ,並於 ViewDidLoad 內寫此 function
let suits = [“♠️”, “♥️”, “♦️”, “♣️”]
let ranks = [“A”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “10”, “J”, “Q”, “K”]var cards = [Card]()func createCards() {
for suit in suits {
for rank in ranks {
let card = Card(suit: suit, rank: rank)
cards.append(card)
}
}
}
其餘變數:count 為按籌碼按鈕次數,index 為檯面上牌的張數
var count = 0var wagerAmount = 0
var totalAmount = 1000var index = 0var playerPoint = 0
var dealerPoint = 0
定義各 function
▲下注金額為 10-100,依各情形鎖住按鈕,本想用switch但有個是≥🤦🏻♀️
func limitOfWager() { if wagerAmount == 100 {
buttonOf50Chip.isEnabled = false
buttonOf20Chip.isEnabled = false
buttonOf10Chip.isEnabled = false
} else if wagerAmount == 90 {
buttonOf50Chip.isEnabled = false
buttonOf20Chip.isEnabled = false
} else if wagerAmount == 80 {
buttonOf50Chip.isEnabled = false
} else if wagerAmount == 70 {
buttonOf50Chip.isEnabled = false
} else if wagerAmount == 60 {
buttonOf50Chip.isEnabled = false
} else if wagerAmount >= 10 {
dealButton.isEnabled = true
}
}
▲依總金額不同鎖不同按鈕
func limitOfTotalAmount() { if totalAmount < 10 {
buttonOf50Chip.isEnabled = false
buttonOf20Chip.isEnabled = false
buttonOf10Chip.isEnabled = false
} else if totalAmount < 20 {
buttonOf50Chip.isEnabled = false
buttonOf20Chip.isEnabled = false
} else if totalAmount < 50 {
buttonOf50Chip.isEnabled = false
}
}
▲每按 1 次 10/20/50 籌碼相對應之結果,此只舉例 10 元籌碼
func plus10chip() {
count += 1
wagerAmount += 10
totalAmount -= 10
wagerLabel.text = “\(wagerAmount)”
totalLabel.text = “\(totalAmount)”
limitOfWager()
limitOfTotalAmount()
}
▲反悔下注金額未按發牌前及判斷輸贏後皆以此恢復初始值 / 畫面
func revisionOfTheChips() {
totalAmount += wagerAmount
totalLabel.text = “\(totalAmount)”
count = 0
wagerAmount = 0
wagerLabel.text = “” first10ChipImage.isHidden = true
second10ChipImage.isHidden = true
third10ChipImage.isHidden = true
fourth10ChipImage.isHidden = true
fifth10ChipImage.isHidden = true
sixth10ChipImage.isHidden = true
seventh10ChipImage.isHidden = true
eighth10ChipImage.isHidden = true
ninth10ChipImage.isHidden = true
tenth10ChipImage.isHidden = true
first20ChipImage.isHidden = true
second20ChipImage.isHidden = true
third20ChipImage.isHidden = true
fourth20ChipImage.isHidden = true
fifth20ChipImage.isHidden = true
first50ChipImage.isHidden = true
second50ChipImage.isHidden = true
buttonOf10Chip.isEnabled = true
buttonOf20Chip.isEnabled = true
buttonOf50Chip.isEnabled = true
dealButton.isEnabled = false
}
▲贏 / 輸 / 平手 / 爆各情形,此只舉例贏且非 Blackjack 贏時
func playerWin() {
playerResultImage.isHidden = false
playerResultImage.image = UIImage(named: “U WIN”)
wagerAmount *= 2
revisionOfTheChips()
}
▲生成莊家第 2 張牌 (陣列為 1 總牌數則因不同情形不同) 並計算點數
func createDealerCard2AndCount() {
dealerCardImage[1].isHidden = false
dealerCardImage[1].image = UIImage(named: cards[index].suit + cards[index].rank)
dealerPoint += RankPoint(rank: cards[index].rank)
dealerPointLabel.text = “\(dealerPoint)”
}
▲莊家 Blackjack 時的不同結果 (實質是 11 點所以不算點數用字串判斷)
func dealerBlackjackResult() {
dealerPointLabel.text = “21”
dealerBlackjackImage.isHidden = false
if playerPointLabel.text == “21” && playerCard3Image.isHidden == true {
Push()
} else {
playerLose()
}
}
▲莊家牌超過 16 點後判斷輸贏結果
func finalResult() {
if dealerPoint > 21 {
dealerResultImage.isHidden = false
dealerResultImage.image = UIImage(named: “BUST”)
playerWin()
} else if dealerPoint < playerPoint {
playerWin()
} else if dealerPoint > playerPoint {
playerLose()
} else {
Push()
}
}
▲莊家有第 5 張牌時所有牌之位置調整
func positionOf5DealerCard() {
if dealerCardImage[4].isHidden == false {
dealerCardImage[1].frame = CGRect(x: 340, y: 14, width: 92, height: 119)
dealerCardImage[2].frame = CGRect(x: 264, y: 14, width: 92, height: 119)
dealerCardImage[3].frame = CGRect(x: 188, y: 14, width: 92, height: 119)
}
}
⭐ 回傳東西的 function:回傳東西: point,型別: Int (特設AJQK點數)
func RankPoint(rank: String) -> Int {
var point = 0
switch rank {
case “A”:
point = 1
case “J”, “Q”, “K”:
point = 10
default:
point = Int(rank)!
}
return point
}
拉 IBAction
@IBAction func bet10Chip(_ sender: UIButton) {
}
@IBAction func bet20Chip(_ sender: UIButton) {
}
@IBAction func bet50Chip(_ sender: UIButton) {
}
@IBAction func clearWager(_ sender: UIButton) {
}
@IBAction func deal(_ sender: UIButton) {
}
@IBAction func hit(_ sender: UIButton) {
}
@IBAction func stand(_ sender: UIButton) {
}
@IBAction func Next(_ sender: UIButton) {
}
▲ 新技巧 switch
可省多次 if else 更簡潔,default 如無設定填 break 即可
➞按任一籌碼按鈕 count 皆 +1, 而因 count 次數不同對應不同 case 反應
➞按 1 次出現 1 小籌碼圖,下注及總金額改變 (此只舉例 50 元籌碼按鈕)
@IBAction func bet50Chip(_ sender: UIButton) {
switch count {
case 0:
first50ChipImage.isHidden = false
plus50chip()
default:
second50ChipImage.isHidden = false
plus50chip()
}
}
▲ 如沒加第 2 個 func,餘額< 50 又反悔按 ⨂ 時會發現每個鈕都可按 😵
@IBAction func clearWager(_ sender: UIButton) {
revisionOfTheChips()
limitOfTotalAmount()
}
之後 Action都超長,註解在完整程式碼裡好了 !名稱取很完整應不難懂
▲ 其中 while
也是新學技巧還是註記一下
➞和 for in loop 不同處為無次數限定,依設定條件決定
➞條件沒設好的話,可能有無限循環或根本不會跑情況產生
➞此例為莊家點數未超過 16 點時莊家繼續加牌,但第 5 張出現後則停止
➞莊家第 3 張牌會因檯面上張數不同改變,因此 index-2 / -3 / -4皆有可能
➞如最後無 index += 1,此 while 就只會一直更換莊家第 3 張牌
while dealerPoint < 17 && dealerCardImage[4].isHidden == true {
dealerCardImage[index-2].isHidden = false
dealerCardImage[index-2].image = UIImage(named: cards[index+1].suit + cards[index+1].rank)
dealerPoint += RankPoint(rank: cards[index+1].rank)
dealerPointLabel.text = “\(dealerPoint)”
index += 1
}
完整程式碼 + 後半段解釋
上半為 Card (struct),下半為 ViewController