PBO-B fox and rabbit
Nama : Zahrul Zizki D
NRP : 05111740000168
Kelas : PBO-B
Tugas : Fox And Rabbit
Rabbit
FieldStats
Field
Location
Simulator
NRP : 05111740000168
Kelas : PBO-B
Tugas : Fox And Rabbit
Rabbit
import java.util.List;
import java.util.Random;
/**
* A simple model of a rabbit.
* Rabbits age, move, breed, and die.
*
* @author David J. Barnes and Michael Kolling
* @version 2008.03.30
*/
public class Rabbit
{
// Characteristics shared by all rabbits (static fields).
// The age at which a rabbit can start to breed.
private static final int BREEDING_AGE = 5;
// The age to which a rabbit can live.
private static final int MAX_AGE = 40;
// The likelihood of a rabbit breeding.
private static final double BREEDING_PROBABILITY = 0.15;
// The maximum number of births.
private static final int MAX_LITTER_SIZE = 4;
// A shared random number generator to control breeding.
private static final Random rand = Randomizer.getRandom();
// Individual characteristics (instance fields).
// The rabbit's age.
private int age;
// Whether the rabbit is alive or not.
private boolean alive;
// The rabbit's position.
private Location location;
// The field occupied.
private Field field;
/**
* Create a new rabbit. A rabbit may be created with age
* zero (a new born) or with a random age.
*
* @param randomAge If true, the rabbit will have a random age.
* @param field The field currently occupied.
* @param location The location within the field.
*/
public Rabbit(boolean randomAge, Field field, Location location)
{
age = 0;
alive = true;
this.field = field;
setLocation(location);
if(randomAge) {
age = rand.nextInt(MAX_AGE);
}
}
/**
* This is what the rabbit does most of the time - it runs
* around. Sometimes it will breed or die of old age.
* @param newRabbits A list to add newly born rabbits to.
*/
public void run(List<Rabbit> newRabbits)
{
incrementAge();
if(alive) {
giveBirth(newRabbits);
// Try to move into a free location.
Location newLocation = field.freeAdjacentLocation(location);
if(newLocation != null) {
setLocation(newLocation);
}
else {
// Overcrowding.
setDead();
}
}
}
/**
* Check whether the rabbit is alive or not.
* @return true if the rabbit is still alive.
*/
public boolean isAlive()
{
return alive;
}
/**
* Indicate that the rabbit is no longer alive.
* It is removed from the field.
*/
public void setDead()
{
alive = false;
if(location != null) {
field.clear(location);
location = null;
field = null;
}
}
/**
* Return the rabbit's location.
* @return The rabbit's location.
*/
public Location getLocation()
{
return location;
}
/**
* Place the rabbit at the new location in the given field.
* @param newLocation The rabbit's new location.
*/
private void setLocation(Location newLocation)
{
if(location != null) {
field.clear(location);
}
location = newLocation;
field.place(this, newLocation);
}
/**
* Increase the age.
* This could result in the rabbit's death.
*/
private void incrementAge()
{
age++;
if(age > MAX_AGE) {
setDead();
}
}
/**
* Check whether or not this rabbit is to give birth at this step.
* New births will be made into free adjacent locations.
* @param newRabbits A list to add newly born rabbits to.
*/
private void giveBirth(List<Rabbit> newRabbits)
{
// New rabbits are born into adjacent locations.
// Get a list of adjacent free locations.
List<Location> free = field.getFreeAdjacentLocations(location);
int births = breed();
for(int b = 0; b < births && free.size() > 0; b++) {
Location loc = free.remove(0);
Rabbit young = new Rabbit(false, field, loc);
newRabbits.add(young);
}
}
/**
* Generate a number representing the number of births,
* if it can breed.
* @return The number of births (may be zero).
*/
private int breed()
{
int births = 0;
if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {
births = rand.nextInt(MAX_LITTER_SIZE) + 1;
}
return births;
}
/**
* A rabbit can breed if it has reached the breeding age.
* @return true if the rabbit can breed, false otherwise.
*/
private boolean canBreed()
{
return age >= BREEDING_AGE;
}
}
FieldStats
import java.awt.Color;
import java.util.HashMap;
/**
* This class collects and provides some statistical data on the state
* of a field. It is flexible: it will create and maintain a counter
* for any class of object that is found within the field.
*
* @author David J. Barnes and Michael Kolling
* @version 2008.03.30
*/
public class FieldStats
{
// Counters for each type of entity (fox, rabbit, etc.) in the simulation.
private HashMap<Class, Counter> counters;
// Whether the counters are currently up to date.
private boolean countsValid;
/**
* Construct a FieldStats object.
*/
public FieldStats()
{
// Set up a collection for counters for each type of animal that
// we might find
counters = new HashMap<Class, Counter>();
countsValid = true;
}
/**
* Get details of what is in the field.
* @return A string describing what is in the field.
*/
public String getPopulationDetails(Field field)
{
StringBuffer buffer = new StringBuffer();
if(!countsValid) {
generateCounts(field);
}
for(Class key : counters.keySet()) {
Counter info = counters.get(key);
buffer.append(info.getName());
buffer.append(": ");
buffer.append(info.getCount());
buffer.append(' ');
}
return buffer.toString();
}
/**
* Invalidate the current set of statistics; reset all
* counts to zero.
*/
public void reset()
{
countsValid = false;
for(Class key : counters.keySet()) {
Counter count = counters.get(key);
count.reset();
}
}
/**
* Increment the count for one class of animal.
* @param animalClass The class of animal to increment.
*/
public void incrementCount(Class animalClass)
{
Counter count = counters.get(animalClass);
if(count == null) {
// We do not have a counter for this species yet.
// Create one.
count = new Counter(animalClass.getName());
counters.put(animalClass, count);
}
count.increment();
}
/**
* Indicate that an animal count has been completed.
*/
public void countFinished()
{
countsValid = true;
}
/**
* Determine whether the simulation is still viable.
* I.e., should it continue to run.
* @return true If there is more than one species alive.
*/
public boolean isViable(Field field)
{
// How many counts are non-zero.
int nonZero = 0;
if(!countsValid) {
generateCounts(field);
}
for(Class key : counters.keySet()) {
Counter info = counters.get(key);
if(info.getCount() > 0) {
nonZero++;
}
}
return nonZero > 1;
}
/**
* Generate counts of the number of foxes and rabbits.
* These are not kept up to date as foxes and rabbits
* are placed in the field, but only when a request
* is made for the information.
* @param field The field to generate the stats for.
*/
private void generateCounts(Field field)
{
reset();
for(int row = 0; row < field.getDepth(); row++) {
for(int col = 0; col < field.getWidth(); col++) {
Object animal = field.getObjectAt(row, col);
if(animal != null) {
incrementCount(animal.getClass());
}
}
}
countsValid = true;
}
}
Field
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
/**
* Represent a rectangular grid of field positions.
* Each position is able to store a single animal.
*
* @author David J. Barnes and Michael Kolling
* @version 2008.03.30
*/
public class Field
{
// A random number generator for providing random locations.
private static final Random rand = Randomizer.getRandom();
// The depth and width of the field.
private int depth, width;
// Storage for the animals.
private Object[][] field;
/**
* Represent a field of the given dimensions.
* @param depth The depth of the field.
* @param width The width of the field.
*/
public Field(int depth, int width)
{
this.depth = depth;
this.width = width;
field = new Object[depth][width];
}
/**
* Empty the field.
*/
public void clear()
{
for(int row = 0; row < depth; row++) {
for(int col = 0; col < width; col++) {
field[row][col] = null;
}
}
}
/**
* Clear the given location.
* @param location The location to clear.
*/
public void clear(Location location)
{
field[location.getRow()][location.getCol()] = null;
}
/**
* Place an animal at the given location.
* If there is already an animal at the location it will
* be lost.
* @param animal The animal to be placed.
* @param row Row coordinate of the location.
* @param col Column coordinate of the location.
*/
public void place(Object animal, int row, int col)
{
place(animal, new Location(row, col));
}
/**
* Place an animal at the given location.
* If there is already an animal at the location it will
* be lost.
* @param animal The animal to be placed.
* @param location Where to place the animal.
*/
public void place(Object animal, Location location)
{
field[location.getRow()][location.getCol()] = animal;
}
/**
* Return the animal at the given location, if any.
* @param location Where in the field.
* @return The animal at the given location, or null if there is none.
*/
public Object getObjectAt(Location location)
{
return getObjectAt(location.getRow(), location.getCol());
}
/**
* Return the animal at the given location, if any.
* @param row The desired row.
* @param col The desired column.
* @return The animal at the given location, or null if there is none.
*/
public Object getObjectAt(int row, int col)
{
return field[row][col];
}
/**
* Generate a random location that is adjacent to the
* given location, or is the same location.
* The returned location will be within the valid bounds
* of the field.
* @param location The location from which to generate an adjacency.
* @return A valid location within the grid area.
*/
public Location randomAdjacentLocation(Location location)
{
List<Location> adjacent = adjacentLocations(location);
return adjacent.get(0);
}
/**
* Get a shuffled list of the free adjacent locations.
* @param location Get locations adjacent to this.
* @return A list of free adjacent locations.
*/
public List<Location> getFreeAdjacentLocations(Location location)
{
List<Location> free = new LinkedList<Location>();
List<Location> adjacent = adjacentLocations(location);
for(Location next : adjacent) {
if(getObjectAt(next) == null) {
free.add(next);
}
}
return free;
}
/**
* Try to find a free location that is adjacent to the
* given location. If there is none, return null.
* The returned location will be within the valid bounds
* of the field.
* @param location The location from which to generate an adjacency.
* @return A valid location within the grid area.
*/
public Location freeAdjacentLocation(Location location)
{
// The available free ones.
List<Location> free = getFreeAdjacentLocations(location);
if(free.size() > 0) {
return free.get(0);
}
else {
return null;
}
}
/**
* Return a shuffled list of locations adjacent to the given one.
* The list will not include the location itself.
* All locations will lie within the grid.
* @param location The location from which to generate adjacencies.
* @return A list of locations adjacent to that given.
*/
public List<Location> adjacentLocations(Location location)
{
assert location != null : "Null location passed to adjacentLocations";
// The list of locations to be returned.
List<Location> locations = new LinkedList<Location>();
if(location != null) {
int row = location.getRow();
int col = location.getCol();
for(int roffset = -1; roffset <= 1; roffset++) {
int nextRow = row + roffset;
if(nextRow >= 0 && nextRow < depth) {
for(int coffset = -1; coffset <= 1; coffset++) {
int nextCol = col + coffset;
// Exclude invalid locations and the original location.
if(nextCol >= 0 && nextCol < width && (roffset != 0 || coffset != 0)) {
locations.add(new Location(nextRow, nextCol));
}
}
}
}
// Shuffle the list. Several other methods rely on the list
// being in a random order.
Collections.shuffle(locations, rand);
}
return locations;
}
/**
* Return the depth of the field.
* @return The depth of the field.
*/
public int getDepth()
{
return depth;
}
/**
* Return the width of the field.
* @return The width of the field.
*/
public int getWidth()
{
return width;
}
}
Location
/**
* Represent a location in a rectangular grid.
*
* @author David J. Barnes and Michael Kolling
* @version 2008.03.30
*/
public class Location
{
// Row and column positions.
private int row;
private int col;
/**
* Represent a row and column.
* @param row The row.
* @param col The column.
*/
public Location(int row, int col)
{
this.row = row;
this.col = col;
}
/**
* Implement content equality.
*/
public boolean equals(Object obj)
{
if(obj instanceof Location) {
Location other = (Location) obj;
return row == other.getRow() && col == other.getCol();
}
else {
return false;
}
}
/**
* Return a string of the form row,column
* @return A string representation of the location.
*/
public String toString()
{
return row + "," + col;
}
/**
* Use the top 16 bits for the row value and the bottom for
* the column. Except for very big grids, this should give a
* unique hash code for each (row, col) pair.
* @return A hashcode for the location.
*/
public int hashCode()
{
return (row << 16) + col;
}
/**
* @return The row.
*/
public int getRow()
{
return row;
}
/**
* @return The column.
*/
public int getCol()
{
return col;
}
}
Counterimport java.awt.Color;
/**
* @author Karina Soraya P
* @version 1.7/20181119
*/
public class Counter
{
private String name;
private int count;
public Counter(String name)
{
this.name = name;
count = 0;
}
public String getName()
{
return name;
}
public int getCount()
{
return count;
}
public void increment()
{
count++;
}
public void reset()
{
count = 0;
}
}
Randomizerimport java.util.Random;
/**
* Provide control over the randomization of the simulation.
*
* @author David J. Barnes and Michael Kolling
* @version 2008.03.30
*/
public class Randomizer
{
// The default seed for control of randomization.
private static final int SEED = 1111;
// A shared Random object, if required.
private static final Random rand = new Random(SEED);
// Determine whether a shared random generator is to be provided.
private static final boolean useShared = true;
/**
* Constructor for objects of class Randomizer
*/
public Randomizer()
{
}
/**
* Provide a random generator.
* @return A random object.
*/
public static Random getRandom()
{
if(useShared) {
return rand;
}
else {
return new Random();
}
}
/**
* Reset the randomization.
* This will have no effect if randomization is not through
* a shared Random generator.
*/
public static void reset()
{
if(useShared) {
rand.setSeed(SEED);
}
}
}
Fox import java.util.List;
import java.util.Iterator;
import java.util.Random;
/**
* A simple model of a fox.
* Foxes age, move, eat rabbits, and die.
*
* @author David J. Barnes and Michael Kolling
* @version 2008.03.30
*/
public class Fox
{
// Characteristics shared by all foxes (static fields).
// The age at which a fox can start to breed.
private static final int BREEDING_AGE = 10;
// The age to which a fox can live.
private static final int MAX_AGE = 150;
// The likelihood of a fox breeding.
private static final double BREEDING_PROBABILITY = 0.35;
// The maximum number of births.
private static final int MAX_LITTER_SIZE = 5;
// The food value of a single rabbit. In effect, this is the
// number of steps a fox can go before it has to eat again.
private static final int RABBIT_FOOD_VALUE = 7;
// A shared random number generator to control breeding.
private static final Random rand = Randomizer.getRandom();
// Individual characteristics (instance fields).
// The fox's age.
private int age;
// Whether the fox is alive or not.
private boolean alive;
// The fox's position.
private Location location;
// The field occupied.
private Field field;
// The fox's food level, which is increased by eating rabbits.
private int foodLevel;
/**
* Create a fox. A fox can be created as a new born (age zero
* and not hungry) or with a random age and food level.
*
* @param randomAge If true, the fox will have random age and hunger level.
* @param field The field currently occupied.
* @param location The location within the field.
*/
public Fox(boolean randomAge, Field field, Location location)
{
age = 0;
alive = true;
this.field = field;
setLocation(location);
if(randomAge) {
age = rand.nextInt(MAX_AGE);
foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);
}
else {
// leave age at 0
foodLevel = RABBIT_FOOD_VALUE;
}
}
/**
* This is what the fox does most of the time: it hunts for
* rabbits. In the process, it might breed, die of hunger,
* or die of old age.
* @param field The field currently occupied.
* @param newFoxes A list to add newly born foxes to.
*/
public void hunt(List<Fox> newFoxes)
{
incrementAge();
incrementHunger();
if(alive) {
giveBirth(newFoxes);
// Move towards a source of food if found.
Location newLocation = findFood(location);
if(newLocation == null) {
// No food found - try to move to a free location.
newLocation = field.freeAdjacentLocation(location);
}
// See if it was possible to move.
if(newLocation != null) {
setLocation(newLocation);
}
else {
// Overcrowding.
setDead();
}
}
}
/**
* Check whether the fox is alive or not.
* @return True if the fox is still alive.
*/
public boolean isAlive()
{
return alive;
}
/**
* Return the fox's location.
* @return The fox's location.
*/
public Location getLocation()
{
return location;
}
/**
* Place the fox at the new location in the given field.
* @param newLocation The fox's new location.
*/
private void setLocation(Location newLocation)
{
if(location != null) {
field.clear(location);
}
location = newLocation;
field.place(this, newLocation);
}
/**
* Increase the age. This could result in the fox's death.
*/
private void incrementAge()
{
age++;
if(age > MAX_AGE) {
setDead();
}
}
/**
* Make this fox more hungry. This could result in the fox's death.
*/
private void incrementHunger()
{
foodLevel--;
if(foodLevel <= 0) {
setDead();
}
}
/**
* Tell the fox to look for rabbits adjacent to its current location.
* Only the first live rabbit is eaten.
* @param location Where in the field it is located.
* @return Where food was found, or null if it wasn't.
*/
private Location findFood(Location location)
{
List<Location> adjacent = field.adjacentLocations(location);
Iterator<Location> it = adjacent.iterator();
while(it.hasNext()) {
Location where = it.next();
Object animal = field.getObjectAt(where);
if(animal instanceof Rabbit) {
Rabbit rabbit = (Rabbit) animal;
if(rabbit.isAlive()) {
rabbit.setDead();
foodLevel = RABBIT_FOOD_VALUE;
// Remove the dead rabbit from the field.
return where;
}
}
}
return null;
}
/**
* Check whether or not this fox is to give birth at this step.
* New births will be made into free adjacent locations.
* @param newFoxes A list to add newly born foxes to.
*/
private void giveBirth(List<Fox> newFoxes)
{
// New foxes are born into adjacent locations.
// Get a list of adjacent free locations.
List<Location> free = field.getFreeAdjacentLocations(location);
int births = breed();
for(int b = 0; b < births && free.size() > 0; b++) {
Location loc = free.remove(0);
Fox young = new Fox(false, field, loc);
newFoxes.add(young);
}
}
/**
* Generate a number representing the number of births,
* if it can breed.
* @return The number of births (may be zero).
*/
private int breed()
{
int births = 0;
if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {
births = rand.nextInt(MAX_LITTER_SIZE) + 1;
}
return births;
}
/**
* A fox can breed if it has reached the breeding age.
*/
private boolean canBreed()
{
return age >= BREEDING_AGE;
}
/**
* Indicate that the fox is no longer alive.
* It is removed from the field.
*/
private void setDead()
{
alive = false;
if(location != null) {
field.clear(location);
location = null;
field = null;
}
}
}
Simulator
import java.util.List;
import java.util.Iterator;
import java.util.Random;
/**
* A simple model of a fox.
* Foxes age, move, eat rabbits, and die.
*
* @author David J. Barnes and Michael Kolling
* @version 2008.03.30
*/
public class Fox
{
// Characteristics shared by all foxes (static fields).
// The age at which a fox can start to breed.
private static final int BREEDING_AGE = 10;
// The age to which a fox can live.
private static final int MAX_AGE = 150;
// The likelihood of a fox breeding.
private static final double BREEDING_PROBABILITY = 0.35;
// The maximum number of births.
private static final int MAX_LITTER_SIZE = 5;
// The food value of a single rabbit. In effect, this is the
// number of steps a fox can go before it has to eat again.
private static final int RABBIT_FOOD_VALUE = 7;
// A shared random number generator to control breeding.
private static final Random rand = Randomizer.getRandom();
// Individual characteristics (instance fields).
// The fox's age.
private int age;
// Whether the fox is alive or not.
private boolean alive;
// The fox's position.
private Location location;
// The field occupied.
private Field field;
// The fox's food level, which is increased by eating rabbits.
private int foodLevel;
/**
* Create a fox. A fox can be created as a new born (age zero
* and not hungry) or with a random age and food level.
*
* @param randomAge If true, the fox will have random age and hunger level.
* @param field The field currently occupied.
* @param location The location within the field.
*/
public Fox(boolean randomAge, Field field, Location location)
{
age = 0;
alive = true;
this.field = field;
setLocation(location);
if(randomAge) {
age = rand.nextInt(MAX_AGE);
foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);
}
else {
// leave age at 0
foodLevel = RABBIT_FOOD_VALUE;
}
}
/**
* This is what the fox does most of the time: it hunts for
* rabbits. In the process, it might breed, die of hunger,
* or die of old age.
* @param field The field currently occupied.
* @param newFoxes A list to add newly born foxes to.
*/
public void hunt(List<Fox> newFoxes)
{
incrementAge();
incrementHunger();
if(alive) {
giveBirth(newFoxes);
// Move towards a source of food if found.
Location newLocation = findFood(location);
if(newLocation == null) {
// No food found - try to move to a free location.
newLocation = field.freeAdjacentLocation(location);
}
// See if it was possible to move.
if(newLocation != null) {
setLocation(newLocation);
}
else {
// Overcrowding.
setDead();
}
}
}
/**
* Check whether the fox is alive or not.
* @return True if the fox is still alive.
*/
public boolean isAlive()
{
return alive;
}
/**
* Return the fox's location.
* @return The fox's location.
*/
public Location getLocation()
{
return location;
}
/**
* Place the fox at the new location in the given field.
* @param newLocation The fox's new location.
*/
private void setLocation(Location newLocation)
{
if(location != null) {
field.clear(location);
}
location = newLocation;
field.place(this, newLocation);
}
/**
* Increase the age. This could result in the fox's death.
*/
private void incrementAge()
{
age++;
if(age > MAX_AGE) {
setDead();
}
}
/**
* Make this fox more hungry. This could result in the fox's death.
*/
private void incrementHunger()
{
foodLevel--;
if(foodLevel <= 0) {
setDead();
}
}
/**
* Tell the fox to look for rabbits adjacent to its current location.
* Only the first live rabbit is eaten.
* @param location Where in the field it is located.
* @return Where food was found, or null if it wasn't.
*/
private Location findFood(Location location)
{
List<Location> adjacent = field.adjacentLocations(location);
Iterator<Location> it = adjacent.iterator();
while(it.hasNext()) {
Location where = it.next();
Object animal = field.getObjectAt(where);
if(animal instanceof Rabbit) {
Rabbit rabbit = (Rabbit) animal;
if(rabbit.isAlive()) {
rabbit.setDead();
foodLevel = RABBIT_FOOD_VALUE;
// Remove the dead rabbit from the field.
return where;
}
}
}
return null;
}
/**
* Check whether or not this fox is to give birth at this step.
* New births will be made into free adjacent locations.
* @param newFoxes A list to add newly born foxes to.
*/
private void giveBirth(List<Fox> newFoxes)
{
// New foxes are born into adjacent locations.
// Get a list of adjacent free locations.
List<Location> free = field.getFreeAdjacentLocations(location);
int births = breed();
for(int b = 0; b < births && free.size() > 0; b++) {
Location loc = free.remove(0);
Fox young = new Fox(false, field, loc);
newFoxes.add(young);
}
}
/**
* Generate a number representing the number of births,
* if it can breed.
* @return The number of births (may be zero).
*/
private int breed()
{
int births = 0;
if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {
births = rand.nextInt(MAX_LITTER_SIZE) + 1;
}
return births;
}
/**
* A fox can breed if it has reached the breeding age.
*/
private boolean canBreed()
{
return age >= BREEDING_AGE;
}
/**
* Indicate that the fox is no longer alive.
* It is removed from the field.
*/
private void setDead()
{
alive = false;
if(location != null) {
field.clear(location);
location = null;
field = null;
}
}
}
Komentar
Posting Komentar