Langsung ke konten utama

Tugas 7 PBO: Fox & Rabbit Simulator

Class Location:

 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;  
   }  
 }  

Class 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;  
   }  
 }  

Class FieldStats:

 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;  
   }  
 }  

Class 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);  
     }  
   }  
 }  

Class 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;  
   }  
 }  

Class 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;  
   }  
 }  

Class 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;  
     }  
   }  
 }  

Class 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);  
         }  
       }  
     }  
   }  
 }  

Class SimulatorView:

 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);  
         }  
       }  
     }  
   }  
 }  

Screenshot:



Komentar

Postingan populer dari blog ini

EAS PBO: ImageEditor

Sore.... kali ini mimin mau menampilkan hasil EAS mimin. Kali ini mimin mau membuat aplikasi bernama ImageEditor. Dimana aplikasi ini dapat mengedit gambar secara sederhana. Untuk link soal:  http://fajarbaskoro.blogspot.com/2018/12/evaluasi-akhir-semester-pbo-2018.html 1. Rancangan Interface. Sederhana saja, mirip dengan yang ini: Hanya saja, untuk fungsi tambahannya ditaruh ditoolbar samping kiri dan dibawah fungsi resize (Smaller dan Larger) 2. Class diagram dari mimin: Penjelasan: ImageViewer: Bagian kelas utama untuk aplikasi editor gambar, GUI dari aplikasi, Inisialisasi semua komponen, dan untuk memulai aplikasi (atau bisa disebut juga dengan class Main) ImageFileManager: Untuk memuat dan menyimpan gambar ImagePanel: Komponen swing yang dapat menampilkan class OFImage OFImage: Kelas yang mendefinisikan gambar dalam format OF (Object First) Filter: Kelas Abstrak untuk menjalankan semua filter yang ada didalam program EdgeFilter: Membuat filter efek edge Fis

Tugas 1 APSI: System Request

System Request  Project Name: Rental Motor dan Mobil Matic “Blablabla” Project Sponsor:   Mr. X, Surabaya Business Need:   Untuk membuat penyewaan mobil yang harganya bisa terjangkau dan tentunya efektif untuk masyarakat yang ingin berpergian dengan mobil namun masyarakat tersebut tidak mau direpotkan dengan biaya perawatan mobil atau rumahnya yang tidak mendukung karena ketiadaan garasi.  Selain itu karena memang di kota tempat letak penyewaan kendaraan ini terdapat banyak wisata, dan kebanyakan orang-orang ingin menyewa mobil atau motor untuk bepergian ke wisata-wisata tersebut. Sedangkan mereka tidak memiliki kendaraan entah karena mereka berasal dari luar kota (ke kota ini untuk rekreasi dan menaiki angkutan umum) atau memang karena mereka benar-benar tidak memiliki kendaraan. Mengapa kita pilih Motor dan Mobil Matic? Dikarenakan pada saat ini lumayan sulit untuk mencari penyewaan motor matic (scooter) dan mobil yang bertransmisi otomatis namun dengan harg