Challenge: Configurable Status Format

Here’s my solution, but is there a better way?

fun main() {
val name = "Madrigal"
var healthPoints = 89
val isBlessed = true
val isImmortal = false

// Karma
val karma = (Math.pow(Math.random(), (110 - healthPoints) / 100.0) * 20 ).toInt()

// Aura
val auraVisible = isBlessed && healthPoints > 50 || isImmortal
val auraColor = when (karma) {
    in 0..5 -> "red"
    in 6..10 -> "orange"
    in 11..15 -> "purple"
    in 16..20 -> "green"
    else -> ""
}

val healthStatus = when (healthPoints) {
    100 -> "is in excellent condition!"
    in 90..99 -> "has a few scratches."
    in 75..89 -> if (isBlessed) {
        "has some minor wounds but is healing quite quickly!"
    } else {
        "has some minor wounds."
    }
    in 15..74 -> "looks pretty hurt."
    else -> "is in awful condition!"
}

val statusFormatString = "(B: ${if (isBlessed) "YES" else "NO"}) (HP: $healthPoints) (A: ${if (auraVisible) auraColor else "NONE"}) -> $name $healthStatus"

// Player status
println(statusFormatString)

}

Hello,

i think you should check this post:

Best Regards

exactly i’m also thinking that they said its bit harder challenge but its easy the way you did i’m thinking the same way

I think this provides a nice clean implementation. There must be a more idiomatic way of doing the string substitutions, though.

val formatString = "(HP)(A)(B) -> (H)"
val formatSpecifiers = "HP|H|A|B".toRegex()

var result = StringBuffer()

var i = 0
formatSpecifiers.findAll(formatString).forEach { match ->
    result.append(formatString.substring(i,match.range.start))
    result.append(when (match.value) {
        "H" -> "$name $healthStatus"
        "HP" -> "$healthPoints"
        "A" -> "$aura"
        "B" -> "$isBlessed"
        else -> "?"
    })
    i = match.range.last+1
   }
   result.append(formatString.substring(i))

   println("$result")

The idea here is to provide a regular expression that will match each of the possible substitution specifers. Use regex.findAll() to return a list of all of the matches in the string, and then loop through the format string pulling out a piece at a time, substituting the actual value for each matched sustitution specifier. If you wanted to add a new specifier token, add it to the regular expression, and the corresponding replacement operation in the when statement.

For example,

val karma = (Math.pow( Math.random(), (110-healthPoints)/100.0) * 20).toInt()
val formatString = "(HP)(A)(B)(K) -> (H)"
val formatSpecifiers = "HP|H|A|B|K".toRegex()

and

    result.append(when (match.value) {
        "H" -> "$name $healthStatus"
        "HP" -> "$healthPoints"
        "A" -> "$aura"
        "B" -> "$isBlessed"
        "K" -> "$karma"
        else -> "?"
    })

yields a result that looks like this when run – adding the computed karma value if you did that challenge:

(75)(GREEN)(true)(19) → (Madrigal has some minor wounds but is healing quite quickly!)

Hi. Tell me pls, is this right(enough?) to complete this challenge?

val statusString = “(HP)(A)(B) → H”
println(statusString.replace(“HP”,“$healthPoint”)
.replace(“A”, if (auraVisible) auraColor else “NONE”)
.replace(“B”, if (isBlessed) “YES” else “NO”)
.replace(“H”, “$name $healthStatus”))

Hi, little remark, the solutions above output the following:
“(100)(Green) -> Madrigal is in excellent condition!”
but in challenge result must be:
“(HP: 100)(Aura: Green) -> Madrigal is in excellent condition!”

tnx aparatus, had to use full Kotlin version of replace to work:
var statusString:String="(HP)(A)(B) -> H"
var printString =statusString.replace(“HP”,“Points: $healthPoints”, ignoreCase = false)
.replace(“A”,“Aura: auraColor",ignoreCase = false) .replace("B","Blessed: {if (isBlessed) “YES” else “NO”}”,ignoreCase = false)
.replace(“H”,"$name $healthStatus",ignoreCase = false)

println(printString)

to give:
(Points: 89)(Aura: ORANGE)(Blessed: YES) -> Madrigal has some minor wounds but is healing quite quickly

The most correct solution is here: GitHub - AlexeyYuditsky/TheBigNerdRanchGuide

import kotlin.math.pow

fun main() {

    val name = "Madrigal"
    var healthPoints = 51
    val isBlessed = true
    val isImmortal = false
    val formula = (Math.random().pow((110 - healthPoints) / 100.0) * 20).toInt()

    val auraVisible = isBlessed && healthPoints > 50 || isImmortal
    val auraColor = if (auraVisible) "GREEN" else "NONE"

    val karma = when (formula) {
        in 0..5 -> "red"
        in 6..10 -> "orange"
        in 11..15 -> "purple"
        in 16..20 -> "green"
        else -> "player's health entered incorrectly"
    }

    val healthStatus = when (healthPoints) {
        100 -> "is in excellent condition!"
        in 90..99 -> "has a few scratches!"
        in 75..89 -> if (isBlessed) "has some minor wounds but is healing quite quickly!" else "has some minor wounds!"
        in 15..74 -> "looks pretty hurt!"
        else -> "is in awful condition!"
    }

    val A = "(Aura: $auraColor)"
    val B = "(Blessed: ${if (isBlessed) "Yes" else "No"})"
    val H = "$name $healthStatus"
    val K = "(Karma: $karma)"
    val HP = "(Health: $healthPoints)"

    val statusFormatString = "$HP $A $B $K -> $H"
    println(statusFormatString)

}