Part II · Growing the Project
Chapter 9: Choosing Between Many Things
Your command parser only handles two real commands right now, take and
look, chained together with if and else if. That's fine for two.
Add a help, a quit, and an inventory command, and you'd have a stack
of five else if branches checking the same variable over and over. QF
Code has a tool built specifically for exactly that situation.
The match Statement
match checks one value against several possibilities and runs whichever
branch actually matches.
match verb
when "take"
showInventory(inventory)
when "look"
writeln("A small cottage, one room, one door out.")
when else
writeln("Nothing happens.")
end matchwhen else plays the same role else does in an if chain, it's what
runs when nothing above it matched. It's optional, if you leave it out
and nothing matches, match simply does nothing and moves on.
Stacking Values
Sometimes more than one value should trigger the same response. Stack
them by listing several when lines in a row before the shared body:
match verb
when "quit"
when "exit"
writeln("You step back out into the cold.")
when else
writeln("Nothing happens.")
end matchEither "quit" or "exit" runs that same line. match checks its
values in order and stops at the first one that fits, so once a branch
matches, nothing below it is even considered.
Ranges
match can also test whether a number falls inside a range, using to:
match score
when 90 to 100
writeln("A")
when 80 to 89
writeln("B")
when else
writeln("C or below")
end matchRanges are inclusive on both ends, 90 to 100 matches 90 and 100
themselves, not just what's strictly between them.
match Compared to if
match and a long if/else if chain can often do the same job, but
match reads better once you're checking one value against more than a
couple of possibilities. There's no meaningful difference in what they
can accomplish, just in how clearly the code communicates what it's
doing. A five-branch if chain forces a reader to check every condition
individually to see what's being compared. A match block says it once,
at the top, and lets every branch underneath stay short.
Growing the Adventure
First, the command parser gets cleaner:
match verb
when "take"
showInventory(inventory)
when "look"
writeln("A small cottage, one room, one door out.")
when "quit"
when "exit"
writeln("You step back out into the cold.")
when else
writeln("Nothing happens.")
end matchAnd the chest's warm/cold hints from chapter 8, which were three stacked
if/else if checks against ranges, turn into this:
match distance
when 0 to 5
writeln("Very warm. " + guessesLeft + " turns left.")
when 6 to 20
writeln("Warm. " + guessesLeft + " turns left.")
when else
writeln("Cold. " + guessesLeft + " turns left.")
end matchSame behavior, easier to scan.
Make It Yours. Add a fourth or fifth command to the match block,
something your version of the game should respond to, and stack at least
two values onto one shared when branch somewhere in your own code.
Chapter Checkpoint
Open either known-good checkpoint directly in QF Code, or download the .qfc file to keep locally. The IDE opens in a new tab and does not run the program automatically.
Start this chapter
Chapter 9 starting checkpoint.
Continue from here
Chapter 9 completed checkpoint.
Starting code: the Chapter 8 checkpoint.
Completed code (Chapter 9):
// The Hollow Cottage
// Chapter 9
const cottageName = "The Hollow Cottage"
function showInventory(items)
writeln("You are carrying:")
for each item in items
writeln("- " + item)
end for
end function
writeln("You are standing outside " + cottageName + ".")
var playerName = input("What is your name, traveler? ")
writeln("Welcome, " + playerName + ".")
var tries = 0
var solved = false
while tries < 3 and not solved
tries = tries + 1
var answer = input("There is a riddle carved into the door. It asks: what has keys but no locks? ")
if lower(trim(answer)) == "piano" then
writeln("The door swings open. You step inside.")
solved = true
else
writeln("Nothing happens.")
end if
end while
if not solved then
writeln("The door refuses to budge. You'll have to find another way in.")
else
writeln("You step inside. In the corner sits a locked chest with a dial numbered 1 to 100.")
var secret = randomint(1, 100)
var guessesLeft = 6
var found = false
while guessesLeft > 0 and not found
var guess = num(input("Turn the dial to a number (1-100): "))
guessesLeft = guessesLeft - 1
if guess == secret then
writeln("The chest clicks open!")
found = true
else
var distance = abs(guess - secret)
match distance
when 0 to 5
writeln("Very warm. " + guessesLeft + " turns left.")
when 6 to 20
writeln("Warm. " + guessesLeft + " turns left.")
when else
writeln("Cold. " + guessesLeft + " turns left.")
end match
end if
end while
var inventory = array()
append(inventory, "rusty key")
append(inventory, "half-burned candle")
if not found then
writeln("The dial jams. The chest stays locked, for now.")
else
append(inventory, "small silver coin")
writeln("Inside, you find a small silver coin.")
showInventory(inventory)
end if
var command = input("What do you do? ")
var words = split(lower(trim(command)), " ")
var verb = words[0]
match verb
when "take"
showInventory(inventory)
when "look"
writeln("A small cottage, one room, one door out.")
when "quit"
when "exit"
writeln("You step back out into the cold.")
when else
writeln("Nothing happens.")
end match
end ifCopyright © 2026 Edison Mooers. Published by Gibidda Press. Free for personal learning and qualifying noncommercial educational use. Commercial training, organizational use, redistribution, and adaptation require written permission. Full use terms.