A program in a game
info(), your own log, and the loop every game program is built from.
Do this lesson in the simulatorPrint it: worksheet (PDF) · answers (PDF) · as a web page
You have written programs that drive a mat on their own. A game is the same Python with three differences: other robots are on the mat, the game tells you things while it runs, and nobody stops you at the end of a task.
What changes
- The game talks to you through
info(), a dictionary of whatever this game knows: the score, the clock, where the next thing is. Every game page lists what it puts in there. print()goes to your own log, which you can read after the race. Nobody else sees it, so print as much as you like.- There is no task to pass. There is a result, and it is worked out from what your robot did.
- The program keeps running until the game ends. Most game programs are one big loop.
# info() only exists in a game: in a task there is no game telling you anything
from bugbot import *
connect()
print("this is a task, not a game")
The shape of a game program
Almost every one looks like this:
from bugbot import *
connect()
while True:
# 1. look: sensors, and what the game says
gap = distance()
# 2. decide
if gap < 20:
# 3. move
turn_right(40, angle=45)
else:
forward(60)
# 4. let a moment pass, so the robot keeps hearing from you
wait(0.1)
Look, decide, move, wait. You met it in Module 5 as the behaviour loop. A game is that loop with other robots in the way.
Try one
This is Sprint and Stop: drive up your lane and stand still inside the yellow stop box. The box is somewhere different every race, and the fastest robot to stop in it wins. Drive past its far edge, or touch a lane line, and you are out. Press Race and watch your robot against the built-in bots.
from bugbot import *
connect()
# in a game, position() is the place on the mat, and info() says where this race's stop box is
box = info()['box']
middle = (box['y0'] + box['y1']) / 2
lane_x = info()['lane_x']
while True:
x, y = position()
gap = middle - y
# this game's robots leak sideways: steer back to the middle of the lane
steer = (lane_x - x) * 6
if gap > 25:
drive(90, steer, 0)
elif gap > 3:
drive(30, steer, 0)
else:
stop()
break
wait(0.1)
stop()
print("braked", round(gap, 1), "cm short of the middle of the box")
info()['box'] is that game telling you where the box is, from y0 to y1 on the mat, and info()['lane_x'] is the middle of your lane. In a game position() counts from the mat's corner, not from where you started, so the two agree. Change 25 and 30 and race again: the winner is the one who brakes latest and still stops in the box. Without the steering line this robot drifts into the lane line in most races.
Task: stop on the line
Same idea, on your own: drive 55 cm up the mat and stop within 5 cm of that point, without crossing into the red strip five centimetres beyond it. Remember position() counts from where the robot started.
from bugbot import *
connect()
# position() counts from the start, so the line is 55 cm up from here
forward(70)
wait(1)
stop()
print("stopped at", position())
Challenges
- Print the gap every time round the loop, race, then read your log to see where the braking started.
- Make the light amber while creeping and green once stopped.
- What is the fastest first speed that still stops in time?