To complete the transaction, the price of the item should be deducted from the patron’s purse. The patronGold map associates gold balance values with a given patron’s name as a key. You will modify the gold balance value for a patron to record the patron’s new balance once the purchase is completed.
Your performPurchase and displayBalance functions are tied to Madrigal’s purse and get into details of gold and silver pieces that are not needed here. Delete them and the playerGold and playerSilver variables, which are only used in those functions. Then define a new performPurchase function to handle a patron purchase. (You will define a new function to display patron balances soon.)
To update the value after the purchase is made, the function will get it from the patronGold map using the patron’s name. Call the new performPurchase function after the patron speaks to Taernyl, the tavern master, about their order (do not forget to uncomment the call).
Listing 11.6 Updating the values in patronGold
(Tavern.kt
)
import java.io.File import kotlin.math.roundToInt const val TAVERN_NAME: String = "Taernyl's Folly"var playerGold = 10var playerSilver = 10val patronList = mutableListOf("Eli", "Mordoc", "Sophie") ...fun performPurchase(price: Double) {displayBalance()val totalPurse = playerGold + (playerSilver / 100.0)println("Total purse: $totalPurse")println("Purchasing item for $price")val remainingBalance = totalPurse - priceprintln("Remaining balance: ${"%.2f".format(remainingBalance)}")val remainingGold = remainingBalance.toInt()val remainingSilver = (remainingBalance % 1 * 100).roundToInt()playerGold = remainingGoldplayerSilver = remainingSilverdisplayBalance()}private fun displayBalance() {println("Player's purse balance: Gold: $playerGold , Silver: $playerSilver")}fun performPurchase(price: Double, patronName: String) { val totalPurse = patronGold.getValue(patronName) patronGold[patronName] = totalPurse - price } private fun toDragonSpeak(phrase: String) = ... } private fun placeOrder(patronName: String, menuData: String) { ... println(message)//performPurchase(price.toDouble(), patronName) val phrase = if (name == "Dragon's Breath") { ... } ...
Run Tavern.kt. You will continue to see ten random orders along the lines of:
The tavern master says: Eli's in the back playing cards. The tavern master says: Yea, they're seated by the stew kettle. Mordoc Fernsworth speaks with Taernyl about their order. Mordoc Fernsworth buys a goblet of LaCroix (meal) for 1.22. Mordoc Fernsworth says: Thanks for the goblet of LaCroix. ...
You have updated the patron’s gold balance, and only one task remains – reporting the patrons’ gold balances after they make their purchases. You will do this by iterating through your map using forEach.
Add a new function to Tavern.kt called displayPatronBalances that iterates through the map, printing the final gold balance (formatted to the second decimal place, as you did in Chapter 8) for each patron. Call it after the simulation completes in the main function.
Listing 11.7 Displaying patron balances (Tavern.kt
)
... fun main(args: Array<String>) { ... var orderCount = 0 while (orderCount <= 9) { placeOrder(uniquePatrons.shuffled().first(), menuList.shuffled().first()) orderCount++ } displayPatronBalances() } private fun displayPatronBalances() { patronGold.forEach { patron, balance -> println("$patron, balance: ${"%.2f".format(balance)}") } } ...
Run Tavern.kt, sit back, and watch as the patrons of Taernyl’s Folly chat with the tavern master, order off the menu, and pay for their items:
The tavern master says: Eli's in the back playing cards. The tavern master says: Yea, they're seated by the stew kettle. Mordoc Ironfoot speaks with Taernyl about their order. Mordoc Ironfoot buys a iced boilermaker (elixir) for 11.22. Mordoc Ironfoot says: Thanks for the iced boilermaker. Sophie Baggins speaks with Taernyl about their order. Sophie Baggins buys a Dragon's Breath (shandy) for 5.91. Sophie Baggins exclaims: Ah, d3l1c10|_|s Dr4g0n's Br34th! Sophie Ironfoot speaks with Taernyl about their order. Sophie Ironfoot buys a pickled camel hump (desert dessert) for 7.33. Sophie Ironfoot says: Thanks for the pickled camel hump. Eli Fernsworth speaks with Taernyl about their order. Eli Fernsworth buys a Dragon's Breath (shandy) for 5.91. Eli Fernsworth exclaims: Ah, d3l1c10|_|s Dr4g0n's Br34th! Sophie Fernsworth speaks with Taernyl about their order. Sophie Fernsworth buys a iced boilermaker (elixir) for 11.22. Sophie Fernsworth says: Thanks for the iced boilermaker. Sophie Fernsworth speaks with Taernyl about their order. Sophie Fernsworth buys a Dragon's Breath (shandy) for 5.91. Sophie Fernsworth exclaims: Ah, d3l1c10|_|s Dr4g0n's Br34th! Sophie Fernsworth speaks with Taernyl about their order. Sophie Fernsworth buys a pickled camel hump (desert dessert) for 7.33. Sophie Fernsworth says: Thanks for the pickled camel hump. Mordoc Fernsworth speaks with Taernyl about their order. Mordoc Fernsworth buys a Shirley's Temple (elixir) for 4.12. Mordoc Fernsworth says: Thanks for the Shirley's Temple. Sophie Baggins speaks with Taernyl about their order. Sophie Baggins buys a goblet of LaCroix (meal) for 1.22. Sophie Baggins says: Thanks for the goblet of LaCroix. Mordoc Fernsworth speaks with Taernyl about their order. Mordoc Fernsworth buys a iced boilermaker (elixir) for 11.22. Mordoc Fernsworth says: Thanks for the iced boilermaker. Mordoc Ironfoot, balance: -5.22 Sophie Baggins, balance: -1.13 Eli Fernsworth, balance: 0.09 Sophie Fernsworth, balance: -18.46 Sophie Ironfoot, balance: -1.33 Mordoc Fernsworth, balance: -9.34
In the last two chapters, you learned how to work with Kotlin’s List, Set, and Map collection types. Table 11.3 compares their features.
Table 11.3 Kotlin collections summary
Collection type | Ordered? | Unique? | Stores | Supports destructuring? |
---|---|---|---|---|
List | Yes | No | Elements | Yes |
Set | No | Yes | Elements | No |
Map | No | Keys | Key-value pairs | No |
Since collections are read-only by default, you must explicitly create a mutable collection (or convert a read-only collection to be mutable) to modify its contents – preventing you from accidentally adding or removing elements.
In the next chapter, you will learn how to apply object-oriented programming principles as you define your own classes within NyetHack.