Number guessing game in Kotlin
Some suggestions:


Semi-colons are optional so, avoid them if possible.
Use type inference when possible. For example:

val aInteger = 1 // Int is inferred by the compiler as the type of `aInteger`

val aListOfInt = listOf(1, 2) // List&lt;Int&gt; is inferred by the compiler as the type of `aListOfInt`

Constructors, in particular primary constructor, are very powerful. For example: class Guesser(val range: IntRange = 1..100) is equivalent to:

class Guesser(range: IntRange) {
  val range = range

  constructor(): this(1..100)
}

val is for read-only properties. If you need to re-assign a property, use var instead.
The use of raw strings with the trimMargin() member function is preferable over multiple println invocations.
The when expression is similar to the more traditional switch. You can learn more about it here.


This is the whole thing:

class Guesser(val range: IntRange = 1..100) {
  private var upperLimit = range.last
  private var lowerLimit = range.first
  private var turnCount = 0
  private var lastGuess = 0
  private var lastResponse = Response.UNKNOWN

  init {
    printIntro()

    while (lastResponse != Response.CORRECT) {
      lastResponse = presentNextGuess()
      turnCount++

      when (lastResponse) {
        Response.CORRECT -&gt; println("I guessed your number in $turnCount turns.")
        Response.UNKNOWN -&gt; println("I'm sorry, I didn't understand that.")
      }
    }
  }

  fun calcNextGuess(): Int {
    var roundingFactor = 0

    when (lastResponse) {
      Response.HIGHER -&gt; {
        lowerLimit = lastGuess
        roundingFactor = 1 //compensates for rounding down
      }
      Response.LOWER -&gt; {
        upperLimit = lastGuess
      }
      else -&gt; assert(false) // Assume error if this is reached
    }

    return (lowerLimit + ((upperLimit - lowerLimit) / 2)) + roundingFactor
  }

  fun presentNextGuess(): Response {
    val nextGuess = calcNextGuess()

    println("Is your number $nextGuess?")

    val response = readLine()

    lastGuess = nextGuess

    return parseResponse(response)
  }

  fun parseResponse(response: String?) = when (response?.toLowerCase()) {
    null -&gt; Response.UNKNOWN
    "higher", "h" -&gt; Response.HIGHER
    "lower", "l" -&gt; Response.LOWER
    "yes", "y" -&gt; Response.CORRECT
    else -&gt; Response.UNKNOWN
  }

  fun printIntro() {
    println(
      """
        Think of a number between 1 and 100. I am going to try and guess it.
        If i guess correctly respond with 'yes' (or 'y')
        Otherwise respond to with either 'higher' (or 'h') or 'lower' (or 'l')
        Okay, here we go...
      """.trimIndent()
    )
  }

  enum class Response {
    HIGHER, LOWER, CORRECT, UNKNOWN
  }
}

fun main(args:Array&lt;String&gt;) {
  Guesser()
}


Note: I'm also learning the language and I could be wrong with some things so, the above code can be improved and is not free of mistakes and non-idiomatic constructs.