Skip to content

Instantly share code, notes, and snippets.

@schleary
Created July 14, 2014 18:45
Show Gist options
  • Select an option

  • Save schleary/dca69ea832eabdedeb3d to your computer and use it in GitHub Desktop.

Select an option

Save schleary/dca69ea832eabdedeb3d to your computer and use it in GitHub Desktop.

Revisions

  1. schleary created this gist Jul 14, 2014.
    102 changes: 102 additions & 0 deletions BadCabbage.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,102 @@
    import java.awt.Color;
    import java.awt.Point;
    import uwcse.graphics.*;
    import java.awt.Point;
    import java.util.ArrayList;
    import javax.swing.JOptionPane;
    import uwcse.graphics.*;

    public class BadCabbage extends Cabbage {
    Oval circle;
    private ArrayList<Point> body = new ArrayList<Point>();
    private ArrayList<Rectangle> bodyUnits;

    /**
    * Creates a cabbage in the graphics window
    *
    * @param window
    * the GWindow this Cabbage belongs to
    * @param center
    * the center Point of this Cabbage
    */
    public BadCabbage(GWindow window, Point center) {
    super(window, center);
    draw();
    }

    /**
    * Displays this Cabbage in the graphics window
    */
    protected void draw() {
    int x = (int) center.getX();
    int y = (int) center.getY();

    // Make sure cabbage does not already exist here
    getLocation();

    this.circle = new Oval(x - CABBAGE_RADIUS, y - CABBAGE_RADIUS,
    CABBAGE_RADIUS * 2, CABBAGE_RADIUS * 2, Color.RED, true);
    window.add(circle);
    }

    /**
    * Checks for overlapping cabbages
    *
    * @param Point
    * p
    * @return boolean is cabbage overlapping
    *
    */
    public boolean isCabbageInCabbage(Point p) {
    return (p.distance(center) <= CABBAGE_RADIUS * 2);
    }

    /**
    * This cabbage is eaten by a caterpillar
    *
    * @param cp
    * the caterpillar that is eating this cabbage
    */
    public void isEatenBy(Caterpillar cp, ArrayList<Point> body,
    ArrayList<Rectangle> bodyUnits) {
    // Remove cabbages
    window.remove(this.circle);
    window.stopTimerEvents();
    int n = JOptionPane.showConfirmDialog(null,
    "You ate a bad Cabbage! Would you like to play again?",
    "GAME OVER", JOptionPane.YES_NO_OPTION);
    if (n == 0) {
    window.setExitOnClose();
    new CaterpillarGame();
    } else {
    // exit game
    System.exit(0);
    }
    }

    /**
    * Is this Point in this Cabbage?
    *
    * @param p
    * the Point to check
    * @return true if p in within the cabbage and false otherwise.
    *
    */
    public boolean isPointInCabbage(Point p) {
    return (p.distance(center) <= CABBAGE_RADIUS);
    }

    public double distance(Cabbage c) {
    return Math.sqrt((c.center.x - center.x) * (c.center.x - center.x)
    + (c.center.y - center.y) * (c.center.y - center.y));
    }

    /**
    * Returns the location of this Cabbage
    *
    * @return the location of this Cabbage.
    */
    public Point getLocation() {
    return new Point(center);
    }
    }
    76 changes: 76 additions & 0 deletions Cabbage.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    import uwcse.graphics.*;

    import java.awt.Point;
    import java.util.ArrayList;

    /**
    * An abstract class that contains all of the basic features of a cabbage. It
    * should be derived by any class that represents a cabbage. (complete, but you
    * can add other methods if you want)
    */

    public abstract class Cabbage implements CaterpillarGameConstants {
    // The graphics window this Cabbage belongs to
    protected GWindow window;

    // The location of the center of this Cabbage in the graphics window
    protected Point center;

    /**
    * Creates a cabbage in the graphics window
    *
    * @param window
    * the GWindow this Cabbage belongs to
    * @param center
    * the center Point of this Cabbage
    */
    public Cabbage(GWindow window, Point center) {
    this.window = window;
    this.center = new Point(center);
    }

    /**
    * Displays this Cabbage in the graphics window
    */
    protected abstract void draw();

    /**
    * This cabbage is eaten by a caterpillar
    *
    * @param cp
    * the caterpillar that is eating this cabbage
    */
    public abstract void isEatenBy(Caterpillar cp, ArrayList<Point> body,
    ArrayList<Rectangle> bodyUnits);

    /**
    * Is this Point in this Cabbage?
    *
    * @param p
    * the Point to check
    * @return true if p in within the cabbage and false otherwise.
    */
    public boolean isPointInCabbage(Point p) {

    return (p.distance(center) <= CABBAGE_RADIUS);
    }

    public boolean isCabbageInCabbage(Point p) {

    return (p.distance(center) <= CABBAGE_RADIUS * 2);
    }

    public double distance(Cabbage c) {
    return Math.sqrt((c.center.x - center.x) * (c.center.x - center.x)
    + (c.center.y - center.y) * (c.center.y - center.y));
    }

    /**
    * Returns the location of this Cabbage
    *
    * @return the location of this Cabbage.
    */
    public Point getLocation() {
    return new Point(center);
    }
    }
    382 changes: 382 additions & 0 deletions Caterpillar.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,382 @@
    import uwcse.graphics.*;

    import java.awt.Point;
    import java.util.*;
    //import java.util.concurrent.RecursiveTask;
    import java.awt.Color;

    import javax.swing.JOptionPane;

    import org.w3c.dom.css.Rect;

    /**
    * 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<Point> body = new ArrayList<Point>();

    // Store the graphical elements of the caterpillar body
    // Useful to erase the body of the caterpillar on the screen
    private ArrayList<Rectangle> bodyUnits = new ArrayList<Rectangle>();

    // The window the caterpillar belongs to
    private GWindow window;

    // Direction of motion of the caterpillar (NORTH initially)
    private int dir = NORTH;

    // Length of a unit of the body of the caterpillar
    // MUST be equal to the distance covered by the caterpillar
    // at every step of the animation.
    private final int bodyUnitLength = STEP;
    // Width of a unit of the body of the caterpillar
    private final int bodyUnitWidth = CATERPILLAR_WIDTH;

    private ArrayList<Cabbage> cabbages;

    /**
    * Constructs a caterpillar
    *
    * @param window
    * the graphics where to draw the caterpillar.
    */
    public Caterpillar(GWindow window, ArrayList<Cabbage> cabbages) {
    this.cabbages = cabbages;
    // 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;
    }
    // Show the caterpillar
    draw();
    }

    /**
    * Draw the caterpillar in the graphics window
    */
    private void draw() {
    // Connect with Rectangles the points of the body
    Point p = body.get(0);

    for (int i = 1; i < body.size(); i++) {
    Point q = body.get(i);
    // add a body unit between p and q
    addBodyUnit(p, q, bodyUnits.size(), Color.RED);
    p = q;
    }
    window.doRepaint();
    }

    /**
    * Moves the caterpillar in the current direction (complete)
    */
    public void move() {
    move(dir);
    }

    /**
    * Move the caterpillar in the direction newDir. <br>
    * If the new direction is illegal, select randomly a legal direction of
    * motion and move in that direction.<br>
    *
    * @param newDir
    * the new direction.
    */

    public void move(int newDir) {

    // while caterpillar is trying to do anything invalid
    while (!isPointInTheWindow(newDir) || isApproachingFence(newDir)
    || !validDirection(newDir) || isCrawlingOverItself(newDir)) {
    // if point is not in window
    if (!isPointInTheWindow(newDir)) {
    int[] directions = { NORTH, SOUTH, WEST, EAST };
    newDir = directions[(int) (Math.random() * directions.length)];
    }
    // if about to run into fence
    if (isApproachingFence(newDir)) {
    if (newDir == NORTH || newDir == SOUTH) {
    int[] direction = { WEST, EAST };
    newDir = direction[(int) (Math.random() * direction.length)];

    } else if (newDir == EAST || newDir == WEST) {
    int[] direction = { NORTH, SOUTH };
    newDir = direction[(int) (Math.random() * direction.length)];
    }
    }
    // if attempting to go backwards
    if (!validDirection(newDir)) {
    // keep caterpillar moving in same direction
    newDir = dir;
    }
    // if eats self
    if (isCrawlingOverItself(newDir)) {
    // You lose!;
    }
    }

    // If caterpillar eats all good cabbages and leaves window
    if (isOutsideGarden() && this.cabbages.size() < 11) {
    window.stopTimerEvents();
    int n = JOptionPane.showConfirmDialog(null,
    "You won the game! Would you like to play again?",
    "YOU WIN!", JOptionPane.YES_NO_OPTION);
    if (n == 0) {
    window.setExitOnClose();
    new CaterpillarGame();
    } else {
    // exit game
    System.exit(0);
    }
    }

    // If caterpillar eats cabbages
    Point head = getHead();
    for (int i = 0; i < cabbages.size(); i++) {
    Cabbage c = cabbages.get(i);
    boolean eaten = c.isPointInCabbage(head);
    if (eaten) {
    c.isEatenBy(this, body, bodyUnits);
    cabbages.remove(c);
    }
    }

    // new position of the head
    head = new Point(body.get(body.size() - 1));
    switch (newDir) {
    case NORTH:
    head.y -= STEP;
    break;
    case EAST:
    head.x += STEP;
    break;
    case SOUTH:
    head.y += STEP;
    break;
    case WEST:
    head.x -= STEP;
    break;
    }

    // Is the new position in the window?
    if (isPointInTheWindow(newDir)) {
    // update the position of the caterpillar
    body.add(head);
    body.remove(0);
    }

    // Update the current direction of motion
    dir = newDir;

    // Show the new location of the caterpillar
    moveCaterpillarOnScreen();

    }

    /**
    * Move the caterpillar on the screen
    */
    private void moveCaterpillarOnScreen() {
    // Erase the body unit at the tail
    Rectangle r = bodyUnits.remove(0);
    window.remove(r);
    // Add a new body unit at the head
    Point p = body.get(body.size() - 1);
    Point q = body.get(body.size() - 2);
    addBodyUnit(p, q, bodyUnits.size(), Color.RED);
    // show it
    window.doRepaint();
    }

    /**
    * Add a body unit to the caterpillar. The body unit connects Point p and
    * Point q.<br>
    * Insert this body unit at position index in bodyUnits.<br>
    * e.g. 0 to insert at the tail and bodyUnits.size() to insert at the head.
    */
    public void addBodyUnit(Point p, Point q, int index, Color c) {
    // Connect p and q with a rectangle.
    // To allow for a smooth look of the caterpillar, p and q
    // are not on the edges of the Rectangle
    // Upper left corner of the rectangle
    int x = Math.min(q.x, p.x) - CATERPILLAR_WIDTH / 2;
    int y = Math.min(q.y, p.y) - CATERPILLAR_WIDTH / 2;

    // Width and height of the rectangle (vertical or horizontal rectangle?)
    int width = ((q.y == p.y) ? (STEP + CATERPILLAR_WIDTH)
    : CATERPILLAR_WIDTH);
    int height = ((q.x == p.x) ? (STEP + CATERPILLAR_WIDTH)
    : CATERPILLAR_WIDTH);

    // Create the rectangle and place it in the window
    Rectangle r = new Rectangle(x, y, width, height, c, true);
    window.add(r);

    // keep track of that rectangle (we will erase it at some point)
    bodyUnits.add(index, r);
    }

    /**
    * Is the caterpillar crawling over itself?
    *
    * @return true if the caterpillar is crawling over itself and false
    * otherwise.
    */
    public boolean isCrawlingOverItself(int newDir) {
    // Is the head point equal to any other point of the caterpillar?
    Point head = getHead();
    int x = (int) head.getX();
    int y = (int) head.getY();

    if (newDir == NORTH) {
    y -= STEP;
    } else if (newDir == EAST) {
    x += STEP;
    } else if (newDir == WEST) {
    x -= STEP;
    } else { // SOUTH
    y += STEP;
    }
    // Check each rectangle in caterpillar body; if head points are inside
    // any rectangle, end game.
    for (int i = 0; i < bodyUnits.size(); i++) {
    int w = bodyUnits.get(i).getWidth();
    int h = bodyUnits.get(i).getHeight();
    int bx = bodyUnits.get(i).getX();
    int by = bodyUnits.get(i).getY();

    if ((x > bx && x < (bx + w)) && (y > by && y < (by + h))) {
    window.stopTimerEvents();
    int n = JOptionPane.showConfirmDialog(null,
    "You ate yourself! Would you like to play again?",
    "GAME OVER", JOptionPane.YES_NO_OPTION);
    if (n == 0) {
    window.setExitOnClose();
    new CaterpillarGame();
    } else {
    // exit game
    System.exit(0);
    }
    return true;
    }
    }
    return false;
    }

    /**
    * 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 isApproachingFence(int newDir) {
    // Get head; get direction. Find future head.
    Point head = getHead();
    int x = (int) head.getX();
    int y = (int) head.getY();

    if (newDir == NORTH) {
    y -= STEP;
    } else if (newDir == EAST) {
    x += STEP;
    } else if (newDir == WEST) {
    x -= STEP;
    } else { // SOUTH
    y += STEP;
    }

    // If future head overlaps with body
    if ((x > 149 && x < 161)
    && ((y > 0 && y < 201) || (y > 299 && y < 500))) {
    return true;
    }
    if (x > 491) {
    return true;
    }
    if (y < 11 || y > 491) {
    return true;
    }
    return false;
    }

    public boolean isOutsideGarden() {
    // Check head
    Point head = getHead();
    int x = (int) head.getX();

    // Check tail
    Point tail = new Point(body.get(0));
    int x2 = (int) tail.getX();

    // If head and tail are outside the garden
    if (x < 140 && x2 < 140) {
    return true;
    }
    return false;
    }

    /**
    * Is newDir valid?
    *@param int newDir
    *@returns boolean validity
    */
    public boolean validDirection(int newDir) {
    if ((dir == NORTH && newDir == SOUTH)
    || (dir == SOUTH && newDir == NORTH)
    || (dir == EAST && newDir == WEST)
    || (dir == WEST && newDir == EAST)) {
    return false;
    }
    return true;
    }

    /**
    * Is Point p in the window?
    * @ param newDir
    * @returns boolean
    */
    private boolean isPointInTheWindow(int newDir) {
    Point head = getHead();
    int x = (int) head.getX();
    int y = (int) head.getY();

    if (newDir == NORTH) {
    y -= STEP;
    } else if (newDir == EAST) {
    x += STEP;
    } else if (newDir == WEST) {
    x -= STEP;
    } else { // SOUTH
    y += STEP;
    }

    // Checks to see if point is in the window
    if ((x < 1 || x > 499) || (y < 1 || y > 499)) {
    return false;
    }
    return true;
    }

    /**
    * 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));
    }
    }
    231 changes: 231 additions & 0 deletions CaterpillarGame.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,231 @@
    import uwcse.graphics.*;

    import java.util.*;
    import java.awt.Color;
    import java.awt.Point;

    import javax.swing.JOptionPane;

    /**
    * A CaterpillarGame displays a garden that contains good and bad cabbages and a
    * constantly moving caterpillar. The player directs the moves of the
    * caterpillar. Every time the caterpillar eats a cabbage, the caterpillar
    * grows. The player wins when all of the good cabbages are eaten and the
    * caterpillar has left the garden. The player loses if the caterpillar eats a
    * bad cabbage or crawls over itself.
    */

    public class CaterpillarGame extends GWindowEventAdapter implements
    CaterpillarGameConstants
    // The class inherits from GWindowEventAdapter so that it can handle key events
    // (in the method keyPressed), and timer events.
    // All of the code to make this class able to handle key events and perform
    // some animation is already written.
    {
    // Game window
    private GWindow window;

    // The caterpillar
    private Caterpillar cp;

    // Direction of motion given by the player
    private int dirFromKeyboard;

    // Do we have a keyboard event
    private boolean isKeyboardEventNew = false;

    // The list of all the cabbages
    private ArrayList<Cabbage> cabbages;

    private String messageGameOver;

    /**
    * Constructs a CaterpillarGame
    */
    public CaterpillarGame() {
    // Create the graphics window
    window = new GWindow("Caterpillar game", WINDOW_WIDTH, WINDOW_HEIGHT);

    // Any key or timer event while the window is active is sent to this
    // CaterpillarGame
    window.addEventHandler(this);

    // Set up the game (fence, cabbages, caterpillar)
    initializeGame();

    // Display the game rules
    // ...
    // Rules
    JOptionPane
    .showMessageDialog(
    null,
    " WELCOME TO CATERPILLAR GAME! \n\n "
    + "To win, you must eat all of the white and psychedelic \n"
    + " cabbage heads and then exit the garden \n \n"
    + " Do not eat the poisonous red cabbages \n"
    + " Do not eat yourself \n \n"
    + " Use 'J' to move left \n"
    + " Use 'K' to move right \n"
    + " Use 'I' to move up \n"
    + " Use 'M' to move down \n \n"
    + " Are you ready to play? \n");

    // start timer events (to do the animation)

    this.window.startTimerEvents(ANIMATION_PERIOD);
    }

    /**
    * Initializes the game (draw the garden, garden fence, cabbages,
    * caterpillar)
    */
    private void initializeGame() {
    // Clear the window
    window.erase();

    // No keyboard event yet
    isKeyboardEventNew = false;

    // Background (the garden)
    window.add(new Rectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
    Color.green, true));

    // Create the fence around the garden
    Rectangle fence1 = new Rectangle(150, 0, 10, 200, Color.BLACK, true);
    Rectangle fence2 = new Rectangle(150, 300, 10, 200, Color.BLACK, true);
    Rectangle fence3 = new Rectangle(150, 0, 340, 10, Color.BLACK, true);
    Rectangle fence4 = new Rectangle(490, 0, 10, 500, Color.BLACK, true);
    Rectangle fence5 = new Rectangle(150, 490, 340, 10, Color.BLACK, true);
    window.add(fence1);
    window.add(fence2);
    window.add(fence3);
    window.add(fence4);
    window.add(fence5);

    // Cabbages
    // ...
    cabbages = new ArrayList<Cabbage>(N_GOOD_CABBAGES + N_BAD_CABBAGES);

    // Initialize the elements of the ArrayList = cabbages
    // (they should not overlap and be in the garden) ....
    Point center = new Point();
    boolean locationIsCabbageFree;
    for (int i = 0; i < N_BAD_CABBAGES + N_GOOD_CABBAGES; i++) {
    locationIsCabbageFree = false;
    while (!locationIsCabbageFree) {
    int x = (int) (Math.random() * 310) + 170;
    int y = (int) (Math.random() * 460) + 20;
    center.setLocation(x, y);

    locationIsCabbageFree = true;
    for (Cabbage cabbage : cabbages) {
    if (cabbage.isCabbageInCabbage(center)) {
    locationIsCabbageFree = false;
    }
    }
    }

    if (i < N_BAD_CABBAGES) {
    Cabbage c = new BadCabbage(window, center);
    cabbages.add(c);
    } else if (i < (N_BAD_CABBAGES + (N_GOOD_CABBAGES / 2))) {
    Cabbage c = new GoodCabbage(window, center);
    cabbages.add(c);
    } else if (i < N_BAD_CABBAGES + N_GOOD_CABBAGES) {
    Cabbage c = new PsychedelicCabbage(window, center);
    cabbages.add(c);
    }

    }
    // Create the caterpillar
    cp = new Caterpillar(window, cabbages);
    }

    /**
    * Moves the caterpillar within the graphics window every ANIMATION_PERIOD
    * milliseconds.
    *
    * @param e
    * the timer event
    */
    public void timerExpired(GWindowEvent e) {
    // Did we get a new direction from the user?
    // Use isKeyboardEventNew to take the event into account
    // only once
    if (isKeyboardEventNew) {// if user presses keyboard, store key that is
    // pressed
    isKeyboardEventNew = false;
    cp.move(dirFromKeyboard);
    } else
    cp.move();// always keep moving until key is pressed
    }

    /**
    * Moves the caterpillar according to the selection of the user i: NORTH, j:
    * WEST, k: EAST, m: SOUTH
    *
    * @param e
    * the keyboard event
    */
    public void keyPressed(GWindowEvent e) {

    switch (Character.toLowerCase(e.getKey())) {
    case 'i':
    dirFromKeyboard = NORTH;
    break;
    case 'j':
    dirFromKeyboard = WEST;
    break;
    case 'k':
    dirFromKeyboard = EAST;
    break;
    case 'm':
    dirFromKeyboard = SOUTH;
    break;
    case 'q':
    System.exit(0); // abruptly ends the application
    break;
    default:
    return;
    }

    // new keyboard event
    isKeyboardEventNew = true;
    }

    /**
    * The game is over. Starts a new game or ends the application
    */
    private void endTheGame() {
    window.stopTimerEvents();
    // messageGameOver is an instance String that
    // describes the outcome of the game that just ended
    // (e.g. congratulations! you win)
    boolean again = anotherGame(messageGameOver);
    if (again) {
    initializeGame();
    } else {
    System.exit(0);
    }
    }

    /**
    * Does the player want to play again?
    */
    private boolean anotherGame(String s) {
    int choice = JOptionPane.showConfirmDialog(null, s
    + "\nDo you want to play again?", "Game over",
    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
    if (choice == JOptionPane.YES_OPTION)
    return true;
    else
    return false;
    }

    /**
    * Starts the application
    */
    public static void main(String[] args) {
    new CaterpillarGame();
    }
    }
    41 changes: 41 additions & 0 deletions CaterpillarGameConstants.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    /**
    * Interface that lists useful constants for the caterpillar game
    */

    public interface CaterpillarGameConstants {
    // Possible directions for the motion of the caterpillar
    public static final int NORTH = 1;

    public static final int EAST = 2;

    public static final int WEST = 3;

    public static final int SOUTH = 4;

    // Distance covered by the caterpillar in one move
    public static final int STEP = 10;

    // Number of body elements added to the caterpillar when it grows
    // (after eating a good cabbage)
    public static final int GROWTH_SPURT = 5;

    // Thickness of the caterpillar
    public static final int CATERPILLAR_WIDTH = 6;

    // Number of good cabbages
    public static final int N_GOOD_CABBAGES = 10;

    // Number of bad cabbages
    public static final int N_BAD_CABBAGES = 10;

    // Radius of a cabbage head
    public static final int CABBAGE_RADIUS = 10;

    // Size of the graphics window
    public static final int WINDOW_HEIGHT = 500;

    public static final int WINDOW_WIDTH = 500;

    // Period of the animation (in ms)
    public static final int ANIMATION_PERIOD = 100; // change back to 30
    }
    95 changes: 95 additions & 0 deletions GoodCabbage.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,95 @@
    import java.awt.Color;
    import java.awt.Point;
    import java.util.ArrayList;

    import uwcse.graphics.*;

    public class GoodCabbage extends Cabbage {
    Oval circle;

    private ArrayList<Point> body = new ArrayList<Point>();
    private ArrayList<Rectangle> bodyUnits;

    /**
    * Creates a cabbage in the graphics window
    *
    * @param window
    * the GWindow this Cabbage belongs to
    * @param center
    * the center Point of this Cabbage
    */
    public GoodCabbage(GWindow window, Point center) {
    super(window, center);
    draw();
    }

    /**
    * Displays this Cabbage in the graphics window
    */
    protected void draw() {

    int x = (int) center.getX();
    int y = (int) center.getY();
    ArrayList<Point> centerPoints = new ArrayList<Point>();

    this.circle = new Oval(x - CABBAGE_RADIUS, y - CABBAGE_RADIUS,
    CABBAGE_RADIUS * 2, CABBAGE_RADIUS * 2, Color.WHITE, true);
    window.add(circle);
    centerPoints.add(center);
    }

    /**
    * Checks for overlapping cabbages
    *
    * @param Point
    * p
    * @return boolean is cabbage overlapping
    *
    */
    public boolean isCabbageInCabbage(Point p) {

    return (p.distance(center) <= CABBAGE_RADIUS * 2);
    }

    /**
    * This cabbage is eaten by a caterpillar
    *
    * @param cp
    * the caterpillar that is eating this cabbage
    */
    public void isEatenBy(Caterpillar cp, ArrayList<Point> body,
    ArrayList<Rectangle> bodyUnits) {
    this.body = body;
    this.bodyUnits = bodyUnits;
    window.remove(this.circle);
    Point p = body.get(body.size() - 1);
    Point q = body.get(body.size() - 2);
    cp.addBodyUnit(p, q, bodyUnits.size(), Color.RED);

    }

    /**
    * Is this Point in this Cabbage?
    *
    * @param p
    * the Point to check
    * @return true if p in within the cabbage and false otherwise.
    */
    public boolean isPointInCabbage(Point p) {
    return (p.distance(center) <= CABBAGE_RADIUS);
    }

    public double distance(Cabbage c) {
    return Math.sqrt((c.center.x - center.x) * (c.center.x - center.x)
    + (c.center.y - center.y) * (c.center.y - center.y));
    }

    /**
    * Returns the location of this Cabbage
    *
    * @return the location of this Cabbage.
    */
    public Point getLocation() {
    return new Point(center);
    }
    }
    107 changes: 107 additions & 0 deletions PsychedelicCabbage.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,107 @@
    import java.awt.Color;
    import java.awt.Point;
    import uwcse.graphics.*;
    import java.awt.Point;
    import java.util.ArrayList;
    import uwcse.graphics.*;

    public class PsychedelicCabbage extends GoodCabbage {
    private ArrayList<Point> body = new ArrayList<Point>();
    private ArrayList<Rectangle> bodyUnits;
    //psychedelic cabbages
    Oval circle;
    Oval circle2;

    /**
    * Creates a cabbage in the graphics window
    *
    * @param window
    * the GWindow this Cabbage belongs to
    * @param center
    * the center Point of this Cabbage
    */
    public PsychedelicCabbage(GWindow window, Point center) {
    super(window, center);
    }

    /**
    * Displays this Cabbage in the graphics window
    */
    protected void draw() {
    int x = (int) center.getX();
    int y = (int) center.getY();

    // Create and draw cabbage points
    ArrayList<Point> centerPoints = new ArrayList<Point>();
    this.circle = new Oval(x - CABBAGE_RADIUS, y - CABBAGE_RADIUS,
    CABBAGE_RADIUS * 2, CABBAGE_RADIUS * 2, Color.PINK, true);
    this.circle2 = new Oval(x - CABBAGE_RADIUS / 2, y - CABBAGE_RADIUS / 2,
    CABBAGE_RADIUS * 1, CABBAGE_RADIUS * 1, Color.BLUE, true);

    this.window.add(this.circle);
    this.window.add(this.circle2);
    centerPoints.add(center);
    }

    /**
    * Checks for overlapping cabbages
    *
    * @param Point
    * p
    * @return boolean is cabbage overlapping
    *
    */
    public boolean isCabbageInCabbage(Point p) {
    return (p.distance(center) <= CABBAGE_RADIUS * 2);
    }

    /**
    * This cabbage is eaten by a caterpillar
    *
    * @param cp
    * the caterpillar that is eating this cabbage
    */
    public void isEatenBy(Caterpillar cp, ArrayList<Point> body,
    ArrayList<Rectangle> bodyUnits) {
    // Remove cabbages
    this.window.remove(this.circle2);
    this.window.remove(this.circle);
    this.body = body;
    this.bodyUnits = bodyUnits;
    Point p = body.get(body.size() - 1);
    Point q = body.get(body.size() - 2);
    // Make psychedelic colors
    for (int i = 0; i < bodyUnits.size(); i++) {
    Color c = new Color((float) Math.random(), (float) Math.random(),
    (float) Math.random());
    bodyUnits.get(i).setColor(c);
    }
    cp.addBodyUnit(p, q, bodyUnits.size(), Color.WHITE); // color
    }

    /**
    * Is this Point in this Cabbage?
    *
    * @param p
    * the Point to check
    * @return true if p in within the cabbage and false otherwise.
    */
    public boolean isPointInCabbage(Point p) {
    return (p.distance(center) <= CABBAGE_RADIUS);
    }

    public double distance(Cabbage c) {
    return Math.sqrt((c.center.x - center.x) * (c.center.x - center.x)
    + (c.center.y - center.y) * (c.center.y - center.y));
    }

    /**
    * Returns the location of this Cabbage
    *
    * @return the location of this Cabbage.
    */
    public Point getLocation() {
    return new Point(center);
    }

    }