Skip to Content
Course content

8: Ranges and Progressions

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Ranges in Kotlin are more than just a shorthand for writing loops; they're a first-class way to express "a span of values." I find myself using them constantly for validation and slicing data. To show you how they actually work in a project, let's build a simple Reward System for a game. We want to give players different titles based on their level and print a countdown when they're approaching a boss fight.

Mapping levels to player titles

The most common way to create a range is using the .. operator. This creates a closed range, meaning both the start and the end are included. I like using this with the in operator because it reads almost like a sentence in English.

fun getPlayerTitle(level: Int): String {
    return if (level in 1..10) {
        "Novice"
    } else if (level in 11..30) {
        "Warrior"
    } else if (level in 31..100) {
        "Legend"
    } else {
        "Unknown"
    }
}

It's clean, right? No more clunky level >= 1 && level <= 10 logic. If you need to check the opposite, you can just use !in to see if a value falls outside a range.

The "Off-by-One" trap

Here is where I usually trip up when I'm moving fast. Let's say I have a list of reward descriptions and I want to iterate through them using a range to print them out. I'll try to use the standard .. operator.

val rewards = listOf("Bronze Sword", "Silver Shield", "Golden Armor")
for (i in 0..rewards.size) {
    println("Reward ${i + 1}: ${rewards[i]}")
}

If you ran this, your program would crash with an IndexOutOfBoundsException. Why? Because rewards.size is 3, and 0..3 includes the number 3. But since lists are zero-indexed, the last valid index is 2. I forgot that .. is inclusive.

To fix this, I should use the until keyword. It creates a range that excludes the end element. Here is the corrected version:

for (i in 0 until rewards.size) {
    println("Reward ${i + 1}: ${rewards[i]}")
}

Counting down and skipping steps

Sometimes you don't want to go up by one. If we're approaching a boss fight at level 50, we might want to warn the player every 5 levels as they get closer. For this, we use downTo for reverse ranges and step to change the increment.

I'll write a quick function that simulates a "Boss Warning" sequence starting from level 50 and counting down to 30, but only hitting every 5th level.

fun printBossWarnings() {
    println("Prepare yourself!")
    for (level in 50 downTo 30 step 5) {
        println("Warning: Boss territory starts at level $level")
    }
}

The step modifier is incredibly useful for pagination or processing every Nth item in a dataset. Just remember that downTo is necessary because 50..30 would actually result in an empty range—Kotlin won't automatically assume you want to go backwards just because the first number is larger.




📋 Practical Task

The Tiered Experience Calculator

Build a small program that takes a user's "Experience Points" (XP) as an integer and determines their rank using ranges. Implement the following logic:

  • XP 0 to 1000 (inclusive): "Beginner"
  • XP 1001 to 5000 (inclusive): "Intermediate"
  • XP 5001 to 10000 (inclusive): "Expert"
  • Anything above 10000: "Grandmaster"

Additionally, use a for loop with a step to print a "Milestone Check" message for every 2000 XP from 0 up to and including 10000 (e.g., 0, 2000, 4000...).

Rating
0 0

There are no comments for now.

to be the first to leave a comment.