1. 事前準備
在本 Kotlin 程式碼研究室中,您將建立另一款骰子遊戲 Lucky Dice Roll,試著擲出幸運數字。此遊戲程式將設定一個幸運數字,並擲出骰子。然後,程式會對照幸運數字檢查擲出的數字,並將適當的訊息列印至輸出內容。爲此,您將學習如何在 Kotlin 程式中比較值並做出不同的決策。
為協助您專注於程式設計概念,而無須擔心應用程式的使用者介面,您將使用以瀏覽器為基礎的 Kotlin 程式設計工具,並將結果輸出至控制台。
必要條件
- 瞭解如何在 https://developer.android.com/training/kotlinplayground 中開啟、編輯及執行程式碼
- 能夠建立並執行 Kotlin 程式,且能在程式中使用變數、含引數函式、含方法類別,然後將結果輸出至控制台。
課程內容
- 如何使用
if
和else
陳述式。 - 如何使用大於 (
>
)、小於 (<
) 和等於 (==
) 等運算子來比較值。 - 如何使用
when
陳述式來根據指定值選擇選項。 Boolean
資料類型是什麼,以及如何使用true
和false
值來做出決策。
建構項目
- Lucky Dice Roll 是一款以 Kotlin 為基礎的骰子遊戲,您可以在其中指定一個幸運數字。只要玩家擲出這個幸運數字,即可獲勝。
需求條件
- 連線網際網路的電腦。
2. 在程式碼中做出決策
Lucky Dice Roller 程式需判斷使用者是否擲出幸運數字,並根據結果傳送祝賀訊息或再試一次訊息。
應用程式開發人員須決定應用程式的行為方式,並為使用者建立不同的結果。
如要建構購物應用程式,可以根據使用者選擇的配送選項顯示不同的畫面。若是測驗遊戲,則會根據玩家答案是否正確來顯示不同的畫面。視應用程式而定,您可能需要在程式碼中考量多種可能的結果。
在 Lucky Dice Roller 程式中,應用程式應處理不同的情況,例如:
- 如果擲出的骰子是幸運數字,系統會顯示恭喜訊息!
- 否則如果擲出的骰子並非幸運數字,系統會顯示再試一次訊息。
如要在程式碼中新增此邏輯,請使用特殊的 Kotlin 關鍵字,例如 if
、else
和 when
。
以下舉幾個例子來說明。
使用 if
陳述式來設定符合的條件
- 檢查下方的程式碼。您猜得到輸出內容是什麼嗎?
fun main() {
val num = 5
if (num > 4) {
println("The variable is greater than 4")
}
}
- 將程式碼複製及貼上到 Kotlin 程式編輯器中,然後執行程式來觀察輸出內容。
The variable is greater than 4
此程式的決策過程如下所示:
- 建立變數
num
並將其設為5.
- 如果
num
大於 4,系統會列印"The variable is greater than 4"
。 - 在所有其他情況下,不必採取任何行動。
在上述範例中,num
設定為 5。if
陳述式會比較變數是否大於 4。由於比較結果為 true,系統接下來會執行大括號內的指令並列印訊息。
請注意 if
陳述式的一般格式:
- 以
if
關鍵字開頭。 - 後接一對括號
()
。括號內包含條件。該條件可以是結果為true
或false
的任何條件。例如,一個數字是否大於另一個數字。 - 後接一對大括號
{}
。在大括號內包含結果為true
的條件時要執行的程式碼。
if (condition-is-true) { execute-this-code }
使用 if
陳述式來設定不符合的條件
- 將
num
的值變更為 3,如下所示。如果執行這個程式碼,您預計會發生什麼情況?
fun main() {
val num = 3
if (num > 4) {
println("The variable is greater than 4")
}
}
- 將這些程式碼複製並貼到 Kotlin 程式編輯器中,然後執行程式來觀察輸出內容是否為空白。
將 num
設為 3 時,系統不會列印任何內容,因為 num
的值小於 4。num
大於 4 的條件結果為 false
,並且系統將不會執行大括號內的程式碼,也不會列印任何內容。
使用 else
為不符合的條件建立替代條件
在不符合條件的情況下,您可以為使用者提供其他內容,而非毫無行動。就像使用一般語言一樣,您可以使用 else
陳述式來實現此目標。
- 新增一個
else
陳述式,以在num
不大於 4 的情況下列印訊息,如下所示。如果執行這個程式碼,您預計會發生什麼情況?
fun main() {
val num = 3
if (num > 4) {
println("The variable is greater than 4")
} else {
println("The variable is less than 4")
}
}
- 將程式碼複製及貼上到 Kotlin 程式編輯器中,然後執行程式來觀察輸出內容。
The variable is less than 4
- 請注意,當
num
的值為 3 時,程式會顯示與else
陳述式相關聯的The variable is less than 4
訊息,因為num
不大於 4。 - 將
num
變更為 5,然後再次執行該程式。現在,num
大於 4,而程式會列印「The variable is greater than 4
」。 - 將
num
變更為 4 並執行程式。現在,4 不大於 4,程式會列印「The variable is less than 4
」。
雖然「The variable is less than 4
」是程式碼中所設定條件的正確輸出內容,但顯示的陳述式不準確,因為 4 不小於 4。您可以新增另一個條件,用於檢查第三種可能性,即 num
是否等於 4,並在條件為 true 時顯示正確的陳述式。
使用 else
if
組合新增替代條件
您可以設定多個條件。舉例來說,您可以使用下列方式涵蓋 num
的所有可能性:
- 如果
num
大於 4,則顯示"The variable is greater than 4"
。 - 否則如果
num
等於 4,則顯示"The variable is equal to 4"
。 - 否則,系統會列印
"The variable is less than 4"
。
這些條件在 If-else 陳述式中稱為不同情況。上面列出 3 種情況。
更新後的程式碼如下所示:
fun main() {
val num = 4
if (num > 4) {
println("The variable is greater than 4")
} else if (num == 4) {
println("The variable is equal to 4")
} else {
println("The variable is less than 4")
}
}
請注意下列異動:
num
的值現已設為 4,因此您可以測試新條件。- 在原始的
if
和else
陳述式之間是新的else if
陳述式,適用於num
恰好為 4 的情況。
- 將上述程式碼複製並貼到 Kotlin 程式編輯器中,然後執行程式來觀察輸出內容。
The variable is equal to 4
- 嘗試變更
num
的值,看看會對輸出內容產生什麼影響。將num
變更為 2 和 6 後,您會看到每個條件變爲true
。
控制流程
您查看上述 if-else 陳述式時,會發現程式碼可能會執行或繼續,如同受到條件的控制。因此,藉由這些條件來引導程式執行的過程稱為程式的「控制流程」。
- 假設擲骰子的
num
為 3,該程式會檢查第一個條件 (num > 4)。結果為 false,因此程式會檢查下一個條件 (num == 4),結果同樣為 false。然後,程式會執行 else 陳述式的程式碼,這是最後一個選項。 - 如果擲出的骰子 num 為 6,第一個條件 (num > 4) 的結果為 true。程式會顯示「
The variable is greater than 4
」訊息。由於此條件結果為 true,因此無須檢查其餘條件,使用 if-else 陳述式即可完成這項工作。 - 使用 else + if 組合可新增替代條件。
3. 建立 Lucky Dice Roll 遊戲
在本節中,您將運用在上一個工作中學到的內容更新 Dice Roller 程式,檢查是否擲出預設的幸運數字。擲出預設的幸運數字代表您獲勝!
設定範例程式碼
您用來開始建構 Lucky Dice Roller 的程式碼,會類似於先前 Kotlin Dice Roller 程式的解決方案程式碼。您可以編輯先前程式碼中的 main()
函式來進行比對,也可以複製及貼上下方的程式碼來開始建構。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
println("Your ${myFirstDice.numSides} sided dice rolled ${rollResult}!")
}
class Dice (val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
檢查是否擲出幸運數字
請先建立一個幸運數字,再比較擲出的數字與該數字。
- 在
main()
中,刪除println()
陳述式。 - 在
main()
中,新增名為luckyNumber
的val
,並將其設為 4。您的程式碼應如下所示。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
}
- 在下方新增
if
陳述式,括號()
內包含條件,用於檢查rollResult
是否等於 (==
)luckyNumber
。在大括號{}
之間保留一些空間,以新增更多程式碼。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
}
}
- 在大括號
{}
內新增println
陳述式,以列印"You win!"
。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
}
}
- 執行程式。您可能需要執行幾次之後才會得到幸運數字,並在輸出內容中看到獲勝訊息。
You win!
在未擲出幸運數字時回應
在使用者沒有獲勝的情況下,如果程式沒有任何回應,使用者就可能懷疑程式是否故障。最好的做法是對使用者的每個動作給予回應。在 Lucky Dice Roller 程式中,可以使用 else
陳述式告知使用者他們並未獲勝。
- 新增
else
陳述式以列印"You didn't win, try again!"
。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
} else {
println("You didn't win, try again!")
}
}
- 執行程式。無論結果為何,使用者都會收到通知。
此時,使用者會知道自己是否獲勝,但不知道原因。請務必向使用者提供相關資訊,讓他們瞭解自己的操作結果!假設您的程式是貸款應用程式。提供「您的信用評等較差,因此並未獲得核准」訊息,會比提供「很抱歉,無法向您提供貸款,請再試一次!」訊息更實用。在 Lucky Dice Roller 中,如果使用者失敗,您可以在使用者每次擲出骰子時提供不同的資訊型訊息。為此,請使用多個 else if
陳述式。
- 新增
else if
陳述式,即可針對每次擲骰輸出不同訊息。必要時,請參閱您在上一個工作中學到的格式。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
} else if (rollResult == 1) {
println("So sorry! You rolled a 1. Try again!")
} else if (rollResult == 2) {
println("Sadly, you rolled a 2. Try again!")
} else if (rollResult == 3) {
println("Unfortunately, you rolled a 3. Try again!")
} else if (rollResult == 5) {
println("Don't cry! You rolled a 5. Try again!")
} else {
println("Apologies! You rolled a 6. Try again!")
}
}
在上方的程式碼中,您可以
- 檢查
rollResult
是否為luckyNumber
。 - 如果
rollResult
為luckyNumber
,系統會列印獲勝訊息。 - 否則,請檢查
rollResult
是否為 1。如果是,系統會列印再試一次訊息。 - 否則,請檢查
rollResult
是否為 2。如果是,系統會列印另一則再試一次訊息。 - 否則,請繼續檢查,直至數字 5。
- 如果這個數字並非介於 1 到 5,則僅剩下選項 6,因此不必再使用
else if
進行測試,可以透過最後一個else
陳述式直接擷取最後一個選項。
由於使用多個 else if
的情況很常見,因此 Kotlin 提供一種更簡單的編寫方法。
4. 使用 when 陳述式
在程式設計中,針對許多不同的結果或情況進行測試的做法很常見。有時,可能的結果很多。舉例來說,如果使用 12 面骰子,成功結果與最終 else
之間會有 11 個 else if
陳述式。為了讓這類陳述式更容易寫入和讀取,Kotlin 提供 when
陳述式,以幫助避免錯誤。
您將變更程式,改為使用 when
陳述式。when
陳述式的開頭為關鍵字 when
,後接 ()
括號。括號內包含要測試的值。後接大括號 {}
,讓程式碼可以在不同的條件下執行。
- 在程式的
main()
中,選取從第一個if
陳述式至括住最後一個else
陳述式的大括號}
之間的程式碼,然後刪除這些程式碼。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
}
- 在
main()
中的luckyNumber
宣告下方,建立when
陳述式。由於when
須針對擲出的結果進行測試,因此請將rollResult
包含在括號()
內。新增大括號{}
並留出額外的空格,如下所示。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
}
}
和先前一樣,先測試 rollResult
是否與 luckyNumber
相同。
- 在
when
陳述式的大括號{}
內,新增用來測試luckyNumber
的陳述式rollResult
。如果兩者相同,系統會顯示獲勝訊息。此陳述式如下所示:
luckyNumber -> println("You win!")
因此:
- 請先放入您要與
rollResult
比較的值。即luckyNumber
。 - 後接箭頭 (
->
)。 - 然後,新增系統偵測到相符內容時要執行的動作。
這可以讀做「如果 rollResult
為 luckyNumber
,系統會顯示 "You win!"
訊息」。
您的 main()
程式碼如下所示。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You win!")
}
}
- 使用相同的模式為可能擲出的數字 1 至 6 (4 除外) 新增行和訊息,如下所示。完成的
main()
函式應如下所示。
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You won!")
1 -> println("So sorry! You rolled a 1. Try again!")
2 -> println("Sadly, you rolled a 2. Try again!")
3 -> println("Unfortunately, you rolled a 3. Try again!")
5 -> println("Don't cry! You rolled a 5. Try again!")
6 -> println("Apologies! You rolled a 6. Try again!")
}
}
- 執行程式。輸出內容沒有任何差異,但您的程式碼更爲精簡,也更容易閱讀。
恭喜!您已掌握根據條件輸出訊息的兩種方式。這是一款強大的工具,非常適合用來編寫有趣的程式!
5. 解決方案程式碼
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You won!")
1 -> println("So sorry! You rolled a 1. Try again!")
2 -> println("Sadly, you rolled a 2. Try again!")
3 -> println("Unfortunately, you rolled a 3. Try again!")
5 -> println("Don't cry! You rolled a 5. Try again!")
6 -> println("Apologies! You rolled a 6. Try again!")
}
}
class Dice(val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
6. 總結
- 使用
if
陳述式來設定執行部分指令的條件。舉例來說,如果使用者擲出幸運數字,系統會列印獲勝訊息。 Boolean
資料類型的值為true
和false
,可用於做出決策。- 使用大於 (
>
)、小於 (<
) 和等於 (==
) 運算子來比較值。 - 使用
else if
陳述式鏈結可設定多個條件。例如,系統會為每次可能擲出的骰子列印不同的訊息。 - 在條件鏈結的結尾處使用
else
陳述式,以捕捉您未明確涵蓋的任何情況。如果您涵蓋 6 面骰子的情況,else
陳述式會捕捉使用 8 面骰子時擲出的數字 7 和 8。 - 使用
when
陳述式做為根據比較數值的結果執行程式碼的一種精簡形式。
if-else 的一般形式:
if (condition-is-true) {
execute-this-code
} else if (condition-is-true) {
execute-this-code
} else {
execute-this-code
}
when 陳述式:
when (variable) {
matches-value -> execute-this-code
matches-value -> execute-this-code
...
}
7. 瞭解詳情
8. 自行練習
請練習下列項目:
- 將
myFirstDice
變更為包含 8 個面並執行程式碼。會發生什麼?
提示:當您增加面數時,when
陳述式不會再涵蓋所有情況,因此如果出現未涵蓋的情況,系統不會顯示任何內容。
- 修正
when
陳述式,以涵蓋所有 8 個面。爲此,您可以新增針對其他數字的情況。挑戰:使用else
陳述式可捕捉所有未明確涵蓋的情況,而不必針對每個數字新增新的情況。
提示:您可以新增更多情況來涵蓋更多面。如果您希望系統為擲出的每個數字顯示不同的訊息,可以採用這種方式。或者,您可以使用 else
陳述式,針對現有程式碼涵蓋的所有大於 6 的面顯示相同訊息。
- 將
myFirstDice
變更為僅包含 4 個面。會發生什麼?
提示:將骰子的面數變更為小於 when
陳述式涵蓋的範圍時,不會產生明顯影響,因為會發生的所有情況均涵蓋在內。