Students turn the reaction game into a two-player race over radio, using a shared message code, a function to remove copied blocks, a true/false variable and a score.
Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.
Predict, Run, Investigate 12 min · Milestone 1 10 min · Milestone 2 15 min · Milestone 3 15 min · Fair play 5 min
Both micro:bits run the same program. The players agree a code: 0 = get ready, 1 = go, 2 = I pressed first (and 3 = I won the match, in Milestone 3). Whoever presses B sends 0, waits, sends 1 and shows its own heart; the other shows its heart when 1 arrives. racing is true only while a round is on, so only the first press counts, and a late press after receiving 2 does nothing. Milestone 1 is a refactor: the starter shows the heart and sets racing in two places (a design fault: copies must be kept the same by hand), and students fold them into one function. In the simulator, two micro:bits appear; one student can play both sides to test.
Keeping two micro:bits in step with a code of messages. Ask them to trace one round on paper: who sends what, and who checks it.
| What you will see | A question to ask | The fix |
|---|---|---|
| The heart only shows on one micro:bit. | Is message 1 sent, and does the receiver check for 1? | Send 1 before calling go, and in on radio received call go when receivedNumber = 1. |
| Both players see a happy face. | Do you check racing before counting a press? | In A, only act if racing; set racing to false straight away. |
| The check for Milestone 1 does not tick. | How many call go blocks are there? | Call go in both places: after sending 1, and when 1 arrives. |
One possible solution for each task. Other correct programs are fine.

let racing = false
radio.setGroup(7)
function go () {
basic.showIcon(IconNames.Heart)
racing = true
}
input.onButtonPressed(Button.B, function () {
radio.sendNumber(0)
racing = false
basic.clearScreen()
basic.pause(randint(1000, 4000))
radio.sendNumber(1)
go()
})
radio.onReceivedNumber(function (receivedNumber) {
if (receivedNumber == 0) {
racing = false
basic.clearScreen()
} else if (receivedNumber == 1) {
go()
}
})

let racing = false
radio.setGroup(7)
function go () {
basic.showIcon(IconNames.Heart)
racing = true
}
input.onButtonPressed(Button.B, function () {
radio.sendNumber(0)
racing = false
basic.clearScreen()
basic.pause(randint(1000, 4000))
radio.sendNumber(1)
go()
})
input.onButtonPressed(Button.A, function () {
if (racing) {
racing = false
radio.sendNumber(2)
basic.showIcon(IconNames.Happy)
}
})
radio.onReceivedNumber(function (receivedNumber) {
if (receivedNumber == 0) {
racing = false
basic.clearScreen()
} else if (receivedNumber == 1) {
go()
} else if (receivedNumber == 2) {
if (racing) {
racing = false
basic.showIcon(IconNames.Sad)
}
}
})

let wins = 0
let racing = false
radio.setGroup(7)
function go () {
basic.showIcon(IconNames.Heart)
racing = true
}
input.onButtonPressed(Button.B, function () {
radio.sendNumber(0)
racing = false
basic.clearScreen()
basic.pause(randint(1000, 4000))
radio.sendNumber(1)
go()
})
input.onButtonPressed(Button.A, function () {
if (racing) {
racing = false
radio.sendNumber(2)
wins += 1
if (wins == 3) {
radio.sendNumber(3)
basic.showIcon(IconNames.Yes)
} else {
basic.showIcon(IconNames.Happy)
}
}
})
input.onButtonPressed(Button.AB, function () {
basic.showNumber(wins)
})
radio.onReceivedNumber(function (receivedNumber) {
if (receivedNumber == 0) {
racing = false
basic.clearScreen()
} else if (receivedNumber == 1) {
go()
} else if (receivedNumber == 2) {
if (racing) {
racing = false
basic.showIcon(IconNames.Sad)
}
} else if (receivedNumber == 3) {
basic.showIcon(IconNames.Skull)
}
})
Stretch: Add an early-press penalty: pressing A before the heart sends 4, and the other player wins the round.
Support: Run Milestone 3 in pairs: one student builds the winner side (counting and sending 3), the other the loser side (receiving 3).
In a duel, the first micro:bit radios 1 just before it shows a heart, and the second shows a heart when 1 arrives. Why do the two hearts appear at almost the same time?
The first sends message 1 just before showing its heart, and the second shows its heart as soon as 1 arrives.
Two optional lessons go further: Fake-outs and levels (one player, harder rules) and Tournament (a scoreboard list and a round function). Class ideas: a class knockout tournament; a quiz buzzer for real class quizzes.