Racing the bots

Practice, replay and the results board: why you lost, and the fast-then-careful pattern that wins.

10.2CompetingRobot club14 min

Do this lesson in the simulator

Every game comes with built-in bots. They are not there to be beaten once; they are a measuring stick you can run again and again.

Practice is free

Open any game and press Race. Your program runs against the bots on your own screen, as often as you like, with nobody watching. That is where a program gets good.

from bugbot import *
connect()
import math

# park in the first bay: info() says where it is. Fast while it is far, then creep
bay = info()['bay']
while True:
    x, y = position()
    dx, dy = bay['cx'] - x, bay['cy'] - y
    gap = math.hypot(dx, dy)
    if gap < 2:
        break
    speed = 70 if gap > 20 else 30
    # slide straight at it without turning: forward for y, sideways for x
    drive(speed * dy / gap, speed * dx / gap, 0)
    wait(0.1)
stop()
print("parked, gap", round(gap, 1))

This parks in the first bay only, for close to 90 points (88 to 91 over six races), and then stands still while the bots go on to all three. info()['bay'] always holds the next bay, so a loop round this that reads it again would do the rest.

One race of Precision Park from above: the three bays, the lesson's program parking in the first and stopping there, and Careful Carl parking in all threebay 1bay 2bay 3startyours, at 70at 30, the last20 cmCareful Carlpointsyours: 90.4Careful Carl: 281.4
One race. The program parks in bay 1, the last 20 cm slowly, then stands still for the rest of the race. Careful Carl goes on to bays 2 and 3, and scores 281.4 to its 90.4. The replay shows this at once.

Reading why you lost

After a race you get a results board and a replay. Three things to look at, in this order:

  1. Did the robot do what you meant? Watch the replay. Most losses are a program doing exactly what it was told.
  2. Where did the time go? A robot that drives at 30 the whole way loses to one that drives at 90 and creeps at the end.
  3. What did the bots do differently? Their descriptions are on the game page: one may look further ahead, another may take a straighter line.

Print as you go. Your log is yours alone, and a line like print("state", state, "gap", round(gap, 1)) each time round the loop tells you afterwards exactly when the robot changed its mind.

Fast, then careful

The pattern that wins nearly every game with a target is the same: go fast while the target is far away, slow down as you arrive, and stop before you overshoot.

from bugbot import *
connect()

# how speed could follow distance: far away, fast; close, slow
for gap in [80, 60, 40, 20, 10, 5]:
    speed = max(20, min(90, gap * 1.2))
    print("gap", gap, "-> speed", round(speed))

Run this in the simulator

That is proportional control from Module 3, used as a tactic.

Speed against the gap left: two fixed speeds that switch at 20 cm, and speed that follows the gap020406080020406080100gap left, cmspeedtwo fixed speeds, 70 and 30follows the gap, up to 90never under 20
The two ways to set speed on this page. The dashed line jumps from 70 to 30 at 20 cm. The green line slows down smoothly as the gap closes, from 90 far away to 20 at the end, never less, because a very small speed does not move the robot at all.

Task: park square

Drive into the bay and stop inside it, facing the way you started, within 10 degrees. Being in the bay is not enough: finish straight.

from bugbot import *
connect()

forward(60, distance=35)
stop()
print("heading", heading())

Challenges

  1. Run the same program five times. How much do the finishing positions differ?
  2. Add a correction at the end: if the heading is out by more than 5 degrees, turn back.
  3. Try the speed rule above instead of two fixed speeds, and see which parks closer.