Mushroom

<< ChickenBugs | GridworldTrailIndex | RockHound >>

Make a Mushroom Actor that will keep track of its age so that it will die (remove itself from the grid) after 4 steps.

Watch a Quicktime movie of it in action

Make a MushroomBug that will drop Mushrooms instead of Flowers, and die (remove itself from the grid) if it "eats" (moves to a location occupied by) a Mushroom.

  1. Make and test your Mushroom class
  2. Make your MushroomBug, and test that it drops Mushrooms, and has a boolean poisoned field and originalColor field.
  3. Override your MushroomBug's canMove() method to record if was poisoned, and allow moving over Mushroom objects
  4. Override your Mushroom's move() method so it turns black if it is poisoned, and if it is already black removes itself from the grid.
  5. See if you can further adapt your move() method so that it drops a Tombstone (of the MushroomBug's original color) instead of a Mushroom when it removes itself from the grid.
  6. See if you can get a hint from the Flower class so that your Tombstone is actually a darker version of the MushroomBug's original color.

MushroomBugRunner.java

import java.awt.Color;
import info.gridworld.actor.*;
import info.gridworld.grid.BoundedGrid;
import info.gridworld.grid.Location;

public class MushroomBugRunner 
{
	public static void main (String[] args)
	{
		ActorWorld  myWorld = new ActorWorld();
		myWorld.setGrid(new BoundedGrid<Actor>(4,5));
		myWorld.setMessage("Mushroom Bug Runner");
		myWorld.add(new Location(3,4), new Mushroom());
		myWorld.add(new Location(0,2), new Rock());
		myWorld.add(new Location(1,1), new MushroomBug());
		MushroomBug greeny=new MushroomBug(Color.GREEN);
		myWorld.add(new Location (1,0), greeny);
		MushroomBug yellowy=new MushroomBug(Color.YELLOW);
		yellowy.setDirection(Location.NORTHEAST);
		myWorld.add(new Location(3,3), yellowy);
		myWorld.show();
	}
}

Get some ideas for the Mushroom from the Flower class. What would you do differently?

Flower.java

/* 
 * AP(r) Computer Science GridWorld Case Study:
 * Copyright(c) 2005-2006 Cay S. Horstmann (http://horstmann.com)
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * @author Cay Horstmann
 */

package info.gridworld.actor;

import java.awt.Color;

/**
 * A <code>Flower</code> is an actor that darkens over time. Some actors drop
 * flowers as they move. <br />
 * The API of this class is testable on the AP CS A and AB exams.
 */

public class Flower extends Actor
{
    private static final Color DEFAULT_COLOR = Color.PINK;
    private static final double DARKENING_FACTOR = 0.05;

    // lose 5% of color value in each step

    /**
     * Constructs a pink flower.
     */
    public Flower()
    {
        setColor(DEFAULT_COLOR);
    }

    /**
     * Constructs a flower of a given color.
     * @param initialColor the initial color of this flower
     */
    public Flower(Color initialColor)
    {
        setColor(initialColor);
    }

    /**
     * Causes the color of this flower to darken.
     */
    public void act()
    {
        Color c = getColor();
        int red = (int) (c.getRed() * (1 - DARKENING_FACTOR));
        int green = (int) (c.getGreen() * (1 - DARKENING_FACTOR));
        int blue = (int) (c.getBlue() * (1 - DARKENING_FACTOR));

        setColor(new Color(red, green, blue));
    }
}

Get some ideas for the MushroomBug from the Bug class. What methods do you need to override?

Bug.java

/* 
 * AP(r) Computer Science GridWorld Case Study:
 * Copyright(c) 2005-2006 Cay S. Horstmann (http://horstmann.com)
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * @author Cay Horstmann
 */

package info.gridworld.actor;

import info.gridworld.grid.Grid;
import info.gridworld.grid.Location;

import java.awt.Color;

/**
 * A <code>Bug</code> is an actor that can move and turn. It drops flowers as
 * it moves. <br />
 * The implementation of this class is testable on the AP CS A and AB exams.
 */
public class Bug extends Actor
{
    /**
     * Constructs a red bug.
     */
    public Bug()
    {
        setColor(Color.RED);
    }

    /**
     * Constructs a bug of a given color.
     * @param bugColor the color for this bug
     */
    public Bug(Color bugColor)
    {
        setColor(bugColor);
    }

    /**
     * Moves if it can move, turns otherwise.
     */
    public void act()
    {
        if (canMove())
            move();
        else
            turn();
    }

    /**
     * Turns the bug 45 degrees to the right without changing its location.
     */
    public void turn()
    {
        setDirection(getDirection() + Location.HALF_RIGHT);
    }

    /**
     * Moves the bug forward, putting a flower into the location it previously
     * occupied.
     */
    public void move()
    {
        Grid<Actor> gr = getGrid();
        if (gr == null)
            return;
        Location loc = getLocation();
        Location next = loc.getAdjacentLocation(getDirection());
        if (gr.isValid(next))
            moveTo(next);
        else
            removeSelfFromGrid();
        Flower flower = new Flower(getColor());
        flower.putSelfInGrid(gr, loc);
    }

    /**
     * Tests whether this bug can move forward into a location that is empty or
     * contains a flower.
     * @return true if this bug can move.
     */
    public boolean canMove()
    {
        Grid<Actor> gr = getGrid();
        if (gr == null)
            return false;
        Location loc = getLocation();
        Location next = loc.getAdjacentLocation(getDirection());
        if (!gr.isValid(next))
            return false;
        Actor neighbor = gr.get(next);
        return (neighbor == null) || (neighbor instanceof Flower);
        // ok to move into empty location or onto flower
        // not ok to move onto any other actor
    }
}