尝试/抓住游戏循环

时间:2018-09-20 16:47:08

标签: loops kotlin try-catch

我有这个小小的猜测游戏代码。为了处理字符串输入,我使用了try / catch块。尝试效果很好,但是catch块不在循环中,我似乎无法使其在内部起作用。因此程序在捕获异常后停止。我应该怎么做才能让我的循环在捕获到异常后继续?

fun main(args: Array<String>) {

    val rand = java.util.Random()
    val n = 1 + rand.nextInt(100)
    var guess: Int
    var numberOfTries = 0

    println("I guessed a number from 1 до 100. What is it?\n")

    try {
        do {
            guess = readLine()!!.toInt()
            var x = Math.abs(n - guess)
            numberOfTries++

            when (x) {
                in 1..3 -> println("А-а-аh! It's burning!")
                in 4..7 -> println("Really hot!")
                in 8..15 -> println("Warm")
                in 16..31 -> println("A bit warm!")
                in 32..63 -> println("Pretty cold")
                in 64..99 -> println("It's freezing!")

            }

        } while (guess != n)

    } catch (e: NumberFormatException) {
        println("Use digits, please!") }

    println("Wow! You only used $numberOfTries tries!")
}

2 个答案:

答案 0 :(得分:1)

您应该可以在try...catch中添加do...while块。唯一需要做的其他更改就是用一个值初始化guess(因为不能保证在命中while块之前就设置了该值)

val rand = java.util.Random()
val n = 1 + rand.nextInt(100)
var guess = 0
var numberOfTries = 0

println("I guessed a number from 1 до 100. What is it?\n")

do {
    try {
            guess = readLine()!!.toInt()
            val x = Math.abs(n - guess)
            numberOfTries++

            when (x) {
                in 1..3 -> println("А-а-аh! It's burning!")
                in 4..7 -> println("Really hot!")
                in 8..15 -> println("Warm")
                in 16..31 -> println("A bit warm!")
                in 32..63 -> println("Pretty cold")
                in 64..99 -> println("It's freezing!")

            }
    } catch (e: NumberFormatException) {
        println("Use digits, please!")
    }
} while (guess != n)

println("Wow! You only used $numberOfTries tries!")

答案 1 :(得分:1)

正如MFazio23所述,您可以在while循环中使用try。否则,如果引发异常,它将退出循环。

如果引发异常,则内部的所有内容都将停止,其中包括更多代码。如果您有引发异常的方法,则在该异常之后将不会执行任何代码。 try-catch为异常创建一个入口点。您的代码将在相关的catch块内继续运行(如果没有,则退出程序),这意味着try-catch内部的循环将停止。

但是,您实际上根本不需要try-catch。 Kotlin有一个很好的扩展功能,叫做toIntOrNull,它可以完全满足您的期望。它将尝试将输入转换为int,然后返回数字;如果失败,则返回null。因此,您可以这样做:

fun main(args: Array<String>) {

    val rand = java.util.Random()
    val n = 1 + rand.nextInt(100)
    var guess: Int?
    var numberOfTries = 0

    println("I guessed a number from 1 до 100. What is it?\n")

    do {
        guess = readLine()?.toIntOrNull() // Note that this now uses ?. instead of !!. This is to make the null check useful If it throws an NPE, it kinda defeats the point. If the line is null, it now prints the same message as an invalid number
        // numberOfTries++ // move this up here if you want to count invalid guesses as a guess
        if(guess == null){
            System.out.println("Only use numbers")
            continue;
        }
        val x = Math.abs(n - guess)// I also changed this to a val; it's immutable, so it doesn't need to be a var
        numberOfTries++

        when (x) {
            in 1..3 -> println("А-а-аh! It's burning!")
            in 4..7 -> println("Really hot!")
            in 8..15 -> println("Warm")
            in 16..31 -> println("A bit warm!")
            in 32..63 -> println("Pretty cold")
            in 64..99 -> println("It's freezing!")
        }
    } while (guess != n)
    println("Wow! You only used $numberOfTries tries!")

}

您还可以进一步优化它,但是使用扩展函数/变量(我不确定它是什么,它是一个声明为扩展函数的变量,但是由于也有吸气剂,因此我不确定该怎么做。称为absoluteValue

您也可以使用if语句,但是它比使用if语句要简单得多。您不能使用空值调用Math.abs,因为它使用原语。 Java中的基元永远不能为null。

这意味着您传递给您的任何方法都不能为null,这在Kotlin中意味着实例Int。如果它可以为null,则为Int?,但是该方法要求Kotlin提供非null。您不能将Int?传递给Int(可以用另一种方法来实现,但这在这里不重要)。

在后台,.absoluteValue会调用Math.abs(n),但是由于它是一个调用,因此可以使用null安全运算符(?.

guess = readLine()?.toIntOrNull() 
val x = guess?.absoluteValue
numberOfTries++
when (x) {
    in 1..3 -> println("А-а-аh! It's burning!")
    in 4..7 -> println("Really hot!")
    in 8..15 -> println("Warm")
    in 16..31 -> println("A bit warm!")
    in 32..63 -> println("Pretty cold")
    in 64..99 -> println("It's freezing!")
    null -> println("Please only use numbers")
}

现在x可为空,您可以将null添加到when语句中(以响应您的评论)。

此外,如果您只想让numberOfTries增加有效数字,请在调用前添加if(x != null)