60 minutes · Ages 9–16 · Model: EV3 Wooden Man Game
What you are building 3 min
The Wooden Man: a doll on a Large Motor that turns to face the players and turns away again, with a flag on a Medium Motor and a button the player presses.
It is the machine from “Red Light, Green Light” — the doll faces away and you may move; it turns round and you must be still. The game is nothing but a sequence of moments, and a machine that runs it needs to remember them all.
By the end of the lesson your game will record every reaction time of the round and report how many there were — from a single variable that can hold more than one thing.
In the real world 5 min
Where you have seen it
Almost every version of this game in the world is the same shape. In Korea it is mugunghwa kkoci pieot seumnida; in Japan daruma-san ga koronda; in Britain “Grandmother’s Footsteps”; in Spain un, dos, tres, pollito inglés. One player looks away and chants, then turns; everyone else advances only while they are not being watched.
Hopscotch in California. Photo: Dave Parker / Wikimedia Commons (CC BY 2.0).
The chant is the timer, and it is deliberately variable. A caller who always counted to exactly three would be beaten every time — the whole tension comes from not knowing how long you have.
Why it is built that way
Any system that judges people over a sequence of events has to keep the sequence, not just the last event. A race keeps every lap time, not the most recent one. An athlete’s coach wants the spread across ten sprints, because one sprint tells you almost nothing.
The moment you want an average, a best, a worst, or “how many times did that happen”, one box is no longer enough. You need the whole run.
What would go wrong without it
A stopwatch that only ever showed the current time and forgot each split would be useless for training. You would know how fast the last lap was and nothing about whether you were improving — which is the only question worth asking.
One number tells you what happened. A run of numbers tells you what is happening.
The main concept — a variable that holds many things 6 min
A list is a variable with room for many values, kept in order, that can grow while the program runs. Where a variable is a box, a list is a shelf.
set [best v] to (2.4) :: variables
set [best v] to (1.9) :: variables
A variable holds one thing. The 2.4 is gone — not hidden, gone. Nothing in the program can ever get it back.
add (2.4) to [times v] :: list
add (1.9) to [times v] :: list
A list keeps both, in the order they arrived. times now has a length of 2.
The four blocks you need today
Block
What it does
Watch out for
add (x) to [list]
Puts a value on the end.
Grows for ever if it is inside a forever loop.
delete all of [list]
Empties it.
Do this at the start of every round. A list is not cleared when the program restarts.
length of [list]
How many values are in it.
This is a number — you can compare it, display it, do sums with it.
item (n) of [list]
The value in position n.
Counting starts at 1, not 0. Next lesson leans on this.
The commonest bug in this lesson is a list that never empties. Values survive between runs of the program, so a game played three times reports fifteen reaction times instead of five. Put delete all at the top, always.
Length is the instrument
The most useful thing a list gives you is not the values — it is length of. It answers “how many times did that happen?” without a counter variable, without a separate change by 1, and without the two ever disagreeing.
A count that is derived cannot drift. If you keep a separate score variable alongside the list, one day you will add to the list and forget to increment the score, and then no line of the program is wrong but the answer is.
ComponentData6 min
Lists
A variable holds one number. A list holds many, in order, under one name — so a robot can remember every reading it took rather than only the most recent.
A corridor of lockers
If a variable is a piece of paper with one number on it, a list is a row of lockers. Each locker has a number on the door, and each one holds something of its own. They all share a name — snacks, colours — and you tell them apart by the number, not the name.
The doors matter. You cannot see what is in the whole row at a glance: to find out what is in locker 3, you have to open locker 3. And if you want to change what is in there, you open it, take out what is inside, and put something else in. Try it — click a door.
length of snacks = 3
add candy to snacks
Three lockers are in use. You cannot see inside any of them until you open one — click a door.
Every list block is one of those physical actions, and the block for whatever you just did appears underneath the lockers:
Block
The locker version
add [banana] to [snacks v]
Put a banana in the next free locker. Always the end of the row.
(item (3) of [snacks v])
Open locker 3 and tell me what is inside. One locker, one look.
replace item (3) of [snacks v] with [candy]
Open 3, take out what is there, put candy in. Nothing else moves.
delete (3) of [snacks v]
Empty locker 3 and close up the gap — everything after it shuffles down one. What was in 4 is now in 3.
(length of [snacks v])
How many lockers are in use.
delete all of [snacks v]
Empty the whole row. This belongs at the top of a program.
Deleting is the one that catches people. A locker does not stay empty — the row closes up. Delete item 2 of a five-item list and you have a four-item list, with everything after position 2 now one number lower than it was. Any position you wrote down before the delete is wrong afterwards.
What a robot puts in them
Lists are not only for numbers. Anything a block can report can go in one:
Colours from the Colour Sensor. Drive along a line of coloured cards adding each reading, and at the end the robot has the whole sequence — not just the last card it went over.
Positions in degrees. A list of angles is a list of places an arm should go: 0, 90, 180, 270. Walking the list drives the arm through the positions in order, and changing where it stops means editing a number rather than rewriting the program.
Words.apple, banana, candy — a vending machine holds its stock in one list and the matching prices or positions in another, so item 2 of one lines up with item 2 of the other.
Blocks reference
Block
What it does
add [thing] to [List v]
Puts a new value on the end.
(item (1) of [List v])
Reads the value at a position. Positions start at 1.
(length of [List v])
Reports how many values are stored.
delete all of [List v]
Empties it. This belongs at the top of the program, for the same reason a variable is set to zero there.
Collecting readings
The natural shape is a loop that takes a reading and adds it. Watch the same four readings go into a variable and into a list.
into a variable
repeat 4
set reading to 4 distance in cm
into a list
delete all of Readings
repeat 4
add 4 distance in cm to Readings
write item (3) of Readings at line 1
0values in the variable0values in the list
The robot will stop four times and read the distance. One program keeps the reading in a variable; the other adds it to a list.Reading 1: 38 cm. Both programs hold 38.Reading 2: 12 cm. The variable has just thrown 38 away. The list has both.Reading 3: 47 cm — the biggest of the run.Reading 4: 25 cm. The variable holds one number; the list holds four, in the order they were taken.Now go back and ask for any of them — item 3 of the list is still 47, the largest of the run. The variable cannot answer: 47 stopped existing two stops ago.Finished. The variable was never wrong — it was only ever holding one thing.
0 of 4 readings taken
Watch the variable box, not the list. Every reading it shows is correct; it is the ones it has already forgotten that matter.
Notice that the variable is never wrong. Every number it shows is a real reading, correctly taken, moments ago. It simply has room for one, so each new reading pushes the last one out — and by the fourth stop three readings have quietly ceased to exist.
Afterwards the list can be walked to find the largest, the smallest, or the average — none of which is possible if you only ever kept the latest value.
Positions count from 1, not 0. A loop that starts its counter at 0 reads a position that does not exist and misses the first entry.
Reading the whole list out
Storing readings is only half of it. To use a list you walk it, and that needs one more idea: a variable that holds a position rather than a value. Call it i. Set it to 1, read item i, then change i by 1 — and the next pass round the loop looks at the next locker.
Two things make this work without anybody counting. The loop repeats length of colours, so it runs once per item however many there are; and i doubles as the screen line, so each item lands on its own row.
when program starts :: events hat
delete all of [colours v]
add [red] to [colours v]
add [blue] to [colours v]
add [green] to [colours v]
add [yellow] to [colours v]
clear display :: display
set [i v] to (1)
repeat (length of [colours v])
write (item (i) of [colours v]) at line (i) :: display
change [i v] by (1)
end
1i · the positionreditem i of colours4length of colours
The list holds four colours. i is set to 1 — it is not a colour, it is a position.Pass 1. item 1 of colours is red, so red goes on line 1. Then i changes to 2.Pass 2. item 2 is blue, onto line 2, and i becomes 3.Pass 3. item 3 is green, onto line 3, and i becomes 4.Pass 4 writes yellow. The loop was told to repeat length of colours — four — so it stops there without anybody counting.Four items, four passes, four lines. Add a fifth colour to the list and the same program writes five, unchanged.Finished. The program never mentions the number four — it asks the list how long it is.
i = 1
Watch i rather than the blocks. It is the only thing that changes between one pass and the next, and it is what makes each pass look at a different locker.
Nowhere does that program mention the number four. Add a fifth colour and it writes five lines, unchanged — which is the whole reason to ask a list its length rather than typing a number you will have to remember to update.
Going further: sorting, and finding the biggest
Once a robot can walk a list it can do real work on one. Both of these are the same trick — go along comparing two items at a time — and they differ only in what they do about it. Sorting swaps the pair; finding the biggest just remembers the winner.
when program starts :: events hat
set [i v] to (1)
repeat ((length of [nums v]) - (1))
set [j v] to (1)
repeat ((length of [nums v]) - (i))
if <(item (j) of [nums v]) > (item ((j) + (1)) of [nums v])> then
set [temp v] to (item (j) of [nums v])
replace item (j) of [nums v] with (item ((j) + (1)) of [nums v])
replace item ((j) + (1)) of [nums v] with (temp)
end
change [j v] by (1)
end
change [i v] by (1)
end
5 was bigger than 2, so they swap. The bigger number moves one place to the right.5 is already smaller than 9 — nothing to do. Move along one.9 was bigger than 1, so they swap. The bigger number moves one place to the right.9 was bigger than 7, so they swap. The bigger number moves one place to the right.2 is already smaller than 5 — nothing to do. Move along one.5 was bigger than 1, so they swap. The bigger number moves one place to the right.5 is already smaller than 7 — nothing to do. Move along one.2 was bigger than 1, so they swap. The bigger number moves one place to the right.2 is already smaller than 5 — nothing to do. Move along one.1 is already smaller than 2 — nothing to do. Move along one.Sorted. Every pass floated the biggest remaining number to the end, which is why it is called a bubble sort.Finished. Same blocks, any list — it does not care how long it is or what order it started in.
swap
Only ever two numbers are being compared at a time. A sort looks complicated because it repeats, not because any one step is hard.
A bubble sort looks hard because it is a loop inside a loop, but no single step is: compare two neighbours, swap them if they are the wrong way round, move along one. Each full pass floats the biggest remaining number to the end — which is where the name comes from — so after as many passes as there are items, the list is in order.
Finding the biggest needs no swapping at all. Assume the first item is the winner, walk the rest, and whenever you meet something bigger, remember that instead. One pass, one variable. Swap the > for a < and the same program finds the smallest — which is how a line-following robot works out its black and its white before choosing a threshold between them.
Why it matters
This is data collection — a robot driving a course while recording distances, then reporting what it found. It is the difference between a machine that reacts and one that measures.
ComponentData6 min
Variables
Why anybody needs one
Long before there were computers, people had exactly this problem. A shepherd counting sheep through a gate, a trader counting sacks of grain, a builder counting days — none of them can hold the number in their head while they get on with the work. So they scratched a mark on a wall, cut a notch in a stick, or wrote a number on a piece of paper. The number lived outside the person, in a place they had agreed on, and they could go back to it, read it, and change it.
Better still, once the number is written down somebody else can use it. Watch these two: one of them counts and writes, the other never sees a single animal and simply reads the wall.
Abby never remembers the numberBen never sees a henThe wall holds it for both
Abby has a gate and a wall. Before a single hen comes through she chalks 0 on the wall — that is where the number is going to live.A hen goes through. Abby rubs out the 0 and chalks 1. Another goes through, and she does it again.Three hens have been through, and the wall says 3. Abby is not remembering the number — she is reading her own wall each time and writing the next one.Ben has been at the market all morning. He has not seen one hen. He walks up, reads the wall, and knows the answer — without asking Abby anything.That is a variable. Not a number in somebody's head, but a place both of them agreed on: one writes to it, the other reads from it, and it keeps the number in between.Finished. Abby wrote, Ben read, and the wall is what joined them up.
the wall holds it
Notice what never happens: Ben never asks Abby. He does not need to — the number is not in her head, it is on the wall, and the wall is there for anyone who needs it.
Neither Abby nor Ben is holding the number — the wall is. And notice what never happens: Ben does not ask Abby. He does not need to, because the count is not in her head. It is in a place they both agreed on, which is what makes it useful to more than one of them.
That is all a variable is. The robot cannot hold a number in its head either, so you give it a wall of its own, write a name at the top so everyone knows which wall is which — score, count, degree_turn — and the program can read what is on it and write something new. One part of the program writes; another part reads. Exactly Abby and Ben.
The paper, and the two things you can do to it
Say we are counting rotations of a motor. Before we start we write 0 on the paper. Every time the motor completes a turn we cross out what is there and write one more: 0 becomes 1, then 2, then 3. That is change — it has to read the old number to work out the new one.
set is the other thing you can do, and it is completely different: rub the whole paper out and write the number you want. It does not care what was there. Press the buttons and watch what happens to the crossings-out.
score
0
The paper starts blank, so we write 0 on it. That is what a variable is: a place to keep a number while the robot works.
change leaves a trail — every value follows from the one before it. This is what counting is.
set wipes the sheet. Use it to start a count, never to continue one.
Press set score to 0 after counting up a few times and watch the whole history vanish. That is what happens to a count when a set block ends up in the wrong place — and it is the commonest variable bug there is.
Blocks reference
Block
What it does
set [count v] to (0)
Puts a value in, replacing whatever was there.
change [count v] by (1)
Adds to what is already there.
(count)
Reports the current value, for use in a comparison or on the display.
Set, or change?
set replaces; change adds. Counting things needs change. Starting a count needs set. Both programs below have both blocks — the only difference is whether the set block is inside the loop or above it.
set before the loop
when program starts
set count to 0
repeat 4
A run clockwise for 1rotations
change count by 1
set inside it
repeat 4
set count to 0
A run clockwise for 1rotations
change count by 1
Before the loop: counted 0Inside the loop: stuck at 0
Both programs count the turns of a motor. The left sets the count to zero before the loop; the right sets it inside.Turn 1. Both counters read 1, and so far the two programs agree.Turn 2. The left count is 2. The right was set back to zero at the top of the loop, so it is 1 again.Turn 3. The left reads 3. The right still reads 1.Turn 4. The motor turned four times on both robots — only one of them counted them.Finished. Four turns, and one of the two counts is fiction.
stopped
Both programs contain both blocks. Only the position of set [count] to 0 is different.
The count on the right is not broken; it is being told to start again on every pass. Each time round the loop it is wiped back to zero and then changed by one, so the honest answer is always 1 — while the motor cheerfully turns four times. A counter stuck at 1 almost always means a set block that has slipped inside the loop.
Anything oval is a number you can pick up
EV3 Classroom tells you what a block does by its shape, and once you have noticed that, a whole set of questions answers itself:
Oval — reports a number. The blue degrees counted, the timer, a distance, your own variable.
Pointed — reports true or false. These go in an if or a wait until, not in a variable.
Block-shaped — does something. These stack up; they do not fit inside anything.
So when a slot is oval, any oval fits it — and it does not matter in the least where that number came from. You can take the motor’s own A degrees counted and keep it in a variable you named degree_turn, then compare that with a number later. Pick an oval below and watch the same one drop into all three kinds of slot.
pick an oval
the same oval fits all three
set degree_turn to A degrees countedkeep it in a variable of your own
A degrees counted+10do arithmetic with it
A degrees counted>50compare it with a number
Every one of those slots is oval-shaped, and A degrees counted is an oval — so it drops in. Nothing about where the number came from matters.
This is what makes a variable more than a counter. A sensor reading is true only at the instant you read it; copying it into a variable freezes it, so the robot can compare where it is now against where it was when something happened:
when program starts :: events hat
[A v] reset degrees counted :: motors
set [degree_turn v] to ([A v] degrees counted :: sensors)
start moving [right: 30] :: movement
wait until <(([A v] degrees counted :: sensors) - (degree_turn)) > (400)>
stop moving :: movement
Read the condition aloud: how far the motor has gone now, minus where it was when we started, is more than 400. Both are ovals, so both can go into a subtraction, and the subtraction is an oval too — which is why it can go into a comparison. Ovals nest inside ovals as deep as you need.
Reset at the start, every time
A variable keeps its value after the program ends. Run the program again without setting it back and the second run begins where the first left off — the count starts at 14, the robot thinks it has already done the job. Every variable a program changes must be set to its starting value at the top.
Why it matters
A variable is the difference between a machine that repeats a fixed routine and one that responds to how things have gone — counting parts, tracking a score, remembering where it started.
ComponentControl4 min
The Timer
A wait pauses for a length of time. The timer is different: it runs in the background and can be read at any moment, so the robot can know how long something has taken while it is still happening.
Blocks reference
Block
What it does
(timer)
Reports the seconds since the timer was last reset.
reset timer
Sets it back to zero, so the next reading counts from here.
The timeout — a safety net
The most valuable use of a timer is escaping a wait that might never end. A robot told to drive until it sees a wall will drive for ever if the wall is not there. Combined with a timer, it can give up:
Repeat until the wall is close or five seconds have passed. That one change turns a program that can hang into one that always finishes. Both robots below are looking for a wall that is not there.
no way out
repeat until distance < 15
start moving straight: 0
with a timeout
reset timer
repeat until distance < 15 or timer> 5
start moving straight: 0
write GAVE UP at line 1
1.2stimer212cm · distance
Both robots are told to drive until something is within 15 cm. The room ahead is empty.Three seconds. No wall. Both are still driving — and the right-hand program is also watching its timer.The timer passes 5. The right-hand robot gives up, stops, and says so.The left robot is still going. Its condition can never become true, so that block will hold the program for ever.The right-hand program finished. The left one has not, and there is nothing to say why.
timer 1.2 s
The sensor is not faulty and the program is not wrong. There is simply no wall, and only one of these two programs has a way of noticing that.
The left-hand robot is not broken, and neither is its sensor. Its condition is simply one that will never come true, so the program sits on that block for ever — with nothing on the Brick to say so. The right-hand program asks the same question with an escape route bolted on, and finishes every time.
Why it matters
Real systems time themselves out constantly — a lift that cannot close its doors eventually gives up and beeps rather than trying for ever. A robot with no timeout simply stops responding, and there is nothing on screen to say why.
If you ever want the best, the average, or how many — you wanted a list all along.
▶The timerFrom Level 2, Lesson 40 — reading elapsed seconds, and resetting it before you measure.Show meHide
ComponentControl4 min
The Timer
A wait pauses for a length of time. The timer is different: it runs in the background and can be read at any moment, so the robot can know how long something has taken while it is still happening.
Blocks reference
Block
What it does
(timer)
Reports the seconds since the timer was last reset.
reset timer
Sets it back to zero, so the next reading counts from here.
The timeout — a safety net
The most valuable use of a timer is escaping a wait that might never end. A robot told to drive until it sees a wall will drive for ever if the wall is not there. Combined with a timer, it can give up:
Repeat until the wall is close or five seconds have passed. That one change turns a program that can hang into one that always finishes. Both robots below are looking for a wall that is not there.
no way out
repeat until distance < 15
start moving straight: 0
with a timeout
reset timer
repeat until distance < 15 or timer> 5
start moving straight: 0
write GAVE UP at line 1
1.2stimer212cm · distance
Both robots are told to drive until something is within 15 cm. The room ahead is empty.Three seconds. No wall. Both are still driving — and the right-hand program is also watching its timer.The timer passes 5. The right-hand robot gives up, stops, and says so.The left robot is still going. Its condition can never become true, so that block will hold the program for ever.The right-hand program finished. The left one has not, and there is nothing to say why.
timer 1.2 s
The sensor is not faulty and the program is not wrong. There is simply no wall, and only one of these two programs has a way of noticing that.
The left-hand robot is not broken, and neither is its sensor. Its condition is simply one that will never come true, so the program sits on that block for ever — with nothing on the Brick to say so. The right-hand program asks the same question with an escape route bolted on, and finishes every time.
Why it matters
Real systems time themselves out constantly — a lift that cannot close its doors eventually gives up and beeps rather than trying for ever. A robot with no timeout simply stops responding, and there is nothing on screen to say why.
Say this back before moving on: “A box holds one. A shelf holds all of them, in order.”
What’s in this build 4 min
Three electronic parts. Turn the doll by hand and check it faces properly both ways — the game is unplayable if “looking” is ambiguous.
Part
What it is doing here
EV3 Intelligent Brick
The referee. Today its screen is a scoreboard, showing the length of the list as the round runs.
Large Motor — the doll
Turns the head or the whole body to face the players. Large because the turn must be decisive: a slow, ambiguous turn ruins the game.
Medium Motor — the flag
Raises and drops to signal. Redundant with the doll’s turn, and deliberately so — a second signal makes the game readable across a room.
Touch Sensor — the player’s button
What the player hits when the doll turns. The gap between the turn and the press is the reaction time, and each one goes on the list.
The turning mechanism (not electronic)
Should stop crisply. A doll that wobbles after turning makes the moment of “now” fuzzy, and every reaction time inherits that fuzz.
Ports — and the rule 4 min
Sensors go in ports 1, 2, 3, 4. Motors go in ports A, B, C, D. They are not interchangeable, and nothing will tell you politely if you swap them.
Part
Port
Why this one
Doll (Large)
A
The motor the game is built around.
Flag (Medium)
B
The signal motor.
Player button (Touch)
1
Touch stays on 1 across the course.
Check your own build now:
Doll in A, flag in B, button in 1.
Put the button where a player can actually reach it fast. You are measuring reaction times; an awkward button measures reach, not reaction.
Turn the doll to “away” and leave it there. Every round starts from that position.
Press the button a few times and listen for a clean click each time.
Connect the Brick 4 min
Two routes, and either is fine. USB is the reliable one and the one to fall back on when a room’s Bluetooth is busy; Bluetooth leaves the robot free to move, which some models need.
▶How to connect the BrickUSB and Bluetooth, step by step, with a photograph of every screen. Open it if you have not done this before — or if pairing is not working.Show meHide
USB — the reliable one
Switch the Brick on with the dark grey centre button.
Cable into the Brick’s PC port — the small square socket beside the numbered ports, not one of the numbered ones.
Other end into the computer.
Bluetooth — name it first
Do these in order. Naming the Brick after you go looking for it in the list is how groups end up driving each other’s robots.
Name your Brick. On the Brick: Settings (the spanner) → Brick Name. Type something nobody else will pick, then press the tick. Every Brick is called EV3 until somebody changes it.
Turn Bluetooth on. Settings → Bluetooth. Tick Bluetooth and Visibility. Leave iPhone/iPad/iPod unticked.
Connect from EV3 Classroom. Click the Brick icon at the top of the programming area, find your Brick by name, and click Connect.
Say yes on the Brick. It asks “Connect?” with the computer’s name — choose the tick, then accept the passkey, which is already 1234.
Where to read it. The name sits in the bar across the very top of the screen, on every screen — so you can check which Brick you are holding at any moment without going into a menu. This one is EV3VE. A Brick nobody has renamed says EV3.Step 3, and the reason step 1 exists. Three Bricks in range — read the name before you click Connect. Pairing with the wrong one is not an error: it works perfectly, on somebody else’s robot.
Step 2.Bluetooth switches the radio on; Visibility is what lets the computer find you. With Visibility off your Brick works perfectly and simply never appears in the list.Step 4. Look at the Brick. It asks whether to accept and names the computer. Choose the tick.Then the passkey, already 1234. Press the tick again and you are connected.
The two failures, every class, every time. The Brick has gone to sleep while you were building — press the centre button to wake it. Or you have paired with the group at the next table, which is why the name matters.
The long version, including Port View and how to read the port tiles, is in the Brick & Bluetooth guide.
USB is fine. The game sits on a table and everybody comes to it. The one thing to keep clear of the cable is the button — a player lunging for it will find the lead.
Confirm the connection 2 min
Check the Brick icon: connected, or not.
Two motor tiles — A and B.
One sensor tile — 1, reading a Touch Sensor.
Turn the doll by hand from away to facing and read tile A. Note the degrees — that is the turn your program will command, and a half-turn that only goes three-quarters of the way makes the game ambiguous.
Stuck? The long version, with a photograph of every screen, is in the Brick & Bluetooth guide.
Make it move 10 min
Five rounds. Each one: wait an unpredictable time, turn, start the clock, wait for the press, put the time on the list.
when program starts :: events hat
delete all of [times v] :: list
clear display :: display
write [GET READY] at line (1) :: display
wait (2) seconds :: control
repeat (5)
write [LOOK AWAY] at line (1) :: display
wait (pick random (2) to (5)) seconds :: control
[A v] run [clockwise v] for (180) [degrees v] at (80) % speed :: motors
[B v] run [clockwise v] for (90) [degrees v] at (80) % speed :: motors
write [NOW!] at line (1) :: display
reset timer :: control
wait until <[1 v] is pressed? :: sensors>
add (timer) to [times v] :: list
write (length of [times v]) at line (3) :: display
[A v] run [counterclockwise v] for (180) [degrees v] at (80) % speed :: motors
[B v] run [counterclockwise v] for (90) [degrees v] at (80) % speed :: motors
wait until <not <[1 v] is pressed? :: sensors>> :: control
end
write [DONE] at line (1) :: display
write (length of [times v]) at line (5) :: display
play sound [Communication / Goodbye v] until done :: sound
Five reaction times on one list. Line 3 counts up as the round goes; line 5 reports the total at the end.
delete all is the first line for a reason. Take it out and play twice: the second game reports ten times. Lists survive between runs.
pick random 2 to 5 is what makes it a game. A fixed wait is learnable in two rounds.
reset timer goes immediately after the turn. Put it before and you are timing the doll’s motor as well as the player.
The wait-for-release at the end stops a player who is leaning on the button from scoring the next round at zero.
Nothing counts the rounds. There is no score variable — length of is the count, and it cannot disagree with the list because it is the list.
What success looks like: five turns of the doll at unpredictable intervals, a number on line 3 climbing 1…5, and a final total of 5 on line 5.
If line 3 reads 6, 7, 8… on the first game, the list was not emptied — you are seeing the previous round’s values still on the shelf.
Change it and test 8 min
One change at a time. Predict, then run, then look.
Delete the delete all line and play twice. Predict the second game’s final number. Then put the line back.
Play ten rounds instead of five. Change one number and notice that nothing about the recording had to change — a list does not care how long it gets.
Show item (1) of [times] on line 4. That is the first reaction of the round, still there at the end. Now try item (0) and see what happens — lists count from 1.
Add a second list. Record the random wait alongside each reaction time. Two lists, same length, position 3 of each belonging to the same round — that pairing is how a list becomes a table.
Move add to list inside a forever loop. Watch the length run away. A list that grows unwatched will fill the Brick’s memory — this is worth seeing once, briefly.
Empty the list at the start. Derive the count from the list. Never keep a second number that means the same thing.
Where this goes 3 min
You can now record a run of values. What you cannot yet do is look back through them.
Your program knows how many reaction times it collected. It cannot tell you the fastest, the slowest, or the average — because that needs walking the list from item 1 to item length, one at a time, keeping track as you go.
A counting loop plus item (n) of is how a program reads its own memory. That is the next lesson, on a reaction game that finally tells you who won.
Today the machine remembered. Next lesson it works out what the memory means.
Build it 15 min
Build the model before you read any further. Everything after this is about making it do something, and none of it will make much sense with nothing on the table in front of you.
Use the viewer's own controls to zoom and turn pages. Fullscreen makes it big enough to build from.
Check the finished build against the picture before you switch anything on. A motor mounted the wrong way round is far easier to spot now than it is to debug later, when it looks like a program fault.
This is what you are building: the EV3 Wooden Man Game.
Challenges & mission 27 min
Work through the challenges in order — each is harder than the last. The mission comes after all three, and it is meant to make you plan before you build.
Challenge 1
Show the first and last.
Add two lines to the end: item 1 of your list, and the last item — which is item (length of times) of the list.
Play a round and check the numbers against what you saw on line 3 as you played. Getting the last item is the first time you have used length as a position rather than a count.
Challenge 2
Record two things per round.
Add a second list holding the random wait for each round, so times item 3 and waits item 3 belong to the same round.
Show both lists side by side at the end. Two lists of the same length, read at the same position, is how a program stores a table.
Challenge 3
Make it fair.
At the moment a player who is leaning on the button scores an impossibly fast time. Reject any reaction faster than 0.1 seconds — that is quicker than a human nerve, so it is a false start.
The round must be replayed rather than recorded, which means the list should still end up with exactly five honest times. Check the length at the end to prove it.
Mission
Turn the wooden man into a tournament machine.
Three players take turns, five rounds each, and the machine keeps everyone's times separately. At the end it announces who won.
Plan the data first, on paper: how many lists, what goes in each, and how you will know which player a value belongs to. There is more than one sensible answer, and choosing between them IS the mission.
Three rules:
1. Every list is emptied at the start of the tournament, and only there.
2. No separate counter variables. If you want to know how many rounds a player has played, ask their list how long it is.
3. The machine must be able to run a second tournament straight after the first without being restarted — which is the real test of rule 1.
You do not yet know how to find the fastest of a list. You may work it out, or you may wait until the next lesson and come back — both are honest answers, and noticing that you are missing a tool is worth as much as having it.