Fox & Rabbit

Pada kesempatan kali ini saya akan membuat sebuah aplikasi bernama Fox & Rabbit. Fox & Rabbit membutuhkan 8 Class. 8 Class tersebut adalah Simulator, SimulatorView, Location, Field, FieldStats, Fox, Rabbit, Counter, dan Ramdomizer. Dibawah ini merupakan foto dari class :
Untuk lebih lengkapnya silahkan melihat source code saya dibawah ini :

1. Class Simulator
 /**  
  * Write a description of class Simulator here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 import java.util.Random;   
 import java.util.List;   
 import java.util.ArrayList;   
 import java.util.Iterator;   
 import java.awt.Color;   
 public class Simulator   
 {   
  // Constants representing configuration information for the simulation.   
  // The default width for the grid.   
  private static final int DEFAULT_WIDTH = 50;   
  // The default depth of the grid.   
  private static final int DEFAULT_DEPTH = 50;   
  // The probability that a fox will be created in any given grid position.   
  private static final double FOX_CREATION_PROBABILITY = 0.02;   
  // The probability that a rabbit will be created in any given grid position.   
  private static final double RABBIT_CREATION_PROBABILITY = 0.08;    
  // Lists of animals in the field. Separate lists are kept for ease of iteration.   
  private List<Rabbit> rabbits;   
  private List<Fox> foxes;   
  // The current state of the field.   
  private Field field;   
  // The current step of the simulation.   
  private int step;   
  // A graphical view of the simulation.   
  private SimulatorView view;   
  /**   
   * Construct a simulation field with default size.   
   */   
  public Simulator()   
  {this(DEFAULT_DEPTH, DEFAULT_WIDTH);}   
  /**   
   * Create a simulation field with the given size.   
   * @param depth Depth of the field. Must be greater than zero.   
   * @param width Width of the field. Must be greater than zero.   
   */   
  public Simulator(int depth, int width)   
  {   
   if(width <= 0 || depth <= 0) {   
    System.out.println("The dimensions must be greater than zero.");   
    System.out.println("Using default values.");   
    depth = DEFAULT_DEPTH;   
    width = DEFAULT_WIDTH;   
   }   
   rabbits = new ArrayList<Rabbit>();   
   foxes = new ArrayList<Fox>();   
   field = new Field(depth, width);   
   // Create a view of the state of each location in the field.   
   view = new SimulatorView(depth, width);   
   view.setColor(Rabbit.class, Color.orange);   
   view.setColor(Fox.class, Color.blue);   
   // Setup a valid starting point.   
   reset();   
  }   
  /**   
   * Run the simulation from its current state for a reasonably long period,   
   * e.g. 500 steps.   
   */   
  public void runLongSimulation()   
  {simulate(500);}   
  /**   
   * Run the simulation from its current state for the given number of steps.   
   * Stop before the given number of steps if it ceases to be viable.   
   * @param numSteps The number of steps to run for.   
   */   
  public void simulate(int numSteps)   
  {   
   for(int step = 1; step <= numSteps && view.isViable(field); step++)   
   {simulateOneStep();}   
  }   
  /**   
   * Run the simulation from its current state for a single step.   
   * Iterate over the whole field updating the state of each   
   * fox and rabbit.   
   */   
  public void simulateOneStep()   
  {   
   step++;   
   // Provide space for newborn rabbits.   
   List<Rabbit> newRabbits = new ArrayList<Rabbit>();     
   // Let all rabbits act.   
   for(Iterator<Rabbit> it = rabbits.iterator(); it.hasNext(); ) {   
    Rabbit rabbit = it.next();   
    rabbit.run(newRabbits);   
    if(! rabbit.isAlive())   
    {it.remove();}   
   }   
   // Provide space for newborn foxes.   
   List<Fox> newFoxes = new ArrayList<Fox>();     
   // Let all foxes act.   
   for(Iterator<Fox> it = foxes.iterator(); it.hasNext(); ) {   
    Fox fox = it.next();   
    fox.hunt(newFoxes);   
    if(! fox.isAlive())   
    {it.remove();}   
   }   
   // Add the newly born foxes and rabbits to the main lists.   
   rabbits.addAll(newRabbits);   
   foxes.addAll(newFoxes);   
   view.showStatus(step, field);   
  }   
  /**   
   * Reset the simulation to a starting position.   
   */   
  public void reset()   
  {   
   step = 0;   
   rabbits.clear();   
   foxes.clear();   
   populate();   
   // Show the starting state in the view.   
   view.showStatus(step, field);   
  }   
  /**   
   * Randomly populate the field with foxes and rabbits.   
   */   
  private void populate()   
  {   
   Random rand = Randomizer.getRandom();   
   field.clear();   
   for(int row = 0; row < field.getDepth(); row++) {   
    for(int col = 0; col < field.getWidth(); col++) {   
     if(rand.nextDouble() <= FOX_CREATION_PROBABILITY) {   
      Location location = new Location(row, col);   
      Fox fox = new Fox(true, field, location);   
      foxes.add(fox);   
     }   
     else if(rand.nextDouble() <= RABBIT_CREATION_PROBABILITY) {   
      Location location = new Location(row, col);   
      Rabbit rabbit = new Rabbit(true, field, location);   
      rabbits.add(rabbit);   
     }   
     // else leave the location empty.   
    }   
   }   
  }   
 }   
