This is a bonus program! It's meant to be a bit challenging, but completing this program will definitely help you write your final project.

Write a GraphicsProgram that moves a snake counter-clockwise around the border of the canvas.

BorderBox

This exercise assumes that you have completed BorderBox. A lot of the logic is similar (there's only one additional trick), so it really helps to know the general problem setup. If you haven't completed BorderBox yet, go implement it and come back.

Snake setup

Open BorderSnake.java. You'll find that the main() method is exactly the same as BorderBox. However, some of the class variables are different. Instead of a single GRect, we now have an ArrayList of GRects. We still have one direction for the snake, though.

private ArrayList<GRect> snake;
private int snakeDirection = EAST; // starting direction

Implement makeSnake(). To make your life easier later, add the head of the snake first (so that snake.get(0) returns the GRect for the head). Remember that the snake starts out facing EAST, so the head is the rightmost GRect. Our snake is SNAKE_LENGTH = 5 blocks long.

Move eastward

Set frontIsClear() to always return true for now, so we can test our snake moving in one direction (eastward). Implement moveSnake() to move the snake one box to the right; remember, the snake should be moving SQUARE_LENGTH + SQUARE_GAP to keep the gap between the different parts of the snake!

There is a trick here; you don't need to move every single block in the snake. In fact, you just need to move one block! Think about which block you would move to give the illusion of the entire snake moving.

The block you chose will now be the head of the snake, so not only do you have to update its location on the canvas, but you also need to update its position in the ArrayList. Remove the block and add it to the head (in the previous part, we designated the head to be the 0th position of the ArrayList).

snake.remove(block); // the GRect you moved
snake.add(0, block); // becomes the new head

Next, implement frontIsClear() to check when you've reached the rightmost wall. Again, there's a trick here: can you check if the entire snake can move by just checking a single block? (Hint: it's the head)

You should now be able to see your snake move step-by-step to the east wall!

Move along the border

You're very close to the finish line!! Implement turnLeft(). This should be VERY simple; remember what we did in BorderBox.

Now, we have to extend moveSnake() and frontIsClear() to handle multiple directions. There's one last trick. Suppose we have the snake in the following configuration, where snakeDirection = NORTH:

In order to move the snake (read: give the illusion that the entire snake has moved), do we care that part of the snake is still turning? (Hint: No, we don't) Given this information, how do we move that single block that you selected in the previous part to move north, in the direction that the snake is facing?


Congratulations, you now have a moving snake! :)