Tutorial: Position Tracking

Skill Level: Beginner

Knowing where you are is vital to getting to where you want to be. Both of the previous tutorials (Goal Seeking and Maze Mapping) make use of the bot's location, as would more advanced algorithms. Knowing the bot's orientation too will be relevant for a number of tasks.

The AMazeBot system provides methods to determine a bot's location and orientation, but they are convenience methods rather than essential methods. This means that it's possible to achieve their full functionality by using your own code; those methods are only intended to help you get your bot working quickly and with minimal effort. Thereafter they should be replaced in order to improve efficiency, and this tutorial will get you started.

First, let's review the AMazeBot coordinate system. The maze is a square grid that is 44 cells on each side. The top-left cell has coordinates (0, 0) and the coordinates increase toward the right and toward the bottom. Thus the bottom-right cell has coordinates (43, 43). Directions are specified not in terms of up & down, left & right; rather we use the standard compass directions.

Now, consider that we can obtain the bot's starting position and direction for free. Suppose we were to do this before entering the bot's main loop, and store the information in a pair of varibales. If we were to update these variables appropriately whenever the bot moves or turns, then we would always have the current position and direction, and never need to waste energy asking the system for this information. This is the basis of position trakcing.

Let's simplify things by starting with the empty maze as described in the Goal Seeking tutorial. This is how to obtain the starting information:

Point pos = bot.getStartPosition();
Compass dir = bot.getStartDirection();

On the empty maze we'd find that initially the position is (0, 0) and the direction is EAST. If the bot were to move forward, which cell would it end up in? We can see that since the bot is facing EAST, a forward move is going to increase the bot's x-coordinate and not change the y-coordinate. Likewise it's clear that a move in each direction would change only one coordinate at a time, either adding or subtracting 1. We can easily update the position variable depending on which direction we have moved, but we must be sure to update the variable only if the move was successful! If the bot hit a wall, its position isn't going to change at all.

if (bot.move(MOVE.FORWARD))
{
    if (dir == Compass.EAST) pos.x++;
    else if (dir == Compass.SOUTH) pos.y++;

    // Notice that the other 2 directions aren't handled here...
    // You would have to add code for that yourself!
}

This works, but it looks a bit messy. We've only shown you how to handle 2 of the direction but you'd need another 2 lines of code to handle the rest. Is there any way we can reduce the number of lines of code needed? We could of course stick this code into a method, but there is another way. The sample bot included in the devkit demonstrates the use of a method from the PointHelper class:

pos = addPoints(pos, dir.getVector());

This single line of code accomplishes exactly what 4 lines of "messy" code would. The addPoints method simply adds the 2 given points together and gives you the result (note that it does not modify its parameters). For example, adding the points (4, 7) and (2, -4) yields (6, 3). The trick is that the Compass class provides an easy way to convert a direction into a vector (which is still stored in a Java Point) representing the change in position that would occur if a bot were to move foward in the given direction. The vector corresponding to EAST is (1, 0) and you can see that adding this to the original position does exactly what the first if statement above does.

This simplifies our code nicely, and you may find that adding points comes in handy in other parts of your algorithm. You can also subtract points with the subPoints method.

Now we have our position variable being updated correctly if the bot has moved. But what if it hasn't? It's fine that we don't update the position variable, but shouldn't we do something? Borrowing an idea from the Goal Seeking tutorial, we'll just turn the bot left. Now we must remember to update our direction variable, so that the next time the bot does move forward, the correct vector will be added to the position. We won't provide the code to do that here, but you should be able to find what you need in the sample bot. Good luck!