2. Class SimulatorView
 /**  
  * Write a description of class SimulatorView here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 import java.awt.*;   
 import java.awt.event.*;   
 import javax.swing.*;   
 import java.util.LinkedHashMap;   
 import java.util.Map;   
 /**   
  * A graphical view of the simulation grid.   
  * The view displays a colored rectangle for each location    
  * representing its contents. It uses a default background color.   
  * Colors for each type of species can be defined using the   
  * setColor method.   
  *    
  *    
  * @author VYP   
  */   
 public class SimulatorView extends JFrame   
 {   
  // Colors used for empty locations.   
  private static final Color EMPTY_COLOR = Color.white;   
  // Color used for objects that have no defined color.   
  private static final Color UNKNOWN_COLOR = Color.gray;   
  private final String STEP_PREFIX = "Step: ";   
  private final String POPULATION_PREFIX = "Population: ";   
  private JLabel stepLabel, population;   
  private FieldView fieldView;   
  // A map for storing colors for participants in the simulation   
  private Map<Class, Color> colors;   
  // A statistics object computing and storing simulation information   
  private FieldStats stats;   
  /**   
   * Create a view of the given width and height.   
   * @param height The simulation's height.   
   * @param width The simulation's width.   
   */   
  public SimulatorView(int height, int width)   
  {   
   stats = new FieldStats();   
   colors = new LinkedHashMap<Class, Color>();   
   setTitle("Fox and Rabbit Simulation");   
   stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);   
   population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);   
   setLocation(100, 50);   
   fieldView = new FieldView(height, width);   
   Container contents = getContentPane();   
   contents.add(stepLabel, BorderLayout.NORTH);   
   contents.add(fieldView, BorderLayout.CENTER);   
   contents.add(population, BorderLayout.SOUTH);   
   pack();   
   setVisible(true);   
  }   
  /**   
   * Define a color to be used for a given class of animal.   
   * @param animalClass The animal's Class object.   
   * @param color The color to be used for the given class.   
   */   
  public void setColor(Class animalClass, Color color)   
  {colors.put(animalClass, color);}   
  /**   
   * @return The color to be used for a given class of animal.   
   */   
  private Color getColor(Class animalClass)   
  {   
   Color col = colors.get(animalClass);   
   if(col == null)   
   {return UNKNOWN_COLOR;} // no color defined for this class   
   else   
   {return col;}   
  }   
  /**   
   * Show the current status of the field.   
   * @param step Which iteration step it is.   
   * @param field The field whose status is to be displayed.   
   */   
  public void showStatus(int step, Field field)   
  {   
   if(!isVisible())   
   {setVisible(true);}   
   stepLabel.setText(STEP_PREFIX + step);   
   stats.reset();   
   fieldView.preparePaint();   
   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) {   
      stats.incrementCount(animal.getClass());   
      fieldView.drawMark(col, row, getColor(animal.getClass()));   
     }   
     else   
     {fieldView.drawMark(col, row, EMPTY_COLOR);}   
    }   
   }   
   stats.countFinished();   
   population.setText(POPULATION_PREFIX + stats.getPopulationDetails(field));   
   fieldView.repaint();   
  }   
  /**   
   * Determine whether the simulation should continue to run.   
   * @return true If there is more than one species alive.   
   */   
  public boolean isViable(Field field)   
  {return stats.isViable(field);}   
  /**   
   * Provide a graphical view of a rectangular field. This is    
   * a nested class (a class defined inside a class) which   
   * defines a custom component for the user interface. This   
   * component displays the field.   
   * This is rather advanced GUI stuff - you can ignore this    
   * for your project if you like.   
   */   
  private class FieldView extends JPanel   
  {   
   private final int GRID_VIEW_SCALING_FACTOR = 6;   
   private int gridWidth, gridHeight;   
   private int xScale, yScale;   
   Dimension size;   
   private Graphics g;   
   private Image fieldImage;   
   /**   
    * Create a new FieldView component.   
    */   
   public FieldView(int height, int width)   
   {   
    gridHeight = height;   
    gridWidth = width;   
    size = new Dimension(0, 0);   
   }   
   /**   
    * Tell the GUI manager how big we would like to be.   
    */   
   public Dimension getPreferredSize()   
   {   
    return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,   
          gridHeight * GRID_VIEW_SCALING_FACTOR);   
   }   
   /**   
    * Prepare for a new round of painting. Since the component   
    * may be resized, compute the scaling factor again.   
    */   
   public void preparePaint()   
   {   
    if(! size.equals(getSize())) { // if the size has changed...   
     size = getSize();   
     fieldImage = fieldView.createImage(size.width, size.height);   
     g = fieldImage.getGraphics();   
     xScale = size.width / gridWidth;   
     if(xScale < 1)   
     {xScale = GRID_VIEW_SCALING_FACTOR;}   
     yScale = size.height / gridHeight;   
     if(yScale < 1)   
     {yScale = GRID_VIEW_SCALING_FACTOR;}   
    }   
   }   
   /**   
    * Paint on grid location on this field in a given color.   
    */   
   public void drawMark(int x, int y, Color color)   
   {   
    g.setColor(color);   
    g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);   
   }   
   /**   
    * The field view component needs to be redisplayed. Copy the   
    * internal image to screen.   
    */   
   public void paintComponent(Graphics g)   
   {   
    if(fieldImage != null) {   
     Dimension currentSize = getSize();   
     if(size.equals(currentSize))  
     {g.drawImage(fieldImage, 0, 0, null);}   
     else   
     {g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);} // Rescale the previous image.   
    }   
   }   
  }   
 }   
