Foxes and rabbit

Jadi pada postingan saya ini akan membahas project Foxes and Rabbits, yang merupakan simulasi antara predator dan mangsa. pada bahasan kali ini Foxes berperan sebagai pradator dan rabbits sebgai mangsa. Pertama-tama kita lihat skema Classnya sebagai berikut :
1. Fox
1:  import java.util.List;  
2:  import java.util.Iterator;  
3:  import java.util.Random;  
4:  /**  
5:   * @author Annas  
6:   * @version 20181119  
7:   */  
8:  public class Fox  
9:  {  
10:    // Characteristics shared by all foxes (static fields).  
11:    // The age at which a fox can start to breed.  
12:    private static final int BREEDING_AGE = 10;  
13:    // The age to which a fox can live.  
14:    private static final int MAX_AGE = 150;  
15:    // The likelihood of a fox breeding.  
16:    private static final double BREEDING_PROBABILITY = 0.35;  
17:    // The maximum number of births.  
18:    private static final int MAX_LITTER_SIZE = 5;  
19:    // The food value of a single rabbit. In effect, this is the  
20:    // number of steps a fox can go before it has to eat again.  
21:    private static final int RABBIT_FOOD_VALUE = 7;  
22:    // A shared random number generator to control breeding.  
23:    private static final Random rand = Randomizer.getRandom();  
24:    // Individual characteristics (instance fields).  
25:    // The fox's age.  
26:    private int age;  
27:    // Whether the fox is alive or not.  
28:    private boolean alive;  
29:    // The fox's position.  
30:    private Location location;  
31:    // The field occupied.  
32:    private Field field;  
33:    // The fox's food level, which is increased by eating rabbits.  
34:    private int foodLevel;  
35:    public Fox(boolean randomAge, Field field, Location location)  
36:    {  
37:      age = 0;  
38:      alive = true;  
39:      this.field = field;  
40:      setLocation(location);  
41:      if(randomAge) {  
42:        age = rand.nextInt(MAX_AGE);  
43:        foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);  
44:      }  
45:      else {  
46:        // leave age at 0  
47:        foodLevel = RABBIT_FOOD_VALUE;  
48:      }  
49:    }  
50:    public void hunt(List<Fox> newFoxes)  
51:    {  
52:      incrementAge();  
53:      incrementHunger();  
54:      if(alive) {  
55:        giveBirth(newFoxes);        
56:        // Move towards a source of food if found.  
57:        Location newLocation = findFood(location);  
58:        if(newLocation == null) {   
59:          // No food found - try to move to a free location.  
60:          newLocation = field.freeAdjacentLocation(location);  
61:        }  
62:        // See if it was possible to move.  
63:        if(newLocation != null) {  
64:          setLocation(newLocation);  
65:        }  
66:        else {  
67:          // Overcrowding.  
68:          setDead();  
69:        }  
70:      }  
71:    }  
72:    public boolean isAlive()  
73:    {  
74:      return alive;  
75:    }  
76:    public Location getLocation()  
77:    {  
78:      return location;  
79:    }  
80:    private void setLocation(Location newLocation)  
81:    {  
82:      if(location != null) {  
83:        field.clear(location);  
84:      }  
85:      location = newLocation;  
86:      field.place(this, newLocation);  
87:    }  
88:    private void incrementAge()  
89:    {  
90:      age++;  
91:      if(age > MAX_AGE) {  
92:        setDead();  
93:      }  
94:    }  
95:    private void incrementHunger()  
96:    {  
97:      foodLevel--;  
98:      if(foodLevel <= 0) {  
99:        setDead();  
100:      }  
101:    }  
102:    private Location findFood(Location location)  
103:    {  
104:      List<Location> adjacent = field.adjacentLocations(location);  
105:      Iterator<Location> it = adjacent.iterator();  
106:      while(it.hasNext()) {  
107:        Location where = it.next();  
108:        Object animal = field.getObjectAt(where);  
109:        if(animal instanceof Rabbit) {  
110:          Rabbit rabbit = (Rabbit) animal;  
111:          if(rabbit.isAlive()) {   
112:            rabbit.setDead();  
113:            foodLevel = RABBIT_FOOD_VALUE;  
114:            // Remove the dead rabbit from the field.  
115:            return where;  
116:          }  
117:        }  
118:      }  
119:      return null;  
120:    }  
121:    private void giveBirth(List<Fox> newFoxes)  
122:    {  
123:      // New foxes are born into adjacent locations.  
124:      // Get a list of adjacent free locations.  
125:      List<Location> free = field.getFreeAdjacentLocations(location);  
126:      int births = breed();  
127:      for(int b = 0; b < births && free.size() > 0; b++) {  
128:        Location loc = free.remove(0);  
129:        Fox young = new Fox(false, field, loc);  
130:        newFoxes.add(young);  
131:      }  
132:    }  
133:    private int breed()  
134:    {  
135:      int births = 0;  
136:      if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {  
137:        births = rand.nextInt(MAX_LITTER_SIZE) + 1;  
138:      }  
139:      return births;  
140:    }  
141:    private boolean canBreed()  
142:    {  
143:      return age >= BREEDING_AGE;  
144:    }  
145:    private void setDead()  
146:    {  
147:      alive = false;  
148:      if(location != null) {  
149:        field.clear(location);  
150:        location = null;  
151:        field = null;  
152:      }  
153:    }  
154:  }  
2. Rabbit
1:  import java.util.List;  
2:  import java.util.Random;  
3:  /**  
4:   *   
5:   * @author Annas  
6:   * @version 20181119  
7:   */  
8:  public class Rabbit  
9:  {  
10:    // Characteristics shared by all rabbits (static fields).  
11:    // The age at which a rabbit can start to breed.  
12:    private static final int BREEDING_AGE = 5;  
13:    // The age to which a rabbit can live.  
14:    private static final int MAX_AGE = 40;  
15:    // The likelihood of a rabbit breeding.  
16:    private static final double BREEDING_PROBABILITY = 0.15;  
17:    // The maximum number of births.  
18:    private static final int MAX_LITTER_SIZE = 4;  
19:    // A shared random number generator to control breeding.  
20:    private static final Random rand = Randomizer.getRandom();  
21:    // Individual characteristics (instance fields).  
22:    // The rabbit's age.  
23:    private int age;  
24:    // Whether the rabbit is alive or not.  
25:    private boolean alive;  
26:    // The rabbit's position.  
27:    private Location location;  
28:    // The field occupied.  
29:    private Field field;  
30:    public Rabbit(boolean randomAge, Field field, Location location)  
31:    {  
32:      age = 0;  
33:      alive = true;  
34:      this.field = field;  
35:      setLocation(location);  
36:      if(randomAge) {  
37:        age = rand.nextInt(MAX_AGE);  
38:      }  
39:    }  
40:    public void run(List<Rabbit> newRabbits)  
41:    {  
42:      incrementAge();  
43:      if(alive) {  
44:        giveBirth(newRabbits);        
45:        // Try to move into a free location.  
46:        Location newLocation = field.freeAdjacentLocation(location);  
47:        if(newLocation != null) {  
48:          setLocation(newLocation);  
49:        }  
50:        else {  
51:          // Overcrowding.  
52:          setDead();  
53:        }  
54:      }  
55:    }  
56:    public boolean isAlive()  
57:    {  
58:      return alive;  
59:    }  
60:    public void setDead()  
61:    {  
62:      alive = false;  
63:      if(location != null) {  
64:        field.clear(location);  
65:        location = null;  
66:        field = null;  
67:      }  
68:    }  
69:    public Location getLocation()  
70:    {  
71:      return location;  
72:    }  
73:    private void setLocation(Location newLocation)  
74:    {  
75:      if(location != null) {  
76:        field.clear(location);  
77:      }  
78:      location = newLocation;  
79:      field.place(this, newLocation);  
80:    }  
81:    private void incrementAge()  
82:    {  
83:      age++;  
84:      if(age > MAX_AGE) {  
85:        setDead();  
86:      }  
87:    }  
88:    private void giveBirth(List<Rabbit> newRabbits)  
89:    {  
90:      // New rabbits are born into adjacent locations.  
91:      // Get a list of adjacent free locations.  
92:      List<Location> free = field.getFreeAdjacentLocations(location);  
93:      int births = breed();  
94:      for(int b = 0; b < births && free.size() > 0; b++) {  
95:        Location loc = free.remove(0);  
96:        Rabbit young = new Rabbit(false, field, loc);  
97:        newRabbits.add(young);  
98:      }  
99:    }  
100:    private int breed()  
101:    {  
102:      int births = 0;  
103:      if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {  
104:        births = rand.nextInt(MAX_LITTER_SIZE) + 1;  
105:      }  
106:      return births;  
107:    }  
108:    private boolean canBreed()  
109:    {  
110:      return age >= BREEDING_AGE;  
111:    }  
112:  }  
3. Field
1:  import java.util.Collections;  
2:  import java.util.Iterator;  
3:  import java.util.LinkedList;  
4:  import java.util.List;  
5:  import java.util.Random;  
6:  /**  
7:   *   
8:   * @author Annas   
9:   * @version 20181119  
10:   */  
11:  public class Field  
12:  {  
13:    private static final Random rand = Randomizer.getRandom();  
14:    private int depth, width;  
15:    private Object[][] field;  
16:    public Field(int depth, int width)  
17:    {  
18:      this.depth = depth;  
19:      this.width = width;  
20:      field = new Object[depth][width];  
21:    }  
22:    public void clear()  
23:    {  
24:      for(int row = 0; row < depth; row++) {  
25:        for(int col = 0; col < width; col++) {  
26:          field[row][col] = null;  
27:        }  
28:      }  
29:    }  
30:    public void clear(Location location)  
31:    {  
32:      field[location.getRow()][location.getCol()] = null;  
33:    }  
34:    public void place(Object animal, int row, int col)  
35:    {  
36:      place(animal, new Location(row, col));  
37:    }  
38:    public void place(Object animal, Location location)  
39:    {  
40:      field[location.getRow()][location.getCol()] = animal;  
41:    }  
42:    public Object getObjectAt(Location location)  
43:    {  
44:      return getObjectAt(location.getRow(), location.getCol());  
45:    }  
46:    public Object getObjectAt(int row, int col)  
47:    {  
48:      return field[row][col];  
49:    }  
50:    public Location randomAdjacentLocation(Location location)  
51:    {  
52:      List<Location> adjacent = adjacentLocations(location);  
53:      return adjacent.get(0);  
54:    }  
55:    public List<Location> getFreeAdjacentLocations(Location location)  
56:    {  
57:      List<Location> free = new LinkedList<Location>();  
58:      List<Location> adjacent = adjacentLocations(location);  
59:      for(Location next : adjacent) {  
60:        if(getObjectAt(next) == null) {  
61:          free.add(next);  
62:        }  
63:      }  
64:      return free;  
65:    }  
66:    public Location freeAdjacentLocation(Location location)  
67:    {  
68:      // The available free ones.  
69:      List<Location> free = getFreeAdjacentLocations(location);  
70:      if(free.size() > 0) {  
71:        return free.get(0);  
72:      }  
73:      else {  
74:        return null;  
75:      }  
76:    }  
77:    public List<Location> adjacentLocations(Location location)  
78:    {  
79:      assert location != null : "Null location passed to adjacentLocations";  
80:      // The list of locations to be returned.  
81:      List<Location> locations = new LinkedList<Location>();  
82:      if(location != null) {  
83:        int row = location.getRow();  
84:        int col = location.getCol();  
85:        for(int roffset = -1; roffset <= 1; roffset++) {  
86:          int nextRow = row + roffset;  
87:          if(nextRow >= 0 && nextRow < depth) {  
88:            for(int coffset = -1; coffset <= 1; coffset++) {  
89:              int nextCol = col + coffset;  
90:              // Exclude invalid locations and the original location.  
91:              if(nextCol >= 0 && nextCol < width && (roffset != 0 || coffset != 0)) {  
92:                locations.add(new Location(nextRow, nextCol));  
93:              }  
94:            }  
95:          }  
96:        }  
97:        // Shuffle the list. Several other methods rely on the list  
98:        // being in a random order.  
99:        Collections.shuffle(locations, rand);  
100:      }  
101:      return locations;  
102:    }  
103:    public int getDepth()  
104:    {  
105:      return depth;  
106:    }  
107:    public int getWidth()  
108:    {  
109:      return width;  
110:    }  
111:  }  
4. Location
1:  /**  
2:   * @author Annas   
3:   * @version 20181119  
4:   */  
5:  public class Location  
6:  {  
7:    // Row and column positions.  
8:    private int row;  
9:    private int col;  
10:    /**  
11:     * Represent a row and column.  
12:     * @param row The row.  
13:     * @param col The column.  
14:     */  
15:    public Location(int row, int col)  
16:    {  
17:      this.row = row;  
18:      this.col = col;  
19:    }  
20:    /**  
21:     * Implement content equality.  
22:     */  
23:    public boolean equals(Object obj)  
24:    {  
25:      if(obj instanceof Location) {  
26:        Location other = (Location) obj;  
27:        return row == other.getRow() && col == other.getCol();  
28:      }  
29:      else {  
30:        return false;  
31:      }  
32:    }  
33:    /**  
34:     * Return a string of the form row,column  
35:     * @return A string representation of the location.  
36:     */  
37:    public String toString()  
38:    {  
39:      return row + "," + col;  
40:    }  
41:    /**  
42:     * Use the top 16 bits for the row value and the bottom for  
43:     * the column. Except for very big grids, this should give a  
44:     * unique hash code for each (row, col) pair.  
45:     * @return A hashcode for the location.  
46:     */  
47:    public int hashCode()  
48:    {  
49:      return (row << 16) + col;  
50:    }  
51:    /**  
52:     * @return The row.  
53:     */  
54:    public int getRow()  
55:    {  
56:      return row;  
57:    }  
58:    /**  
59:     * @return The column.  
60:     */  
61:    public int getCol()  
62:    {  
63:      return col;  
64:    }  
65:  }  
5. Counter
1:  import java.awt.Color;  
2:  /**  
3:   *   
4:   * @author Annas  
5:   * @version 20181119  
6:   */  
7:  public class Counter  
8:  {  
9:    // A name for this type of simulation participant  
10:    private String name;  
11:    // How many of this type exist in the simulation.  
12:    private int count;  
13:    public Counter(String name)  
14:    {  
15:      this.name = name;  
16:      count = 0;  
17:    }  
18:    public String getName()  
19:    {  
20:      return name;  
21:    }  
22:    public int getCount()  
23:    {  
24:      return count;  
25:    }  
26:    public void increment()  
27:    {  
28:      count++;  
29:    }  
30:    public void reset()  
31:    {  
32:      count = 0;  
33:    }  
34:  }  
6. Randomizer
1:  import java.util.Random;  
2:  /**  
3:   *   
4:   * @author Annas  
5:   * @version 20181119  
6:   */  
7:  public class Randomizer  
8:  {  
9:    // The default seed for control of randomization.  
10:    private static final int SEED = 1111;  
11:    // A shared Random object, if required.  
12:    private static final Random rand = new Random(SEED);  
13:    // Determine whether a shared random generator is to be provided.  
14:    private static final boolean useShared = true;  
15:    public Randomizer()  
16:    {  
17:    }  
18:    public static Random getRandom()  
19:    {  
20:      if(useShared) {  
21:        return rand;  
22:      }  
23:      else {  
24:        return new Random();  
25:      }  
26:    }  
27:    public static void reset()  
28:    {  
29:      if(useShared) {  
30:        rand.setSeed(SEED);  
31:      }  
32:    }  
33:  }  
7. Simulator
1:  import java.util.Random;  
2:  /**  
3:   *   
4:   * @author Annas  
5:   * @version 20181119  
6:   */  
7:  public class Randomizer  
8:  {  
9:    // The default seed for control of randomization.  
10:    private static final int SEED = 1111;  
11:    // A shared Random object, if required.  
12:    private static final Random rand = new Random(SEED);  
13:    // Determine whether a shared random generator is to be provided.  
14:    private static final boolean useShared = true;  
15:    public Randomizer()  
16:    {  
17:    }  
18:    public static Random getRandom()  
19:    {  
20:      if(useShared) {  
21:        return rand;  
22:      }  
23:      else {  
24:        return new Random();  
25:      }  
26:    }  
27:    public static void reset()  
28:    {  
29:      if(useShared) {  
30:        rand.setSeed(SEED);  
31:      }  
32:    }  
33:  }  
8. FieldStats
1:  import java.awt.Color;  
2:  import java.util.HashMap;  
3:  /**  
4:   * @author Annas Nuril Iman  
5:   * @version 20181119  
6:   */  
7:  public class FieldStats  
8:  {  
9:    private HashMap<Class, Counter> counters;  
10:    private boolean countsValid;  
11:    public FieldStats()  
12:    {  
13:      counters = new HashMap<Class, Counter>();  
14:      countsValid = true;  
15:    }  
16:    public String getPopulationDetails(Field field)  
17:    {  
18:      StringBuffer buffer = new StringBuffer();  
19:      if(!countsValid) {  
20:        generateCounts(field);  
21:      }  
22:      for(Class key : counters.keySet()) {  
23:        Counter info = counters.get(key);  
24:        buffer.append(info.getName());  
25:        buffer.append(": ");  
26:        buffer.append(info.getCount());  
27:        buffer.append(' ');  
28:      }  
29:      return buffer.toString();  
30:    }  
31:    public void reset()  
32:    {  
33:      countsValid = false;  
34:      for(Class key : counters.keySet()) {  
35:        Counter count = counters.get(key);  
36:        count.reset();  
37:      }  
38:    }  
39:    public void incrementCount(Class animalClass)  
40:    {  
41:      Counter count = counters.get(animalClass);  
42:      if(count == null) {  
43:        // We do not have a counter for this species yet.  
44:        // Create one.  
45:        count = new Counter(animalClass.getName());  
46:        counters.put(animalClass, count);  
47:      }  
48:      count.increment();  
49:    }  
50:    public void countFinished()  
51:    {  
52:      countsValid = true;  
53:    }  
54:    public boolean isViable(Field field)  
55:    {  
56:      // How many counts are non-zero.  
57:      int nonZero = 0;  
58:      if(!countsValid) {  
59:        generateCounts(field);  
60:      }  
61:      for(Class key : counters.keySet()) {  
62:        Counter info = counters.get(key);  
63:        if(info.getCount() > 0) {  
64:          nonZero++;  
65:        }  
66:      }  
67:      return nonZero > 1;  
68:    }  
69:    private void generateCounts(Field field)  
70:    {  
71:      reset();  
72:      for(int row = 0; row < field.getDepth(); row++) {  
73:        for(int col = 0; col < field.getWidth(); col++) {  
74:          Object animal = field.getObjectAt(row, col);  
75:          if(animal != null) {  
76:            incrementCount(animal.getClass());  
77:          }  
78:        }  
79:      }  
80:      countsValid = true;  
81:    }  
82:  }  
9. SimulatorView
1:  import java.awt.*;  
2:  import java.awt.event.*;  
3:  import javax.swing.*;  
4:  import java.util.LinkedHashMap;  
5:  import java.util.Map;  
6:  /**  
7:   * @author Annas  
8:   * @version 20181119  
9:   */  
10:  public class SimulatorView extends JFrame  
11:  {  
12:    // Colors used for empty locations.  
13:    private static final Color EMPTY_COLOR = Color.white;  
14:    // Color used for objects that have no defined color.  
15:    private static final Color UNKNOWN_COLOR = Color.gray;  
16:    private final String STEP_PREFIX = "Step: ";  
17:    private final String POPULATION_PREFIX = "Population: ";  
18:    private JLabel stepLabel, population;  
19:    private FieldView fieldView;  
20:    // A map for storing colors for participants in the simulation  
21:    private Map<Class, Color> colors;  
22:    // A statistics object computing and storing simulation information  
23:    private FieldStats stats;  
24:    public SimulatorView(int height, int width)  
25:    {  
26:      stats = new FieldStats();  
27:      colors = new LinkedHashMap<Class, Color>();  
28:      setTitle("Fox and Rabbit Simulation");  
29:      stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);  
30:      population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);  
31:      setLocation(100, 50);  
32:      fieldView = new FieldView(height, width);  
33:      Container contents = getContentPane();  
34:      contents.add(stepLabel, BorderLayout.NORTH);  
35:      contents.add(fieldView, BorderLayout.CENTER);  
36:      contents.add(population, BorderLayout.SOUTH);  
37:      pack();  
38:      setVisible(true);  
39:    }  
40:    public void setColor(Class animalClass, Color color)  
41:    {  
42:      colors.put(animalClass, color);  
43:    }  
44:    private Color getColor(Class animalClass)  
45:    {  
46:      Color col = colors.get(animalClass);  
47:      if(col == null) {  
48:        // no color defined for this class  
49:        return UNKNOWN_COLOR;  
50:      }  
51:      else {  
52:        return col;  
53:      }  
54:    }  
55:    public void showStatus(int step, Field field)  
56:    {  
57:      if(!isVisible()) {  
58:        setVisible(true);  
59:      }  
60:      stepLabel.setText(STEP_PREFIX + step);  
61:      stats.reset();  
62:      fieldView.preparePaint();  
63:      for(int row = 0; row < field.getDepth(); row++) {  
64:        for(int col = 0; col < field.getWidth(); col++) {  
65:          Object animal = field.getObjectAt(row, col);  
66:          if(animal != null) {  
67:            stats.incrementCount(animal.getClass());  
68:            fieldView.drawMark(col, row, getColor(animal.getClass()));  
69:          }  
70:          else {  
71:            fieldView.drawMark(col, row, EMPTY_COLOR);  
72:          }  
73:        }  
74:      }  
75:      stats.countFinished();  
76:      population.setText(POPULATION_PREFIX + stats.getPopulationDetails(field));  
77:      fieldView.repaint();  
78:    }  
79:    public boolean isViable(Field field)  
80:    {  
81:      return stats.isViable(field);  
82:    }  
83:    private class FieldView extends JPanel  
84:    {  
85:      private final int GRID_VIEW_SCALING_FACTOR = 6;  
86:      private int gridWidth, gridHeight;  
87:      private int xScale, yScale;  
88:      Dimension size;  
89:      private Graphics g;  
90:      private Image fieldImage;  
91:      public FieldView(int height, int width)  
92:      {  
93:        gridHeight = height;  
94:        gridWidth = width;  
95:        size = new Dimension(0, 0);  
96:      }  
97:      public Dimension getPreferredSize()  
98:      {  
99:        return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,  
100:                   gridHeight * GRID_VIEW_SCALING_FACTOR);  
101:      }  
102:      public void preparePaint()  
103:      {  
104:        if(! size.equals(getSize())) { // if the size has changed...  
105:          size = getSize();  
106:          fieldImage = fieldView.createImage(size.width, size.height);  
107:          g = fieldImage.getGraphics();  
108:          xScale = size.width / gridWidth;  
109:          if(xScale < 1) {  
110:            xScale = GRID_VIEW_SCALING_FACTOR;  
111:          }  
112:          yScale = size.height / gridHeight;  
113:          if(yScale < 1) {  
114:            yScale = GRID_VIEW_SCALING_FACTOR;  
115:          }  
116:        }  
117:      }  
118:      public void drawMark(int x, int y, Color color)  
119:      {  
120:        g.setColor(color);  
121:        g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);  
122:      }  
123:      public void paintComponent(Graphics g)  
124:      {  
125:        if(fieldImage != null) {  
126:          Dimension currentSize = getSize();  
127:          if(size.equals(currentSize)) {  
128:            g.drawImage(fieldImage, 0, 0, null);  
129:          }  
130:          else {  
131:            // Rescale the previous image.  
132:            g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);  
133:          }  
134:        }  
135:      }  
136:    }  
137:  }  

Berikutnya kita jalankan class Simulator


Dan hasil simulasi dengan run 500 step akan terlihat



Komentar

Postingan populer dari blog ini

Pong Java Game

EAS PBO-B

Image Viewer versi 3