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.

QF Code example 1
match verb
    when "take"
        showInventory(inventory)
    when "look"
        writeln("A small cottage, one room, one door out.")
    when else
        writeln("Nothing happens.")
end match

when 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:

QF Code example 2
match verb
    when "quit"
    when "exit"
        writeln("You step back out into the cold.")
    when else
        writeln("Nothing happens.")
end match

Either "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:

QF Code example 3
match score
    when 90 to 100
        writeln("A")
    when 80 to 89
        writeln("B")
    when else
        writeln("C or below")
end match

Ranges 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:

QF Code example 4
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

And the chest's warm/cold hints from chapter 8, which were three stacked if/else if checks against ranges, turn into this:

QF Code example 5
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

Same 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.

Starting code: the Chapter 8 checkpoint.

Completed code (Chapter 9):

QF Code example 6Open in QF Code
// 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 if

Next: your game has been trusting the player to type sensible things. Chapter 10 teaches you what to do when they don't.


Copyright © 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.