3. Class Location
 /**  
  * Write a description of class Location here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 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;}   
 }   
4. Class Field
 /**  
  * Write a description of class Field here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 import java.util.Collections;   
 import java.util.Iterator;   
 import java.util.LinkedList;   
 import java.util.List;   
 import java.util.Random;   
 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;}   
 }   
5. FieldStats
 /**  
  * Write a description of class FieldStats here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 import java.awt.Color;   
 import java.util.HashMap;   
 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;   
  }   
 }   
6. Class Rabbit
 /**  
  * Write a description of class Rabbit here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 import java.util.List;   
 import java.util.Random;   
 /**   
  * A simple model of a rabbit.   
  * Rabbits age, move, breed, and die.   
  *    
  * @author VYP   
  */   
  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   
    {setDead();}  // Overcrowding.   
   }    
  }    
  /**    
   * 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;}    
  }    
7. Class Fox
 /**  
  * Write a description of class Fox here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 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 VYP   
  */   
 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   
   {foodLevel = RABBIT_FOOD_VALUE;}  // leave age at 0   
  }   
  /**   
   * 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  
    {setDead();} // Overcrowding.    
   }   
  }   
  /**   
   * 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;   
   }   
  }   
 }   
8. Class Counter
 /**  
  * Write a description of class Counter here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 import java.awt.Color;   
 /**   
  * Provide a counter for a participant in the simulation.   
  * This includes an identifying string and a count of how   
  * many participants of this type currently exist within    
  * the simulation.   
  * *    
  * @author VYP   
  */   
 public class Counter   
 {   
  // A name for this type of simulation participant   
  private String name;   
  // How many of this type exist in the simulation.   
  private int count;   
  /**   
   * Provide a name for one of the simulation types.   
   * @param name A name, e.g. "Fox".   
   */   
  public Counter(String name)   
  {  
   this.name = name;   
   count = 0;   
  }   
  /**   
   * @return The short description of this type.   
   */   
  public String getName()   
  {return name;}   
  /**   
   * @return The current count for this type.   
   */   
   public int getCount()   
   {   
    return count;   
   }   
  /**   
   * Increment the current count by one.   
   */   
  public void increment()   
  {count++;}   
  /**   
   * Reset the current count to zero.   
   */   
  public void reset()   
  {count = 0;}   
 }   
9. Class Randomizer
 /**  
  * Write a description of class Randomizer here.  
  *  
  * @author M Thalut Nadhil Q  
  * @version 19 November 2019  
  */  
 import java.util.Random;  
 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);}   
  }   
 }   
Dibawah ini merupakan hasil outputnya :
Lalu kita jalankan fungsi void runLong, Maka hasilnya akan seperti dibawah ini :

Komentar

Postingan populer dari blog ini

UTS PBKK A

Tugas 2 PBKK