#71 Yahtzee Game 快艇骰子
Yahtzee 快艇骰子,蠻有趣的遊戲,把骰子和撲克牌常見的計分規則綜合在一起,挑戰度大增,要拿高分還真的蠻考驗運氣及策略。這次沒花太多時間製圖及畫面設計,單純用 storyboard 的把 view 排好,以藍白色長方型為基調,畫面有點陽春,不過遊戲功能很齊全唷。
彼得潘的題目介紹:
操作影片
操作截圖
簡單的動畫增加互動性
旋轉
移動、縮放
計分規則
研究一下計分規則
Yahtzee 的計分規則主要分為上半部和下半部分。
上半部分: 相同數字的總和
在上半部分,玩家可以得分的是五個骰子中相同數字的總和。Yahtzee 遊戲中的骰子有六面,從一到六編號。玩家可以選擇計分的類別,分別是 1、2、3、4、5 和 6。當玩家選擇某個類別時,他們得分的是在所有骰子中出現該數字的總和。例如玩家擲出了 1、2、3、3、6 這五個骰子,,如果玩家選擇了 3 類別,則得分為 6(兩個 3)。
加分
如果從一到六編號數字總合大於等於 63 可以額外得到 35 分 (很重要的分數)
下半部分:特定的組合
在下半部分,則是根據特定的組合來計算得分,有點像撲克牌常見的組合,這些組合包括:
- 三條/Three of a Kind:至少三個骰子數字相同,得分是所有骰子的總和。
- 鐵支/Four of a Kind:至少四個骰子數字相同,得分是所有骰子的總和。
- 葫蘆/Full House:三個骰子數字相同且另外兩個骰子數字也相同,得分是固定的 25 分。
- 小順/Small Straight:四個連續的骰子數字,得分是固定的 30 分。
- 大順/Large Straight:五個連續的骰子數字,得分是固定的 40 分。
- Yahtzee:所有骰子數字相同,得分是固定的 50 分。(有些玩法有額外的快艇加分先忽略)
- Chance:任意組合,得分是所有骰子的總和。
紙本的計分表
遊戲人數
遊戲上先設計單人玩的就好,應該很難找到別人一起玩。不過未來可以增加一個挑戰分數,就是一開始先假設對手的總分是多少,你要超過那個分數才算勝利。
已發行的APP界面研究
佈局蠻大同小異,上方計分牌,下方骰子和操作按鍵。
- Yatzy Infinity 黃色系UI
- Yatzy — Classic Edition 藍色系UI
待處理事項
- Debug @@"
- 美術設計
- 遊戲性,增加過關的目標設定
也許可以跟快艇的意像結合起來。想像分數就是快艇的燃料,你得到多少分數,快艇就會增加多少燃料,影響它最後能往前移動的距離。玩家的目標就是努力取得最多的燃料來使自己的快艇跑的比對方還遠。每一個計分格就是一個燃料筒,你可以決定這次的燃料要加在那個筒子裡 - 難度等級調整
其實這遊戲只是把二種常見的計分規則組合在一起,變得很有挑戰性,不過初學者大概看完這麼長的規則就不想玩了。也許把難度分成三個等級:
難度等級1 - 只比上半部分:
這個等級專注於上半部分的計分,讓玩家在遊戲中專注於單一的計分概念,並且減少了對下半部分的考慮。
這對於新手玩家來說是一個很好的入門選擇,因為它降低了遊戲的複雜度,讓他們更容易理解和掌握。
難度等級2 - 只比下半部分:
這個等級讓玩家專注於下半部分的計分,這部分計分相對較複雜,因為它涉及到各種不同的組合。
這對於那些想要挑戰更高難度的玩家來說是一個很好的選擇,他們可以在這個等級中嘗試不同的策略來最大化他們的得分。
難度等級3 - 同時比上半部分和下半部分:
這個等級是最具挑戰性的,因為玩家需要同時考慮上半部分和下半部分的計分,並且找到最佳的平衡點。
這對於有經驗的玩家來說是一個很好的挑戰,他們需要更多的策略和計算來最大化他們的得分。
程式筆記
這次程式練習主力應該就是 Set 及 map 了。
// 定義骰子類別
class Die {
var value: Int
var isHeld: Bool
init() {
value = Int.random(in: 1...6)
isHeld = false
}
func roll() {
if !isHeld {
value = Int.random(in: 1...6)
}
}
}
集合 Set、 陣列轉換map
var dice: [Die]
//dice = [Die(), Die(), Die(), Die(), Die()]
let uniqueValues = Set(dice.map { $0.value })
//創建一個包含了所有 dice 中的不重複 value 屬性值的集合。
當我們調用 map
方法時,我們正在對陣列中的每個元素應用一個轉換,並返回一個包含轉換後結果的新陣列。在這種情況下,dice
是一個 Die
對象的陣列,$0.value
是一個閉包,它返回 Die
對象的 value
屬性的值。所以 dice.map { $0.value }
這行代碼將返回一個包含了所有 Die
對象的 value
屬性值的陣列。
接著,我們將這個陣列傳遞給 Set
初始化器,它將這個陣列中的所有元素作為其內容來創建一個新的 Set
實例。Set
是一種集合類型,它包含一組唯一的元素,這意味著在 uniqueValues
中將不會包含重複的元素,每個元素只會出現一次。
- 計算 Three of a Kind 的得分
// 計算 Three of a Kind 的得分
private func calculateThreeOfAKindScore() -> Int {
let diceValues = dice.map { $0.value }
let counts = Set(diceValues).map { value in diceValues.filter { $0 == value }.count }
if counts.contains(where: { $0 >= 3 }) {
return diceValues.reduce(0, +)
} else {
return 0
}
}
- 計算 Four of a Kind 的得分
// 計算 Four of a Kind 的得分
private func calculateFourOfAKindScore() -> Int {
let diceValues = dice.map { $0.value }
let counts = Set(diceValues).map { value in diceValues.filter { $0 == value }.count }
if counts.contains(where: { $0 >= 4 }) {
return diceValues.reduce(0, +)
} else {
return 0
}
}
- 計算 Full House 的得分
// 計算 Full House 的得分
private func calculateFullHouseScore() -> Int {
let diceValues = dice.map { $0.value }
let counts = Set(diceValues).map { value in diceValues.filter { $0 == value }.count }
if counts.contains(2) && counts.contains(3) {
return 25
} else {
return 0
}
}
參考:
規則介紹
iPad app
iphone
https://apps.apple.com/tw/app/yatzy-classic-edition/id1407804709?l=en-GB
電腦視覺-手寫數字辨識計分
遊戲策略
【數位桌遊】《Yahtzee Girl》:在黃油裡追求桌遊是不是搞錯了什麼?
/*
遊戲的理論滿分為:
點數1:5 分(1、1、1、1、1)
點數2:10 分(2、2、2、2、2)
點數3:15 分(3、3、3、3、3)
點數4:20 分(4、4、4、4、4)
點數5:25 分(5、5、5、5、5)
點數6:30 分(6、6、6、6、6)
63 分獎勵:+35 分
葫蘆:25 分(固定分數)
小順:30 分(固定分數)
大順:40 分(固定分數)
全選:30 分(6、6、6、6、6)
三色同花:30 分(6、6、6、6、6)
四色同花:30 分(6、6、6、6、6)
五色同花/快艇:50 分(6、6、6、6、6)、快艇加分 1200 分(100 分×12 次)
合計是 1575 分。
快艇加分是因為每多骰出一次「快艇」就 +100,
因此連續 13 次都出快艇就能 +1200;
但顯然這太誇張了,
因此不考慮快艇加分的情況下,
理論滿分只有 375 分。
*/