Part II · Growing the Project
Chapter 8: Numbers Under the Hood
Every room, every choice, every riddle in your game so far has been fixed in advance. Play it twice, get the exact same experience both times. Real games usually have some element of chance, and real programs constantly need to round, measure, and compare numbers. This chapter covers QF Code's math library, and puts it to work building something new: a locked chest with a combination the player has to guess.
Chance and Randomness
random() returns a random number between 0 and 1, not including 1
itself.
writeln(random()) // something like 0.4821...You'll rarely want a fraction like that directly. Almost always, you want
a whole number in a specific range, and that's what randomint() is for.
var roll = randomint(1, 6) // a number from 1 to 6, inclusive on both endsrandomint() always includes both endpoints you give it, and both must be
whole numbers.
Rounding
Four functions handle turning a number into a whole number, each rounding a different direction:
round(4.5) // 5, rounds to the nearest whole number
floor(4.9) // 4, always rounds down
ceiling(4.1) // 5, always rounds upAnd abs() strips away a number's sign, turning any negative number
positive while leaving positive numbers alone:
abs(-7) // 7
abs(7) // 7That last one is more useful than it looks. If you want to know how far
apart two numbers are, without caring which one is bigger, abs() of
their difference gives you the answer.
writeln(abs(50 - 82)) // 32Comparing and Combining
min() and max() return whichever of two numbers is smaller or larger:
min(4, 9) // 4
max(4, 9) // 9pow() raises a number to a power:
pow(2, 10) // 1024sqrt() gives you a square root, and only accepts non-negative numbers,
QF Code raises an error rather than guessing what you meant by the square
root of a negative number.
sqrt(64) // 8Growing the Adventure
Time to build something that uses several of these at once: a locked chest with a hidden combination.
// The Hollow Cottage
// Chapter 8
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)
if distance <= 5 then
writeln("Very warm. " + guessesLeft + " turns left.")
else if distance <= 20 then
writeln("Warm. " + guessesLeft + " turns left.")
else
writeln("Cold. " + guessesLeft + " turns left.")
end if
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]
if verb == "take" then
showInventory(inventory)
else if verb == "look" then
writeln("A small cottage, one room, one door out.")
else if verb == "quit" then
writeln("You step back out into the cold.")
else if verb == "exit" then
writeln("You step back out into the cold.")
else
writeln("Nothing happens.")
end if
end ifThe "warm and cold" hints come straight from abs() measuring the
distance between the guess and the secret number, exactly the kind of
thing that function is built for.
Make It Yours. Change the range, the number of guesses, or the distance thresholds for warm and cold. Try making the hints stricter or more forgiving, and see how it changes the feel of the puzzle.
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 8 starting checkpoint.
Continue from here
Chapter 8 completed checkpoint.
Starting code: the Chapter 7 checkpoint.
Completed code (Chapter 8):
// The Hollow Cottage
// Chapter 8
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)
if distance <= 5 then
writeln("Very warm. " + guessesLeft + " turns left.")
else if distance <= 20 then
writeln("Warm. " + guessesLeft + " turns left.")
else
writeln("Cold. " + guessesLeft + " turns left.")
end if
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]
if verb == "take" then
showInventory(inventory)
else if verb == "look" then
writeln("A small cottage, one room, one door out.")
else if verb == "quit" then
writeln("You step back out into the cold.")
else if verb == "exit" then
writeln("You step back out into the cold.")
else
writeln("Nothing happens.")
end if
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.