Selasa, 27 November 2018

PBO-A Fox and Rabbit

Pada kesempatan kali ini saya diberikann tuga membuat program simulasi fox and rabbit

Berikut source codenya :
1. Fox
 import java.util.List;   
  import java.util.Iterator;   
  import java.util.Random;   
  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;   
    }   
   }   
  }   

2.Rabbit
 import java.util.List;   
  import java.util.Random;   
  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;   
   }   
  }   

3. Fieldstat
 import java.awt.Color;   
  import java.util.HashMap;   
  public class FieldStats   
  {    
   private HashMap<Class, Counter> counters;   
   private boolean countsValid;   
   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;   
   }   
  }   

4. field
 import java.util.Collections;   
  import java.util.Iterator;   
  import java.util.LinkedList;   
  import java.util.List;   
  import java.util.Random;   
  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;   
   }   
  }   

5. Locationa
 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;   
   }   
  }   

6. Randomizer
 import java.util.Random;   
  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);   
    }   
   }   
  }   

7. Counter
 import java.awt.Color;   
  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;   
   }   
  }   

8. Simulator
 import java.util.Random;   
  import java.util.List;   
  import java.util.ArrayList;   
  import java.util.Iterator;   
  import java.awt.Color;   
  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);   
      }   
     }   
    }   
   }   
  }   

9. Simulator view
  import java.awt.*;   
  import java.awt.event.*;   
  import javax.swing.*;   
  import java.util.LinkedHashMap;   
  import java.util.Map;   
  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);   
      }   
     }   
    }   
   }   
  }   

Berikut adalah hasil simulasinya

1. start

2. 1 step

3. 100 step

Tidak ada komentar:

Posting Komentar