At some point when you are writing code you will need some sort of rules to determine when and if one specific thing should be done or not. This is known as control flow. By using these control flow features you can define conditions for when specific portions of your code should be executed. The if-else, if, when, while, for, and do are some flow control statements examples used in Kotlin.
If/else
The main structure of an if/else statement is this:
if (condition) {
execute some code
} else {
execute this other code
}
This translates to If the condition you determined inside the parenthesis applies, the program will execute the code inside the first curly brackets. If the condition is not met the program will skip the instructions inside the first curly brackets and execute what comes after the else part.
In the example below, the program will print a different sentence based on the score for the teams playing. So, if the score of the home team, which is being saved in the variable homeTeamScore
is greater than the score of the visitor team (visitorTeamScore) the program will print “YAY we are winning”, otherwise, if the condition is not met, meaning the home team score is lower than the visitor’s score and it will print “Boohoo we are loooosing”

You can add multiple conditions that need to be met, you can combine conditions using the && (and) or the || (or) operators, you can also add multiple statements to be executed if the conditions are met or not, you can also use nested if statements like this:

In this case, there is a nested if statement. There’s one condition that is the Home Team is winning. If they are, then there’s the “child” if statement
that says if they are winning by one point only, the program will say “YAY, we are winning! But just by 1 point. We need moaaaaar!”
If the home team is winning, but by more than one point the program will print only “YAY, we are winning!”
And if it’s losing it will print the usual “Boohoo, we are loooosing”
It’s also possible to add another if statement
(not nested) using an else if
block.

