asked list on the left tracks which have been used), with no question ever repeating in the same game. Two-player mode and the high-score panel arrive in later lessons.Learning Goals 3 min
By the end of this lesson you will be able to:
- Pick a random index from a list with pick random (1) to (length of [questions v]), and explain why this alone repeats questions.
- Maintain a third list, asked, that records every index already used this game, and check it with <[asked v] contains ( ) ?>.
- Loop with repeat until < > to re-roll a fresh index whenever the random number collides with one already in asked.
Warm-Up — predict the boring quiz 7 min
Last lesson you built a 10-question Malaysia bank. Today's job: ask them in a random order, never repeating, until every question has been asked exactly once.
A first attempt — just pick a random index each round:
when flag clicked
repeat (length of [questions v])
set [i v] to (pick random (1) to (length of [questions v]))
ask (item (i) of [questions v]) and wait
end
Play it mentally with 10 questions. Round 1 picks 7. Round 2 picks 3. Round 3 picks 7. Round 4 picks 9. Round 5 picks 3... What's happening?
Reveal the answer
Every round is an independent dice roll. pick random (1) to (10) doesn't remember it rolled 7 last time — it might roll 7 again next time. With 10 rounds and 10 options, you typically see 3–4 questions repeat and 3–4 questions never appear at all. The player thinks the quiz is broken.
The fix is memory: a third list called asked that tracks which indices have been used. Before asking, check if the random index is already in asked. If yes, re-roll. If no, add it to asked and ask the question. After 10 rounds, all 10 indices are in asked — every question fired exactly once.
New Concept — the re-roll trick 15 min
Professional shuffle algorithms (like the Fisher–Yates shuffle) reorder the whole list once and then walk through it in order. They're fast and elegant — but the Scratch blocks needed for in-place swapping get fiddly. Today we use a simpler trick that's perfect for quiz-sized banks (10 to 50 questions): re-roll on collision.
The trick in plain words
- Make a third list, asked. Empty it on green flag.
- Roll a random index i from 1 to length of [questions v].
- If asked already contains i, roll again. Keep rolling until you get a fresh one.
- Add i to asked, ask item (i) of [questions v].
- Repeat until asked is as long as questions — every question has been asked.
The "contains" reporter
The boolean <[asked v] contains ( ) ?> reports true if the value in the round slot is anywhere in the list. Hexagonal, fits in any diamond slot.
if <[asked v] contains (i) ?> then
say [Repeat!]
end
"Repeat until" — the re-roll loop
The cleanest way to re-roll is repeat until < >. It loops until the diamond becomes true. We want to keep rolling until the index is not in asked — so we put < not < > > wrapped around the contains:
set [i v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (i) ?>>
set [i v] to (pick random (1) to (length of [questions v]))
end
Then mark it asked
Once you exit the re-roll loop, add the chosen index to asked so future rounds will reject it:
add (i) to [asked v]
ask (item (i) of [questions v]) and wait
Worked Example — randomise the Malaysia trivia 12 min
Open last lesson's project (or rebuild the 10-pair Malaysia bank). We're going to add randomisation in eight steps.
asked watcher (left) grows by one number each round — drag it to a visible corner during testing. The cat (✏️ badge) asks whichever question the freshly chosen index i points to.Step 1 — Make the third list
Variables → Make a List → asked, For all sprites. Three watchers now sit on the Stage. Drag asked to the corner — you'll watch it fill up in real time and that's the best debug tool you have today.
Step 2 — Make the counter variable
Variables → Make a Variable → i, For all sprites. This is the random index we'll keep re-rolling.
Step 3 — Wipe asked on green flag
Under the existing when ⚑ clicked (after the question/answer-list loading), add delete all of [asked v]. Critical — without this, the second game freezes.
Step 4 — The outer round loop
You want to run as many rounds as there are questions. Drop repeat ( ) with length of [questions v] in the slot. For our 10-pair bank, that's 10 rounds.
Step 5 — First roll, then the re-roll loop
Inside the outer repeat, drop set [i v] to ( ) with pick random (1) to (length of [questions v]). Below it: repeat until < >. Into the diamond: < not < > >. Into the not's diamond: <[asked v] contains (i) ?>. Inside the repeat-until body: another set [i v] to ( ) with the same random pick.
Step 6 — Mark it asked
After the re-roll loop, drop add (i) to [asked v]. Watch the asked watcher — it gets one more item per round.
Step 7 — Ask the question
ask ( ) and wait with item (i) of [questions v] in the slot. The cat asks whatever question lives at the freshly chosen index.
Step 8 — Check the reply (carry over from L04-37)
Same if < > then ... else as last lesson, but using item (i) of [answers v] — the matching answer at index i. say [Correct!] or say [Nope!] for one second each.
The full assembled stack (after the list-loading blocks from L04-37)
delete all of [asked v]
repeat (length of [questions v])
set [i v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (i) ?>>
set [i v] to (pick random (1) to (length of [questions v]))
end
add (i) to [asked v]
ask (item (i) of [questions v]) and wait
if <(answer) = (item (i) of [answers v])> then
say [Correct!] for (1) seconds
else
say [Nope!] for (1) seconds
end
end
What you just built: a proper randomised quiz. The same trick — track-used-items-in-a-helper-list and re-roll on collision — works for random card draws, dungeon room layouts, music playlist shuffle, and lottery draws. Anywhere you need "random but no repeats", this pattern shows up.
Try It Yourself — three shuffle drills 15 min
Goal: Print the random order to the Stage before asking anything. Instead of asking, just say (i) for (0.5) seconds inside the round loop. Run it three times and watch the order change.
delete all of [asked v]
repeat (length of [questions v])
set [i v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (i) ?>>
set [i v] to (pick random (1) to (length of [questions v]))
end
add (i) to [asked v]
say (i) for (0.5) seconds
end
Think: This is a debug version. Confirming "yes, every number 1..10 appears, in a different order each game" before plugging in real questions is faster than debugging from inside the quiz logic.
Goal: Show the player which round they're on. Add a round variable that starts at 1, gets shown on the Stage with the watcher, and increments at the end of every round.
set [round v] to (1)
delete all of [asked v]
repeat (length of [questions v])
set [i v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (i) ?>>
set [i v] to (pick random (1) to (length of [questions v]))
end
add (i) to [asked v]
ask (join [Round ] (join (round) (join [/] (length of [questions v])))) and wait
change [round v] by (1)
end
Think: Nested joins build the string "Round 3/10". UX detail — players love a progress hint. Quiz apps that don't show one feel endless.
Goal: Limit the quiz to 5 random questions from a 10-question bank. Same pattern, but the outer repeat runs 5 times instead of length of [questions v]. The re-roll logic guarantees no repeats among those 5.
delete all of [asked v]
repeat (5)
set [i v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (i) ?>>
set [i v] to (pick random (1) to (length of [questions v]))
end
add (i) to [asked v]
ask (item (i) of [questions v]) and wait
end
Think: This is how Kahoot and Quizizz work — pick a few from a big bank. Different players get different questions, but no single player sees the same question twice.
Mini-Challenge — the frozen quiz 5 min
"Daniel's hanging Scratch"
Daniel finishes his shuffling quiz and clicks the flag. The first game runs perfectly — all 10 questions, random order, no repeats. He clicks the flag a second time. Scratch freezes. The cat just stands there. He has to close the project and reopen it.
Here's the suspect part of his code:
when flag clicked
delete all of [questions v]
delete all of [answers v]
add [Capital?] to [questions v]
add [Kuala Lumpur] to [answers v]
repeat (length of [questions v])
set [i v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (i) ?>>
set [i v] to (pick random (1) to (length of [questions v]))
end
add (i) to [asked v]
ask (item (i) of [questions v]) and wait
end
Predict why the second click freezes Scratch. Hint: which list does Daniel never wipe?
Reveal one valid solution
Daniel wipes questions and answers on green flag, but he never wipes asked. After the first game, asked holds [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] — every index already used. When the second game starts, the re-roll loop rolls a random number 1–10, finds it's already in asked, rolls again, finds it's already in asked... forever. No exit, no question asked, Scratch hangs.
The fix is one block, in the right place — wipe asked on green flag too:
when flag clicked
delete all of [questions v]
delete all of [answers v]
delete all of [asked v]
Whenever you build a re-roll loop, remember: every list that the loop reads must be reset on green flag. The re-roll trick is powerful but it puts complete trust in a clean starting state.
Recap 3 min
You turned a "random with repeats" quiz into a "random with no repeats" quiz using a third helper list. asked records every index that has been used this game. Each round: pick random (1) to (length of [questions v]), then repeat until the new index is not in asked, then add (i) to [asked v] and ask. Wipe asked on green flag or your second game freezes. The pattern scales to card draws, level pools, music shuffle — anywhere you need random-but-no-repeats.
- Shuffle
- Rearranging items in random order with no repeats. Real shuffle algorithms (like Fisher–Yates) reorder the list in place; today's "re-roll on collision" trick is the friendlier Scratch version.
- Re-roll
- The act of rolling a random number again because the first roll was not acceptable. Cheap when the chance of collision is low, slow when most options are already used.
- Helper list
- A list that doesn't store game content — it stores state about the game. asked is a helper list: the player never sees it, but it tells the quiz "don't pick these again".
- repeat until
- The repeat until < > C-block. Loops the body over and over until the diamond becomes true. Different from forever (never exits) and repeat ( ) (fixed count).
- contains
- The <[ v] contains ( ) ?> boolean reporter from the Variables palette. Reports true if any item of the list equals the value in the slot. The block that makes today's re-roll trick possible.
Homework 2 min
Randomise your 10-question Malaysia bank. Take last lesson's project and bolt today's shuffle on top.
- Open your
HW-L4-37-Malaysia-Quiz.sb3(or rebuild a 10-pair bank). - Make two new variables / lists:
i(variable, for all sprites),asked(list, for all sprites). - Add delete all of [asked v] right after your existing list wipes.
- Replace the existing "ask question 1" code with the round loop from today: repeat (length of [questions v]), first roll, re-roll loop, add (i) to [asked v], then ask (item (i) of [questions v]) and wait and the if/else check.
- Test: click the flag three times in a row. Each game should ask all 10 questions in a different order, with no repeats. The asked watcher should fill 1..10 in a different sequence every game.
Save as HW-L4-38-Shuffled-Quiz.sb3.
Bring back next class:
- The
.sb3file. - Your answer to: "On the very last round of the game, only one fresh index is left. Roughly how many times does the re-roll loop spin on average before it finds it? Why does that number get bigger as the bank gets bigger?"
Heads up for next class: SCR-L04-39 tackles a problem the shuffle quiz has — when the player closes the project, the high score vanishes. We'll meet the two ways Scratch can remember things across sessions: a within-session variable trick and cloud variables.