import uwcse.graphics.*; import java.awt.Point; import java.util.*; import java.awt.Color; /** * A Caterpillar is the representation and the display of a caterpillar */ public class Caterpillar implements CaterpillarGameConstants { // The body of a caterpillar is made of Points stored // in an ArrayList private ArrayList body = new ArrayList(); // Store the graphical elements of the caterpillar body // Useful to erase the body of the caterpillar on the screen private ArrayList bodyUnits = new ArrayList(); // The window the caterpillar belongs to private GWindow window; // Direction of motion of the caterpillar (NORTH initially) private int dir = NORTH; /** * Constructs a caterpillar * * @param window * the graphics where to draw the caterpillar. */ public Caterpillar(GWindow window) { // Initialize the graphics window for this Caterpillar this.window = window; // Create the caterpillar (10 points initially) // First point Point p = new Point(); p.x = 5; p.y = WINDOW_HEIGHT / 2; body.add(p); // Other points for (int i = 0; i < 9; i++) { Point q = new Point(p); q.translate(STEP, 0); body.add(q); p = q; } // Other initializations (if you have more instance fields) for (int i = 0; i < body.size() - 1; i++) { Point p1 = (Point) body.get(i); Point p2 = (Point) body.get(i + 1); addBodyUnit(p1, p2); } // Display the caterpillar (call a private method) display(); } /** * Moves the caterpillar in the current direction (complete) */ public void move() { move(dir); } /** * Move the caterpillar in the direction newDir.
* If the new direction is illegal, select randomly a legal direction of * motion and move in that direction.
* * @param newDir * the new direction. */ public void move(int newDir) { // true if we haven't tried the current direction yet boolean firstTry = true; boolean isInvalidMove; int[] direction = { NORTH, SOUTH, EAST, WEST }; do { // Compute the new location of the head of the caterpillar Point head = getHead(); switch (newDir) { case NORTH: head.y -= STEP; break; case WEST: head.x -= STEP; break; case SOUTH: head.y += STEP; break; case EAST: head.x += STEP; break; } // if the head is no longer in the window, select a new direction isInvalidMove = !isInWindow(head); if (isInvalidMove) { if (firstTry) { // first try the current direction newDir = dir; firstTry = false; } else { // random selection newDir = direction[(int) (Math.random() * 4)]; } } else { // valid move body.add(head); body.remove(0); window.remove((Shape) bodyUnits.remove(0)); addBodyUnit((Point) body.get(body.size() - 2), (Point) body .get(body.size() - 1)); window.add((Shape) bodyUnits.get(bodyUnits.size() - 1)); dir = newDir; } } while (isInvalidMove); } /** * Is the caterpillar crawling over itself? * * @return true if the caterpillar is crawling over itself and false * otherwise. */ public boolean isCrawlingOverItself() { // Is the head point equal to any other point of the caterpillar? Point head = getHead(); for (int i = 0; i <= body.size() - 2; i ++) { Point p = (Point) body.get(i); if (p.equals(head)) { return true; } } return false; // CHANGE THIS! } /** * Are all of the points of the caterpillar outside the garden * * @return true if the caterpillar is outside the garden and false * otherwise. */ public boolean isOutsideGarden() { return false; // CHANGE THIS! } /** * Return the location of the head of the caterpillar (complete) * * @return the location of the head of the caterpillar. */ public Point getHead() { return new Point((Point) body.get(body.size() - 1)); } /** * Increase the length of the caterpillar (by GROWTH_SPURT elements) Add the * elements at the tail of the caterpillar. */ public void grow() { } /** * Add a body unit to the caterpillar */ private void addBodyUnit(Point p, Point q) { // Create a rectangle between p and q Rectangle r; if (p.y == q.y) { // horizontal rectangle r = new Rectangle(Math.min(p.x, q.x), p.y - CATERPILLAR_WIDTH / 2, STEP, CATERPILLAR_WIDTH, Color.RED, true); } else { // vertical rectangle r = new Rectangle(p.x - CATERPILLAR_WIDTH / 2, Math.min(p.y, q.y), CATERPILLAR_WIDTH, STEP, Color.RED, true); } bodyUnits.add(r); } /** * Display the caterpillar */ private void display() { for (int i = 0; i < bodyUnits.size(); i++) { window.add((Shape) bodyUnits.get(i)); } } /** * Returns true if the given point is in the window */ private boolean isInWindow(Point p) { return p.x >= 0 && p.x <= window.getWindowWidth() && p.y >= 0 && p.y <= window.getWindowHeight(); } }