In this case, if the first condition is false the program will skip the code inside the first if statement
and check the next block (the else if
in this case). If the score is a tie it will print “Let’s go, team! One more point!”. If this second block is also not met, then it defaults to the else statement.
That said, in Kotlin, the else statement
is not required. You can use it if you need it but it’s optional. In this case, if the condition in the if statement is not met (it evaluates to false) the program will simply run the code right after it.
Logical Operators
The use of else if
statements and nested loops, while very handy, can easily get out of control depending on how many conditionals you need to add. They can get really wordy you might end up with a lot of duplicates and unnecessary code. That when
logical operators come in handy.
In order to demonstrate this, let’s move away from the game example above and dive into something a bit more elaborated. Imagine you are creating a solo RPG.
Consider the following code:
const val HERO_NAME = "Aragorn"
fun main () {
val playerOne = "Frodo"
val playerTwo = "Sam"
//Define if Players have a pony and need a place in the stable
val hasAPony = true
// Define if the players noticed the strange figure sitting in the back of the room
val noticedStrangeFigure = true
//Defines if there are available tables in the back of the room close to the strange figure
val hasAvailableTable = true
println("It's a cold and rainy night. Locals are sheltering in the Prancing Pony Inn and having drinks.")
println("A strange figure sits at the back of the room smoking a pipe")
println("$playerOne and $playerTwo enter the room")
println("The innkeeper greets the travellers: Welcome to the Prancy Pony, my friends. " +
"Do you need to stable a horse or a pony?")
println(hasAPony)
println("Innkeeper: Great! Anything to drink?")
println("Frodo: Yes, water, please ")
println("Innkeeper: Here it is. Take a seat here at the bar or find a table in the back if you want")
if (!noticedStrangeFigure && hasAvailableTable) {
println("Frodo and Sam go grab a table in the back without noticing the stranger following their moves")
} else {
println("Frodo and Sam notice a strange figure looking at them and decide to take a seat at the bar")
}
You have the hero name that won’t change so we declare it as a compile-time constant. Let’s say the players can choose who they wanna play with, so we add the player variables as regular variables. You can choose to play with Frodo and Sam, or Merrin and Pippin, or Legolas and Gimli and so on, so we define them within the main function.
const val HERO_NAME = "Aragorn"
fun main () {
val playerOne = "Frodo"
val playerTwo = "Sam"
...
Then we declare a variable that will tell if the players have a pony or not, one to determine if they notice Aragorn’s presence when they go in and one to determine if there are tables available at the back of the room. Since all three variables will have yes or no (true or false) answers they are of type boolean.
When the players enter the inn they are greeted by the innkeeper a conversation starts. After they grab a drink, they need to decide where to sit. They can either sit in the bar or grab a table at the back of the room. Some conditions will apply and influence their decision. If there is a table available at the back and they don’t notice Aragorn’s presence, they will choose to sit at the back. If there is a table available but they do notice Aragorn there, they will choose to sit in the bar.
if (!noticedStrangeFigure && hasAvailableTable) {
println("Frodo and Sam go grab a table in the back without noticing the stranger following their moves")
} else {
println("Frodo and Sam notice a strange figure looking at them and decide to take a seat at the bar")
}
Here, to determine two conditions, instead of using another if statement
we can use the logical operator && if (!noticedStrangeFigure && hasAvailableTable)
In order to make the code easier to read and less verbose you can combine conditions using the following operators:
Operator | What it does |
&& | Logical AND – When you need two or more conditions to be met |
|| | Logical OR – When you need either one of the conditions to be true |
! | Logical NOT – Returns the opposite of a boolean value |
📌 Worth noting that in Kotlin, when you have one single response for a given condition you can remove the curly braces {} and the code would work just the same.
So this:
if (!noticedStrangeFigure && hasAvailableTable) {
println("Frodo and Sam go grab a table in the back without noticing the stranger following their moves")
} else {
println("Frodo and Sam notice a strange figure looking at them and decide to take a seat at the bar")
}
Works the exact same way this does:
if (!noticedStrangeFigure && hasAvailableTable)
println("Frodo and Sam go grab a table in the back without noticing the stranger following their moves")
else
println("Frodo and Sam notice a strange figure looking at them and decide to take a seat at the bar")
An if statement can be simplified even further if it has only one response for each condition:
val hasPony: Boolean
val needStable = if(hasPony) "I need a place for my pony" else "I don't need stable".
When Expressions
Another very useful control flow mechanism is the When
expression available in Kotlin. It works just like the if/else mechanism, checking different conditions and executing code based on if these conditions evaluate to true or false. For example, let’s say we need to provide weapons based on the character’s choices:
val character = "Legolas"
val giveWeapon: String = when (character) {
"Legolas" -> "Here's your bow and a quiver with neverending arrows"
"Aragorn" -> "Here's your long sword"
"Gimli" -> "Here's your axe"
"Frodo" -> "Here's your dagger"
"Sam" -> "Here's your dagger"
"Merry" -> "Here's your dagger"
"Pippin" -> "Here's your dagger"
else -> "You are not allowed to carry a weapon"
}
This is way easier to read. We have a variable called Character and depending on who the character is you provide a different weapon. The character value (condition) is set on the left side of the ->
(arrow operator) and the equivalent condition to the right. The else part of the mechanism says that if you are not one of the people listed in the When Statement, you are not allowed to carry a weapon. So, if any rogue value is entered the else branch will take care of it.
By default, a when expression
behaves as if there was an equality (==)
operator between the argument you provide (in this case, the variable character
) in parentheses and the conditions you specify in the curly braces. So, if character == Aragorn
print "Here's your long sword"
. You are using the when expression
to assign a value to the variable weapon.
You can also use When Expressions without an argument to avoid some of its limitations. The When Expression does not take multiple arguments and, if you add one, it can only use the ==
, in
, or is
are allowed.
For cases when you need to use other comparison operators you can use the When Expression like this:
Let’s say you would like to let the player know about their current XP status:
val xpStatus: String = when {
experiencePoints >= requiredXP -> {
"Ding! You have reached a new level"
}
experiencePoints - requiredXP < 50 -> {
"You are close. Keep working"
}
else -> "You need more points"
}
println(xpStatus)
In this case, you have the variable xpStatus
which will hold the result of the when expression. You have a variable called experiencePoints
that holds the current amount of experience points a player has and you have the requiredXP
variable which holds the number of experience points needed to level up. So, you are basically presenting some conditions about what should be printed when you call the println(xpStatus)
function and pass the xpStatus
argument.
For Loops
The For Loop is a control flow that goes through every item within a given context. So, for example, let’s say you want to print every item in a list or a range. You can use the for loop for that and it would look like this:
for (i in 1..10) { println(i)}
And this would be the result:

Or you could do something a bit more complex like this:
for (i in 12 downTo 0 step 3) {
println(i)
}
And as a result, you would have the system printing down from 12 to 0 skipping 3 numbers:

While Loops
While and do-while loops will execute a task while a certain condition is true. It will loop several times, checking if the condition still applies and while it does, it will execute their body continuously.
There is a small difference between the while and do-while loops.
The While Loop will check the condition and if the condition applies the body is executed. For example:
while(x > 10) {
x--
}
So, let’s say you have a variable val x = 1
2 the While Loop would check the condition within the parenthesis (x > 10)
and in this case, it evaluates to true because 12 is greater than 10. It then executes its body: x--
X is now 11. The loop goes back to check the condition and it still applied. 11 > 10
so the body executes again and x is now 10. The loop will check the condition one more time and this time it evaluates to false because x now equals 10 and 10 is not greater than 10, so the loop stops and the code continues to whatever is next.
If in the same situation above, x had a value of 10 since the beginning, the loop would have checked the condition, it would have been evaluated to false and it would never execute the body, skipping the loop altogether and going to the next line of code after the loop.
The do-while loop on the other hand checks the condition at the end of the loop. So, it executes the body and then checks the condition, which means the body will be executed at least once before the loop breaks.
It looks like this:
do {
// code to run
{
while(condition)
And here’s an example of an actual code:
var number = 6
var factorial = 1
do {
factorial *= number
number--
} while(number > 0)
println("Factorial of 6 is $factorial")
The output for the code above is as you can see below. In this case, we are calculating the factorial of a given number. The number is stored in the variable number
and the do while loop
is multiplicating the initial number (in this case, 6) by the next number which is the current number minus one (number--
) while number
is greater than zero and then printing the result. So we have 6 (the initial number) * 5 * 4 * 3 * 2 * 1 = 720 or 6! (Factorial of 6)
