A program in a game

info(), your own log, and the loop every game program is built from.

10.1CompetingRobot club14 min

Do this lesson in the simulator

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")

Run this in the simulator

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.

A game program as a loop: look, decide, move, wait, and round again, with the game telling the program things through info()1. looksensors and info()2. decideif this, do that3. movedrive, or stop4. waita tenth of a secondthe gamescore, clock, where things areinfo()round and rounduntil the game ends
Every game program is this loop. The only new part is the game itself, which the program can ask about at the look step through info(). The wait at the end keeps each trip round short, so the robot can react many times a second.

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.

One race of Sprint and Stop seen from above, with the lane running left to right, the stop box, and the robot's path, marked where the program drives fast, slows down and stopsthe stop box, this racepast it: outlane_x, the middle of the lanestartgap over 25: speed 90slow: 30under 3: stopmiddle
One race, seen from above: the lane runs left to right, the thick line is the robot's path, and the stop box was 97.4 to 107.4 cm up the mat this time. The program drives at 90 until the gap to the middle of the box is 25 cm, creeps at 30, and stops once it is within 3 cm. It came to rest in the box, place 2 of 5.

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

  1. Print the gap every time round the loop, race, then read your log to see where the braking started.
  2. Make the light amber while creeping and green once stopped.
  3. What is the fastest first speed that still stops in time?