TUGAS POLYMORPHISM PEMROGRAMAN BERORIENTASI OBJEK

THE FOXES AND RABBITS PROJECT


Karina Soraya P
05111740000003
PBO - B

Terdapat 9 class, yaitu :


  • Source Code Randomizer
  import java.util.Random;   
  /**   
  * @author Karina Soraya P   
  * @version 1.8/20181119   
  */   
  public class Randomizer   
  {    
   private static final int SEED = 1111;   
   private static final Random rand = new Random(SEED);    
   private static final boolean useShared = true;   
   public Randomizer()   
   {   
   }   
   public static Random getRandom()   
   {   
    if(useShared) {   
     return rand;   
    }   
    else {   
     return new Random();   
    }   
   }   
   public static void reset()   
   {   
    if(useShared) {   
     rand.setSeed(SEED);   
    }   
   }   
  }   
  • Source Code Counter
 import 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;   
   }   
  }   
  • Source Code Field Stats
 import java.awt.Color;   
  import java.util.HashMap;   
  /**   
  * @author Karina Soraya P   
  * @version 1.6/20181119   
  */   
  public class FieldStats   
  {    
   private HashMap<Class, Counter> counters;   
   private boolean countsValid;   
   /**   
   * Construct a FieldStats object.   
   */   
   public FieldStats()   
   {   
    counters = new HashMap<Class, Counter>();   
    countsValid = true;   
   }   
   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();   
   }    
   public void reset()   
   {   
    countsValid = false;   
    for(Class key : counters.keySet()) {   
     Counter count = counters.get(key);   
     count.reset();   
    }   
   }   
   public void incrementCount(Class animalClass)   
   {   
    Counter count = counters.get(animalClass);   
    if(count == null) {    
     count = new Counter(animalClass.getName());   
     counters.put(animalClass, count);   
    }   
    count.increment();   
   }   
   public void countFinished()   
   {   
    countsValid = true;   
   }    
   public boolean isViable(Field field)   
   {   
    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;   
   }   
   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;   
   }   
  }   
  • Source Code Field
  import java.util.Collections;   
  import java.util.Iterator;   
  import java.util.LinkedList;   
  import java.util.List;   
  import java.util.Random;   
  /**   
  * @author Karina Soraya P   
  * @version 1.5/20181119   
  */   
  public class Field   
  {    
   private static final Random rand = Randomizer.getRandom();   
   private int depth, width;    
   private Object[][] field;   
   public Field(int depth, int width)   
   {   
    this.depth = depth;   
    this.width = width;   
    field = new Object[depth][width];   
   }   
   public void clear()   
   {   
    for(int row = 0; row < depth; row++) {   
     for(int col = 0; col < width; col++) {   
      field[row][col] = null;   
     }   
    }   
   }   
   public void clear(Location location)   
   {   
    field[location.getRow()][location.getCol()] = null;   
   }   
   public void place(Object animal, int row, int col)   
   {   
    place(animal, new Location(row, col));   
   }    
   public void place(Object animal, Location location)   
   {   
    field[location.getRow()][location.getCol()] = animal;   
   }   
   public Object getObjectAt(Location location)   
   {   
    return getObjectAt(location.getRow(), location.getCol());   
   }    
   public Object getObjectAt(int row, int col)   
   {   
    return field[row][col];   
   }    
   public Location randomAdjacentLocation(Location location)   
   {   
    List<Location> adjacent = adjacentLocations(location);   
    return adjacent.get(0);   
   }    
   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;   
   }   
   public Location freeAdjacentLocation(Location location)   
   {    
    List<Location> free = getFreeAdjacentLocations(location);   
    if(free.size() > 0) {   
     return free.get(0);   
    }   
    else {   
     return null;   
    }   
   }   
   public List<Location> adjacentLocations(Location location)   
   {   
    assert location != null : "Null location passed to adjacentLocations";   
    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;    
        if(nextCol >= 0 && nextCol < width && (roffset != 0 || coffset != 0)) {   
         locations.add(new Location(nextRow, nextCol));   
        }   
       }   
      }   
     }   
     Collections.shuffle(locations, rand);   
    }   
    return locations;   
   }   
   public int getDepth()   
   {   
    return depth;   
   }   
   public int getWidth()   
   {   
    return width;   
   }   
  }   
  • Source Code Location
  /**   
  * @author Karina Soraya P   
  * @version 1.4/20181119   
  */   
  public class Location   
  {    
   private int row;   
   private int col;   
   public Location(int row, int col)   
   {   
    this.row = row;   
    this.col = col;   
   }    
   public boolean equals(Object obj)   
   {   
    if(obj instanceof Location) {   
     Location other = (Location) obj;   
     return row == other.getRow() && col == other.getCol();   
    }   
    else {   
     return false;   
    }   
   }    
   public String toString()   
   {   
    return row + "," + col;   
   }   
   public int hashCode()   
   {   
    return (row << 16) + col;   
   }   
   public int getRow()   
   {   
    return row;   
   }    
   public int getCol()   
   {   
    return col;   
   }   
  }   
  • Source Code Rabbit
  import java.util.List;   
  import java.util.Random;   
  /**   
  * @author Karina Soraya P   
  * @version 1.3/20181119   
  */   
  public class Rabbit   
  {   
   private static final int BREEDING_AGE = 5;   
   private static final int MAX_AGE = 40;   
   private static final double BREEDING_PROBABILITY = 0.15;   
   private static final int MAX_LITTER_SIZE = 4;    
   private static final Random rand = Randomizer.getRandom();   
   private int age;    
   private boolean alive;    
   private Location location;   
   private Field 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);   
    }   
   }    
   public void run(List<Rabbit> newRabbits)   
   {   
    incrementAge();   
    if(alive) {   
     giveBirth(newRabbits);       
     Location newLocation = field.freeAdjacentLocation(location);   
     if(newLocation != null) {   
      setLocation(newLocation);   
     }   
     else {   
      setDead();   
     }   
    }   
   }    
   public boolean isAlive()   
   {   
    return alive;   
   }    
   public void setDead()   
   {   
    alive = false;   
    if(location != null) {   
     field.clear(location);   
     location = null;   
     field = null;   
    }   
   }    
   public Location getLocation()   
   {   
    return location;   
   }    
   private void setLocation(Location newLocation)   
   {   
    if(location != null) {   
     field.clear(location);   
    }   
    location = newLocation;   
    field.place(this, newLocation);   
   }   
   private void incrementAge()   
   {   
    age++;   
    if(age > MAX_AGE) {   
     setDead();   
    }   
   }    
   private void giveBirth(List<Rabbit> newRabbits)   
   { 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);   
    }   
   }   
   private int breed()   
   {   
    int births = 0;   
    if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {   
     births = rand.nextInt(MAX_LITTER_SIZE) + 1;   
    }   
    return births;   
   }    
   private boolean canBreed()   
   {   
    return age >= BREEDING_AGE;   
   }   
  }   
  • Source Code Fox
  import java.util.List;   
  import java.util.Iterator;   
  import java.util.Random;   
  /**   
  * @author Karina Soraya P   
  * @version 1.2/20181119   
  */   
  public class Fox   
  {    
   private static final int BREEDING_AGE = 10;   
   private static final int MAX_AGE = 150;   
   private static final double BREEDING_PROBABILITY = 0.35;   
   private static final int MAX_LITTER_SIZE = 5;   
   private static final int RABBIT_FOOD_VALUE = 7;   
   private static final Random rand = Randomizer.getRandom();   
   private int age;    
   private boolean alive;   
   private Location location;   
   private Field field;    
   private int foodLevel;   
   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;   
    }   
   }   
   public void hunt(List<Fox> newFoxes)   
   {   
    incrementAge();   
    incrementHunger();   
    if(alive) {   
     giveBirth(newFoxes);       
     Location newLocation = findFood(location);   
     if(newLocation == null) {    
      newLocation = field.freeAdjacentLocation(location);   
     }   
     if(newLocation != null) {   
      setLocation(newLocation);   
     }   
     else {   
      setDead();   
     }   
    }   
   }    
   public boolean isAlive()   
   {   
    return alive;   
   }   
   public Location getLocation()   
   {   
    return location;   
   }   
   private void setLocation(Location newLocation)   
   {   
    if(location != null) {   
     field.clear(location);   
    }   
    location = newLocation;   
    field.place(this, newLocation);   
   }    
   private void incrementAge()   
   {   
    age++;   
    if(age > MAX_AGE) {   
     setDead();   
    }   
   }   
   private void incrementHunger()   
   {   
    foodLevel--;   
    if(foodLevel <= 0) {   
     setDead();   
    }   
   }    
   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;   
       return where;   
      }   
     }   
    }   
    return null;   
   }    
   private void giveBirth(List<Fox> newFoxes)   
   {    
    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);   
    }   
   }    
   private int breed()   
   {   
    int births = 0;   
    if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {   
     births = rand.nextInt(MAX_LITTER_SIZE) + 1;   
    }   
    return births;   
   }    
   private boolean canBreed()   
   {   
    return age >= BREEDING_AGE;   
   }   
   private void setDead()   
   {   
    alive = false;   
    if(location != null) {   
     field.clear(location);   
     location = null;   
     field = null;   
    }   
   }   
  }   
  • Source Code Simulator View
  import java.awt.*;   
  import java.awt.event.*;   
  import javax.swing.*;   
  import java.util.LinkedHashMap;   
  import java.util.Map;   
  /**   
  * @author Karina Soraya P   
  * @version 1.1/20181119   
  */   
  public class SimulatorView extends JFrame   
  {    
   private static final Color EMPTY_COLOR = Color.white;   
   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;   
   private Map<Class, Color> colors;    
   private FieldStats stats;   
   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);   
   }   
   public void setColor(Class animalClass, Color color)   
   {   
    colors.put(animalClass, color);   
   }   
   private Color getColor(Class animalClass)   
   {   
    Color col = colors.get(animalClass);   
    if(col == null) {   
     return UNKNOWN_COLOR;   
    }   
    else {   
     return col;   
    }   
   }    
   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();   
   }    
   public boolean isViable(Field field)   
   {   
    return stats.isViable(field);   
   }    
   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;   
    public FieldView(int height, int width)   
    {   
     gridHeight = height;   
     gridWidth = width;   
     size = new Dimension(0, 0);   
    }   
    public Dimension getPreferredSize()   
    {   
     return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,   
          gridHeight * GRID_VIEW_SCALING_FACTOR);   
    }   
    public void preparePaint()   
    {   
     if(! size.equals(getSize())) {   
      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;   
      }   
     }   
    }    
    public void drawMark(int x, int y, Color color)   
    {   
     g.setColor(color);   
     g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);   
    }    
    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);   
      }   
     }   
    }   
   }   
  }   
  • Source Code Simulator
  import java.util.Random;   
  import java.util.List;   
  import java.util.ArrayList;   
  import java.util.Iterator;   
  import java.awt.Color;   
  /**   
  * @author Karina Soraya P   
  * @version 1.0/20181119    
  */   
  public class Simulator   
  {   
   private static final int DEFAULT_WIDTH = 50;    
   private static final int DEFAULT_DEPTH = 50;   
   private static final double FOX_CREATION_PROBABILITY = 0.02;   
   private static final double RABBIT_CREATION_PROBABILITY = 0.08;     
   private List<Rabbit> rabbits;   
   private List<Fox> foxes;    
   private Field field;    
   private int step;    
   private SimulatorView view;   
   public Simulator()   
   {   
    this(DEFAULT_DEPTH, DEFAULT_WIDTH);   
   }    
   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);    
    view = new SimulatorView(depth, width);   
    view.setColor(Rabbit.class, Color.orange);   
    view.setColor(Fox.class, Color.blue);   
    reset();   
   }    
   public void runLongSimulation()   
   {   
    simulate(500);   
   }    
   public void simulate(int numSteps)   
   {   
    for(int step = 1; step <= numSteps && view.isViable(field); step++) {   
     simulateOneStep();   
    }   
   }    
   public void simulateOneStep()   
   {   
    step++;    
    List<Rabbit> newRabbits = new ArrayList<Rabbit>();   
    for(Iterator<Rabbit> it = rabbits.iterator(); it.hasNext(); ) {   
     Rabbit rabbit = it.next();   
     rabbit.run(newRabbits);   
     if(! rabbit.isAlive()) {   
      it.remove();   
     }   
    }    
    List<Fox> newFoxes = new ArrayList<Fox>();   
    for(Iterator<Fox> it = foxes.iterator(); it.hasNext(); ) {   
     Fox fox = it.next();   
     fox.hunt(newFoxes);   
     if(! fox.isAlive()) {   
      it.remove();   
     }   
    }    
    rabbits.addAll(newRabbits);   
    foxes.addAll(newFoxes);   
    view.showStatus(step, field);   
   }   
   public void reset()   
   {   
    step = 0;   
    rabbits.clear();   
    foxes.clear();   
    populate();    
    view.showStatus(step, field);   
   }    
   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);  
      }   
     }   
    }   
   }   
  }  
  • Hasil
Atur simulator dengan ukuran 30x30


Untuk Step 0 tampilannya sebagai berikut :


Ketika memilih Simulate One Step


Jika kita ingin menampilkan step yang kita inginkan, pilih Simulate dan tentukan step keberapa yang kita ingin tampilkan



Ketika memilih Run Long Simulation


Komentar

Postingan Populer