Josh Skeen, David Greenhalgh著　『Kotlinプログラミング』　章末問題に挑戦(第８章)

　[Josh Skeen, David Greenhalgh著『Kotlinプログラミング』](https://www.shoeisha.co.jp/book/detail/9784798160191)には章末問題がある。残念なことに解答がないので、[第７章](https://qiita.com/guijiu/items/452cfa51bee6c4a4af9d)に引き続き本を読み進めながら答案を記述する。
　もし回答に間違いや意見があれば、ぜひご指摘いただきたい。

#第８章　章末問題 回答案

##８．９　チャレンジ！　残りのパインド数
```Kotlin:Pint.kt
// 
fun main() {
    val initialDragonsBreathGallon = 5
    var totalDragonsBreathPint = (5 / 0.125).toInt()
    println("initial Dragong's Breath $totalDragonsBreathPint _Pint")
    var sales = 12
    println("Sales $sales _Pint")
    totalDragonsBreathPint -= sales
    println("remaining Dragon's Breath: $totalDragonsBreathPint _Paint")
}

```

##８．１０　チャレンジ！　持ち金が足りなくなったら
　performPurchase()関数の中で、所持金totalPurseと代金priceを比較し、所持金が上回っていれば真を返し、下回っていれば偽を返すように変更した。
　またplaceOrder()関数の中でperformPurchase()関数を呼びその戻り値が偽の時、“The customer is short on gold”を出力するように変更した。
　注文について、課題ではplaceOrder()関数の中でperformPurchaseを呼び出せと指示しているが、ここではmain()関数の中でplaceOrderを呼び出すこととした。


```kotlin:Tavern.kt
import kotlin.math.roundToInt

const val TAVERN_NAME = "Taernyl's Folly"

var playerGold = 10
var playerSilver = 10

fun main() {
    placeOrder("shandy,Dragon's Breath,5.91")
    placeOrder("shandy,Dragon's Breath,5.91")
    placeOrder("shandy,Dragon's Breath,5.91")
}

fun performPurchase(price: Double): Boolean{
    displayBalance()
    val totalPurse = playerGold + (playerSilver / 100.0)
    println("Total purse: $totalPurse")
    println("Purchasing item for $price")

    if(totalPurse >= price) {   // 所持金が価格を上回っているかを判定し、booleanで戻す
        val remainingBalance = totalPurse - price
        println("Remainging balance: ${"%.2f".format(remainingBalance)}")

        val remainingGold = remainingBalance.toInt()
        val remainingSilver = (remainingBalance % 1 * 100).roundToInt()
        playerGold = remainingGold
        playerSilver = remainingSilver
        displayBalance()
        return true
    } else {
        return false
    }
}

private fun displayBalance(){
    println("Player's purse balance: Gold: $playerGold, Silver: $playerSilver")
}

private fun toDragonSpeak(phrase: String) = phrase.replace(Regex("[aeiouAEIOU]")){
    when (it.value){
        "a","A" -> "4"
        "e","E" -> "3"
        "i","I" -> "2"
        "o","O" -> "1"
        "u","U" -> "|_|"
        else -> it.value
    }
}

private fun placeOrder(menuData: String){
    println()
    val indexOfApostrophe = TAVERN_NAME.indexOf('\'')
    val tavernMaster = TAVERN_NAME.substring(0 until indexOfApostrophe)
    println("Madrigal speaks with $tavernMaster about their order.")
    val (type, name, price ) = menuData.split(',')
    var priceDouble = price.toDouble()
    val message = "Madrigal buys a $name ($type) for $price"
    println(message)
    println()

    var hasMoney = performPurchase(price.toDouble())    // 代金を入力し、所持金から差し引く。
                                                        //　もし少なければfalseが戻る    

    if(hasMoney) {                                      
        // 所持金が代金を上回っているとき
        val phrase = if (name == "Dragon's Breath") {
            "Madrigal exclaims ${toDragonSpeak("Ah, delicious $name!")}"
        } else {
            "Madrigal says: Thanks for the: $name."
        }
        println(phrase)
        println()
    } else {
        // 所持金が代金を下回っているとき
        println ("The customer is short on gold!")
    }
}
```

##　チャレンジ８．１１　竜貨
　ドラゴンコインは、金との交換レートが1.43であることを考え、小数点以下の端数が許されると想定して、Doublieで定義した。
　金と銀は今後持たないものと考え、関係するところをコメントアウトし、ドラゴンコイン表示できるように変更した。



```kotlin:Tavern.kt
import kotlin.math.roundToInt

const val TAVERN_NAME = "Taernyl's Folly"

// 当初もっている書時期
//var playerGold = 0          // 金の所持金
//var playerSilver = 0        // 銀の所持金
var playerDragonCoin = 5.0    // ドラゴンコインの所持金(少数点以下の端数が許されると想定して、Doublieで定義）

fun main() {
    placeOrder("shandy,Dragon's Breath,5.91")
    placeOrder("shandy,Dragon's Breath,5.91")
}

fun performPurchase(price: Double): Boolean{
    displayBalance()
    val totalPurse = playerGold + (playerSilver / 100.0) + playerDragonCoin * 1.43  // 全資金について、DragonCoinでのレートを追記
    println("Total purse: $totalPurse")
    println("Purchasing item for $price")

    if(totalPurse >= price) {   // 所持金が価格を上回っているかを判定し、booleanで戻す
        val remainingBalance = totalPurse - price
        println("Remainging balance: ${"%.2f".format(remainingBalance)}")

//        val remainingGold = remainingBalance.toInt()
//        val remainingSilver = (remainingBalance % 1 * 100).roundToInt()
//        playerGold = remainingGold
//        playerSilver = remainingSilver
        playerDragonCoin = remainingBalance / 1.43
        displayBalance()
        return true
    } else {
        return false
    }
}

private fun displayBalance(){
//    println("Player's purse balance:  Gold: $playerGold,  Silver: $playerSilver")
    println("Player's purse balance:  DragonCoin: $playerDragonCoin")       // DragonCoinの所持金を追加    
}

private fun toDragonSpeak(phrase: String) = phrase.replace(Regex("[aeiouAEIOU]")){

    when (it.value){
        "a","A" -> "4"
        "e","E" -> "3"
        "i","I" -> "2"
        "o","O" -> "1"
        "u","U" -> "|_|"
        else -> it.value
    }
}

private fun placeOrder(menuData: String){
    println()
    val indexOfApostrophe = TAVERN_NAME.indexOf('\'')
    val tavernMaster = TAVERN_NAME.substring(0 until indexOfApostrophe)
    println("Madrigal speaks with $tavernMaster about their order.")
    val (type, name, price ) = menuData.split(',')
    var priceDouble = price.toDouble()
    val message = "Madrigal buys a $name ($type) for $price"
    println(message)
    println()

    var hasMoney = performPurchase(price.toDouble())    // 代金を入力し、所持金から差し引く。
                                                        //　もし少なければfalseが戻る

    if(hasMoney) {
        // 所持金が代金を上回っているとき
        val phrase = if (name == "Dragon's Breath") {
            "Madrigal exclaims ${toDragonSpeak("Ah, delicious $name!")}"
        } else {
            "Madrigal says: Thanks for the: $name."
        }
        println(phrase)
        println()
    } else {
        // 所持金が代金を下回っているとき
        // println ("The customer is short on gold!")
        println ("The customer is short on DragonCoin!")
    }
}
```


[第２章チャレンジ！答案](https://qiita.com/guijiu/items/dd3313f2a73401e29bc4)
[第３章チャレンジ！答案](https://qiita.com/guijiu/items/672b8daf014d4e6bb346)
[第４章チャレンジ！答案](https://qiita.com/guijiu/items/08dfa397b989b7ecdb3a)
[第７章チャレンジ！答案](https://qiita.com/guijiu/items/452cfa51bee6c4a4af9d)
[第８章チャレンジ！答案](https://qiita.com/guijiu/items/9a7871b1e41bdabd85e7)
[第１０章チャレンジ！答案](https://qiita.com/guijiu/items/9619abd4d5bf3488e58f)