Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Follow these steps to get the project loaded in NetBeans. Download the attached zip file: HugLife.zip. You should now see the project loaded into NetBeans.

Follow these steps to get the project loaded in NetBeans.

  1. Download the attached zip file: HugLife.zip.

You should now see the project loaded into NetBeans.

Part 1 - Running the Program

Run the program in NetBeans. This starts up a world called samplesolo. You should see a little red square wandering around randomly. The creatures you'll create in this assignment will go in the creatures directory, in these two files:

  • Plip.java (skeleton provided)
  • Clorus.java (you'll need to create this)

Eventually these two types of creatures will also inhabit the world, and unlike this red creature, they actually do something interesting. These classes will extend the huglife.Creature class, which provides a template that all creatures should follow.

Part 2 - How the Simulator Works

Creatures live on an NxN grid, with no wraparound. Each square may be empty, impassible, or contain exactly one creature. At each tic (timestep), exactly one creature takes a single action. Creatures choose actions in a round-robin fashion. There is a global queue of all creatures in the world, waiting their turn to take an action. When a creature is at the front of the queue, the world simulator tells that creature who its four neighbors are and requests a choice of action from the creature. More specifically, the world simulator calls the creature's chooseAction() method, which takes as an argument a collection of all four neighbors. Based on the identity of the four neighbors, the creature then chooses one of exactly five actions: MOVE, REPLICATE, ATTACK, STAY, or DIE. MOVE, REPLICATE, and ATTACK are directional actions, and STAY and DIE are stationary actions. If a creature takes a directional action, it must specify either a direction or a location. For example, if the acting creature sees a creature to its LEFT that it can eat, it might choose to ATTACK LEFT. One of your main tasks for this assignment is to write the code that makes Creature decisions. Actions are returned as objects of type Action, which are fully described in huglife/Action.java. After a creature chooses an Action, the simulator enacts the changes to the world grid. You'll be responsible for writing the code that tracks the state of each creature. For example, after the acting creature eats another creature, the acting Creature might become stronger, die, change colors, etc. This will be accomplished by a callback to the creature, which is required to provide move(), replicate(), attack(), and stay() methods that describe how the state of the acting creature will evolve after each of these respective actions. For example, if your creature chooses to replicate upwards by returning new Action(Action.ActionType.REPLICATE, Direction.TOP), then the game simulator is guaranteed to later call the replicate() method of the creature that made this choice.

Part 3 - Experimenting with the Sample Creature

Open up Occupant.java, Creature.java, and SampleCreature.java, which you'll find in the huglife package. Occupant is a general class for all possible things that can inhabit the grid of the HugLife universe. You'll see that every Occupant inherits a name, shared by all instances of that Occupant subtype. Furthermore, every Occupant must provide a method that returns a color (more on this later). There are two special Occupant types, with names "empty" and "impassible". These represent unoccupied and unoccupiable squares, respectively.

Creature is a general class for all living things that can inhabit the grid of the HugLife universe. Every Creature has an energy level, and if that energy level ever falls below zero, the universe will choose the DIE action for them. Every creature must implement four callback methods: move(), replicate(), attack(), and stay(). These describe what the creature should do when each of these actions occurs. There is no die() method since the creature is simply removed from the world entirely. Creatures must also implement a chooseAction() method, and any reasonable creature will probably find the built-in getNeighborsOfType() method useful for doing so.

SampleCreature is a sample Creature; in fact, it's the lonely red square we saw earlier. The two creatures you implement for this assignment will look somewhat similar to the SampleCreature, so you'll want to consult this class later. Make some changes to the sample creature and observe how they affect the HugLife simulation. As one of your experiments, you might have the SampleCreature react in some observable way when it sees a wall. You can do this by requesting a list of all neighbors of type "impassible" from the getNeighborsOfType() method.

Part 4 - Creating a Plip

Now it's time to add a new type of creature to the world. Go into the creatures package, and you'll see a file named Plip.java there, waiting to be filled out. Plips will be lazy (but motile) photosynthesizing creatures. They mostly just stand around and grow and replicate, but they'll flee if they happen to see their mortal enemy, the Clorus. Let's start with just a few of the properties that we'll eventually need for our Plip class.

  • The name() method (inherited from Occupant) should return exactly "plip" with no spaces or capitalization. This is important, since creatures only know how to react to each other based on this name string.
  • Plips should lose 0.15 units of energy on a MOVE action, and gain 0.2 units of energy on a STAY action.
  • Plips should never have energy greater than 2. If an action would cause the Plip to have energy greater than 2, then it should be set to 2 instead.
  • The color method for Plips should return a color with red = 99, blue = 76, and green that varies linearly based on the energy of the Plip. If the plip has zero energy, it should have a green value of 63. If it has max energy, it should have a green value of 255. The green value should vary with energy linearly in between these two extremes.

Program this functionality in the Plip class. To test your Plip functionality, you can load a world that contains a Plip. Find the main method in the HugLife.java file. Change the world name from samplesolo.world to sampleplip.world.

Part 5 - Plip replicate() and chooseAction() Methods

Now we'll work on adding the correct replication property to our Plips. When a Plip replicates, it keeps 50% of its energy. The other 50% goes to its offspring. No energy is lost in the replication process. You'll be filling out the replicate() method in Plip.java. Take a look at that now. This method should create and return a new Plip object with 50% of the energy of the original one. The original Plip should lose 50% of its energy.

All that's left is giving the Plip a brain. To do this, you'll be filling out the chooseAction() method. The Plip should obey the following behavioral rules, in order of preference:

  1. If there are no empty spaces, the Plip should STAY. Look at the SampleCreature's chooseAction method for an example of how to see how many empty spaces there are around the Plip.
  2. Otherwise, if the Plip has energy greater than 1.0, it should replicate to a random available space. Again, see the SampleCreature's chooseAction method for an example of how to randomly choose an empty space. You do not have to take a move probability into account for this step. Make sure you choose the correct action type (REPLICATE).
  3. Otherwise, if it sees a neighbor with name equal to "clorus", it will move to any available empty square with probability 50%. It should choose the empty square randomly. As an example, if it sees a Clorus to the LEFT and to the BOTTOM, and "empty" to the TOP and RIGHT, there is a 50% chance it will move, and if it does move, it will pick randomly between RIGHT and TOP. Make sure you choose the correct action type (MOVE).
  4. Otherwise, it will stay.

These rules must be obeyed in this strict order! Example: If it has energy greater than 1, it will always replicate, even if there are neighboring Cloruses.

Test your program. Does it work? We don't have Cloruses yet, but you should see the two Plips replicate until they fill the entire board.

Part 6 - Introducing the Clorus

Now we'll implement the Clorus, a fierce blue-colored predator that enjoys nothing more than snacking on hapless Plips. To begin, create Clorus.java in the creatures package. Unlike before, you'll be writing this class from scratch. The Clorus should obey the following rules exactly:

  • All Cloruses must have a name equal to exactly "clorus" (no capitalization or spaces).
  • Cloruses should lose 0.03 units of energy on a MOVE action.
  • Cloruses should lose 0.01 units of energy on a STAY action.
  • Cloruses have no restrictions on their maximum energy.
  • The color() method for Cloruses should always return the color red = 34, green = 0, blue = 231.
  • If a Clorus attacks another creature, it should gain that creature's energy. This should happen in the attack() method, not in chooseAction(). You do not need to worry about making sure the attacked creature diesthe simulator does that for you.
  • When a Clorus replicates, it keeps 50% of its energy. The other 50% goes to its offspring. No energy is lost in the replication process.
  • Cloruses should obey exactly the following behavioral rules:
    • If there are no empty squares, the Clorus will STAY (even if there are Plips nearby they could attack).
    • Otherwise, if any Plips are seen, the Clorus will ATTACK one of them randomly.
    • Otherwise, if the Clorus has energy greater than one, it will REPLICATE to a random empty square.
    • Otherwise, the Clorus will MOVE to a random empty square.

Part 7 - Show Time

When you have finished writing the Clorus class, go into HugLife.java and uncomment the clorus lines in readWorld(). In the main method, change the world name to "strugggz.world". Now it's time to watch Cloruses and Plips battling it out. Run the program to kick off a Manichaean struggle that will end either in eternal oscillations or in lonely immortals wandering the wastes forever. If you did everything right, it should hopefully look cool. You might consider tweaking the HugLife simulator parameters, including the world size and the pause time between simulation steps. Be warned that world sizes above 50x50 are probably going to run fairly slowly.

package creatures;

import huglife.*; import java.awt.Color; import java.util.Map;

/** An implementation of a motile pacifist photosynthesizer. * @author Josh Hug */ public class Plip extends Creature {

/** red color. */ private int r; /** green color. */ private int g; /** blue color. */ private int b;

/** creates flip with energy equal to E. * @param e */ public Plip(double e) { super("plip"); r = 0; g = 0; b = 0; energy = e; }

/** creates a plip with energy equal to 1. */ public Plip() { this(1); }

/** Should return a color with red = 99, blue = 76, and green that varies * linearly based on the energy of the Plip. If the plip has zero energy, * it should have a green value of 63. If it has max energy, it should * have a green value of 255. The green value should vary with energy * linearly in between these two extremes. It's not absolutely vital * that you get this exactly correct. */ public Color color() { g = 63; return color(r, g, b); }

/** Do nothing with C, Plips are pacifists. */ public void attack(Creature c) { }

/** Plips should lose 0.15 units of energy when moving. If you want to * to avoid the magic number warning, you'll need to make a * private static final variable. This is not required for this lab. */ public void move() { }

/** Plips gain 0.2 energy when staying due to photosynthesis. */ public void stay() { }

/** Plips and their offspring each get 50% of the energy, with none * lost to the process. Now that's efficiency! Returns a baby * Plip. */ public Plip replicate() { return this; }

/** Plips take exactly the following actions based on NEIGHBORS: * 1. If no empty adjacent spaces, STAY. * 2. Otherwise, if energy >= 1, REPLICATE. * 3. Otherwise, if any Cloruses, MOVE with 50% probability. * 4. Otherwise, if nothing else, STAY * * Returns an object of type Action. See Action.java for the * scoop on how Actions work. See SampleCreature.chooseAction() * for an example to follow. */ public Action chooseAction(Map neighbors) { return new Action(Action.ActionType.STAY); }

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Mastering Apache Cassandra 3 X An Expert Guide To Improving Database Scalability And Availability Without Compromising Performance

Authors: Aaron Ploetz ,Tejaswi Malepati ,Nishant Neeraj

3rd Edition

1789131499, 978-1789131499

More Books

Students also viewed these Databases questions

Question

Prepare a short profile of Henry words worth Longfellow?

Answered: 1 week ago

Question

What is RAM as far as telecommunication is concerned?

Answered: 1 week ago

Question

Question 1: What is reproductive system? Question 2: What is Semen?

Answered: 1 week ago

Question

Describe the sources of long term financing.

Answered: 1 week ago