NRP : 05111740000068
Kelas : PBO - A
Pada postingan saya kali ini, saya akan membagikan hasil tugas membuat simulator Fox and Rabbits dengan Java, berikut source code beserta tampilan simulatornya.
- Source Code
- Simulator
1: import java.util.Random;
2: import java.util.List;
3: import java.util.ArrayList;
4: import java.util.Iterator;
5: import java.awt.Color;
6: /**
7: * A simple predator-prey simulator, based on a rectangular field
8: * containing rabbits and foxes.
9: *
10: * @author Haikal Almaz Said
11: * @version 19/11/2018
12: */
13: public class Simulator
14: {
15: // Constants representing configuration information for the simulation.
16: // The default width for the grid.
17: private static final int DEFAULT_WIDTH = 50;
18: // The default depth of the grid.
19: private static final int DEFAULT_DEPTH = 50;
20: // The probability that a fox will be created in any given grid position.
21: private static final double FOX_CREATION_PROBABILITY = 0.02;
22: // The probability that a rabbit will be created in any given grid position.
23: private static final double RABBIT_CREATION_PROBABILITY = 0.08;
24: // Lists of animals in the field. Separate lists are kept for ease of iteration.
25: private List<Rabbit> rabbits;
26: private List<Fox> foxes;
27: // The current state of the field.
28: private Field field;
29: // The current step of the simulation.
30: private int step;
31: // A graphical view of the simulation.
32: private SimulatorView view;
33: /**
34: * Construct a simulation field with default size.
35: */
36: public Simulator()
37: {
38: this(DEFAULT_DEPTH, DEFAULT_WIDTH);
39: }
40: /**
41: * Create a simulation field with the given size.
42: * @param depth Depth of the field. Must be greater than zero.
43: * @param width Width of the field. Must be greater than zero.
44: */
45: public Simulator(int depth, int width)
46: {
47: if(width <= 0 || depth <= 0) {
48: System.out.println("The dimensions must be greater than zero.");
49: System.out.println("Using default values.");
50: depth = DEFAULT_DEPTH;
51: width = DEFAULT_WIDTH;
52: }
53: rabbits = new ArrayList<Rabbit>();
54: foxes = new ArrayList<Fox>();
55: field = new Field(depth, width);
56: // Create a view of the state of each location in the field.
57: view = new SimulatorView(depth, width);
58: view.setColor(Rabbit.class, Color.orange);
59: view.setColor(Fox.class, Color.blue);
60: // Setup a valid starting point.
61: reset();
62: }
63: /**
64: * Run the simulation from its current state for a reasonably long period,
65: * e.g. 500 steps.
66: */
67: public void runLongSimulation()
68: {
69: simulate(500);
70: }
71: /**
72: * Run the simulation from its current state for the given number of steps.
73: * Stop before the given number of steps if it ceases to be viable.
74: * @param numSteps The number of steps to run for.
75: */
76: public void simulate(int numSteps)
77: {
78: for(int step = 1; step <= numSteps && view.isViable(field); step++) {
79: simulateOneStep();
80: }
81: }
82: /**
83: * Run the simulation from its current state for a single step.
84: * Iterate over the whole field updating the state of each
85: * fox and rabbit.
86: */
87: public void simulateOneStep()
88: {
89: step++;
90: // Provide space for newborn rabbits.
91: List<Rabbit> newRabbits = new ArrayList<Rabbit>();
92: // Let all rabbits act.
93: for(Iterator<Rabbit> it = rabbits.iterator(); it.hasNext(); ) {
94: Rabbit rabbit = it.next();
95: rabbit.run(newRabbits);
96: if(! rabbit.isAlive()) {
97: it.remove();
98: }
99: }
100: // Provide space for newborn foxes.
101: List<Fox> newFoxes = new ArrayList<Fox>();
102: // Let all foxes act.
103: for(Iterator<Fox> it = foxes.iterator(); it.hasNext(); ) {
104: Fox fox = it.next();
105: fox.hunt(newFoxes);
106: if(! fox.isAlive()) {
107: it.remove();
108: }
109: }
110: // Add the newly born foxes and rabbits to the main lists.
111: rabbits.addAll(newRabbits);
112: foxes.addAll(newFoxes);
113: view.showStatus(step, field);
114: }
115: /**
116: * Reset the simulation to a starting position.
117: */
118: public void reset()
119: {
120: step = 0;
121: rabbits.clear();
122: foxes.clear();
123: populate();
124: // Show the starting state in the view.
125: view.showStatus(step, field);
126: }
127: /**
128: * Randomly populate the field with foxes and rabbits.
129: */
130: private void populate()
131: {
132: Random rand = Randomizer.getRandom();
133: field.clear();
134: for(int row = 0; row < field.getDepth(); row++) {
135: for(int col = 0; col < field.getWidth(); col++) {
136: if(rand.nextDouble() <= FOX_CREATION_PROBABILITY) {
137: Location location = new Location(row, col);
138: Fox fox = new Fox(true, field, location);
139: foxes.add(fox);
140: }
141: else if(rand.nextDouble() <= RABBIT_CREATION_PROBABILITY) {
142: Location location = new Location(row, col);
143: Rabbit rabbit = new Rabbit(true, field, location);
144: rabbits.add(rabbit);
145: }
146: // else leave the location empty.
147: }
148: }
149: }
150: }
- 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: * Represent a rectangular grid of field positions.
8: * Each position is able to store a single animal.
9: *
10: * @author Haikal Almaz Said
11: * @version 19/11/2018
12: */
13: public class Field
14: {
15: // A random number generator for providing random locations.
16: private static final Random rand = Randomizer.getRandom();
17: // The depth and width of the field.
18: private int depth, width;
19: // Storage for the animals.
20: private Object[][] field;
21: /**
22: * Represent a field of the given dimensions.
23: * @param depth The depth of the field.
24: * @param width The width of the field.
25: */
26: public Field(int depth, int width)
27: {
28: this.depth = depth;
29: this.width = width;
30: field = new Object[depth][width];
31: }
32: /**
33: * Empty the field.
34: */
35: public void clear()
36: {
37: for(int row = 0; row < depth; row++) {
38: for(int col = 0; col < width; col++) {
39: field[row][col] = null;
40: }
41: }
42: }
43: /**
44: * Clear the given location.
45: * @param location The location to clear.
46: */
47: public void clear(Location location)
48: {
49: field[location.getRow()][location.getCol()] = null;
50: }
51: /**
52: * Place an animal at the given location.
53: * If there is already an animal at the location it will
54: * be lost.
55: * @param animal The animal to be placed.
56: * @param row Row coordinate of the location.
57: * @param col Column coordinate of the location.
58: */
59: public void place(Object animal, int row, int col)
60: {
61: place(animal, new Location(row, col));
62: }
63: /**
64: * Place an animal at the given location.
65: * If there is already an animal at the location it will
66: * be lost.
67: * @param animal The animal to be placed.
68: * @param location Where to place the animal.
69: */
70: public void place(Object animal, Location location)
71: {
72: field[location.getRow()][location.getCol()] = animal;
73: }
74: /**
75: * Return the animal at the given location, if any.
76: * @param location Where in the field.
77: * @return The animal at the given location, or null if there is none.
78: */
79: public Object getObjectAt(Location location)
80: {
81: return getObjectAt(location.getRow(), location.getCol());
82: }
83: /**
84: * Return the animal at the given location, if any.
85: * @param row The desired row.
86: * @param col The desired column.
87: * @return The animal at the given location, or null if there is none.
88: */
89: public Object getObjectAt(int row, int col)
90: {
91: return field[row][col];
92: }
93: /**
94: * Generate a random location that is adjacent to the
95: * given location, or is the same location.
96: * The returned location will be within the valid bounds
97: * of the field.
98: * @param location The location from which to generate an adjacency.
99: * @return A valid location within the grid area.
100: */
101: public Location randomAdjacentLocation(Location location)
102: {
103: List<Location> adjacent = adjacentLocations(location);
104: return adjacent.get(0);
105: }
106: /**
107: * Get a shuffled list of the free adjacent locations.
108: * @param location Get locations adjacent to this.
109: * @return A list of free adjacent locations.
110: */
111: public List<Location> getFreeAdjacentLocations(Location location)
112: {
113: List<Location> free = new LinkedList<Location>();
114: List<Location> adjacent = adjacentLocations(location);
115: for(Location next : adjacent) {
116: if(getObjectAt(next) == null) {
117: free.add(next);
118: }
119: }
120: return free;
121: }
122: /**
123: * Try to find a free location that is adjacent to the
124: * given location. If there is none, return null.
125: * The returned location will be within the valid bounds
126: * of the field.
127: * @param location The location from which to generate an adjacency.
128: * @return A valid location within the grid area.
129: */
130: public Location freeAdjacentLocation(Location location)
131: {
132: // The available free ones.
133: List<Location> free = getFreeAdjacentLocations(location);
134: if(free.size() > 0) {
135: return free.get(0);
136: }
137: else {
138: return null;
139: }
140: }
141: /**
142: * Return a shuffled list of locations adjacent to the given one.
143: * The list will not include the location itself.
144: * All locations will lie within the grid.
145: * @param location The location from which to generate adjacencies.
146: * @return A list of locations adjacent to that given.
147: */
148: public List<Location> adjacentLocations(Location location)
149: {
150: assert location != null : "Null location passed to adjacentLocations";
151: // The list of locations to be returned.
152: List<Location> locations = new LinkedList<Location>();
153: if(location != null) {
154: int row = location.getRow();
155: int col = location.getCol();
156: for(int roffset = -1; roffset <= 1; roffset++) {
157: int nextRow = row + roffset;
158: if(nextRow >= 0 && nextRow < depth) {
159: for(int coffset = -1; coffset <= 1; coffset++) {
160: int nextCol = col + coffset;
161: // Exclude invalid locations and the original location.
162: if(nextCol >= 0 && nextCol < width && (roffset != 0 || coffset != 0)) {
163: locations.add(new Location(nextRow, nextCol));
164: }
165: }
166: }
167: }
168: // Shuffle the list. Several other methods rely on the list
169: // being in a random order.
170: Collections.shuffle(locations, rand);
171: }
172: return locations;
173: }
174: /**
175: * Return the depth of the field.
176: * @return The depth of the field.
177: */
178: public int getDepth()
179: {
180: return depth;
181: }
182: /**
183: * Return the width of the field.
184: * @return The width of the field.
185: */
186: public int getWidth()
187: {
188: return width;
189: }
190: }
- 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: * A graphical view of the simulation grid.
8: * The view displays a colored rectangle for each location
9: * representing its contents. It uses a default background color.
10: * Colors for each type of species can be defined using the
11: * setColor method.
12: *
13: * @author Haikal Almaz Said
14: * @version 19/11/2018
15: */
16: public class SimulatorView extends JFrame
17: {
18: // Colors used for empty locations.
19: private static final Color EMPTY_COLOR = Color.white;
20: // Color used for objects that have no defined color.
21: private static final Color UNKNOWN_COLOR = Color.gray;
22: private final String STEP_PREFIX = "Step: ";
23: private final String POPULATION_PREFIX = "Population: ";
24: private JLabel stepLabel, population;
25: private FieldView fieldView;
26: // A map for storing colors for participants in the simulation
27: private Map<Class, Color> colors;
28: // A statistics object computing and storing simulation information
29: private FieldStats stats;
30: /**
31: * Create a view of the given width and height.
32: * @param height The simulation's height.
33: * @param width The simulation's width.
34: */
35: public SimulatorView(int height, int width)
36: {
37: stats = new FieldStats();
38: colors = new LinkedHashMap<Class, Color>();
39: setTitle("Fox and Rabbit Simulation");
40: stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);
41: population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);
42: setLocation(100, 50);
43: fieldView = new FieldView(height, width);
44: Container contents = getContentPane();
45: contents.add(stepLabel, BorderLayout.NORTH);
46: contents.add(fieldView, BorderLayout.CENTER);
47: contents.add(population, BorderLayout.SOUTH);
48: pack();
49: setVisible(true);
50: }
51: /**
52: * Define a color to be used for a given class of animal.
53: * @param animalClass The animal's Class object.
54: * @param color The color to be used for the given class.
55: */
56: public void setColor(Class animalClass, Color color)
57: {
58: colors.put(animalClass, color);
59: }
60: /**
61: * @return The color to be used for a given class of animal.
62: */
63: private Color getColor(Class animalClass)
64: {
65: Color col = colors.get(animalClass);
66: if(col == null) {
67: // no color defined for this class
68: return UNKNOWN_COLOR;
69: }
70: else {
71: return col;
72: }
73: }
74: /**
75: * Show the current status of the field.
76: * @param step Which iteration step it is.
77: * @param field The field whose status is to be displayed.
78: */
79: public void showStatus(int step, Field field)
80: {
81: if(!isVisible()) {
82: setVisible(true);
83: }
84: stepLabel.setText(STEP_PREFIX + step);
85: stats.reset();
86: fieldView.preparePaint();
87: for(int row = 0; row < field.getDepth(); row++) {
88: for(int col = 0; col < field.getWidth(); col++) {
89: Object animal = field.getObjectAt(row, col);
90: if(animal != null) {
91: stats.incrementCount(animal.getClass());
92: fieldView.drawMark(col, row, getColor(animal.getClass()));
93: }
94: else {
95: fieldView.drawMark(col, row, EMPTY_COLOR);
96: }
97: }
98: }
99: stats.countFinished();
100: population.setText(POPULATION_PREFIX + stats.getPopulationDetails(field));
101: fieldView.repaint();
102: }
103: /**
104: * Determine whether the simulation should continue to run.
105: * @return true If there is more than one species alive.
106: */
107: public boolean isViable(Field field)
108: {
109: return stats.isViable(field);
110: }
111: /**
112: * Provide a graphical view of a rectangular field. This is
113: * a nested class (a class defined inside a class) which
114: * defines a custom component for the user interface. This
115: * component displays the field.
116: * This is rather advanced GUI stuff - you can ignore this
117: * for your project if you like.
118: */
119: private class FieldView extends JPanel
120: {
121: private final int GRID_VIEW_SCALING_FACTOR = 6;
122: private int gridWidth, gridHeight;
123: private int xScale, yScale;
124: Dimension size;
125: private Graphics g;
126: private Image fieldImage;
127: /**
128: * Create a new FieldView component.
129: */
130: public FieldView(int height, int width)
131: {
132: gridHeight = height;
133: gridWidth = width;
134: size = new Dimension(0, 0);
135: }
136: /**
137: * Tell the GUI manager how big we would like to be.
138: */
139: public Dimension getPreferredSize()
140: {
141: return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,
142: gridHeight * GRID_VIEW_SCALING_FACTOR);
143: }
144: /**
145: * Prepare for a new round of painting. Since the component
146: * may be resized, compute the scaling factor again.
147: */
148: public void preparePaint()
149: {
150: if(! size.equals(getSize())) { // if the size has changed...
151: size = getSize();
152: fieldImage = fieldView.createImage(size.width, size.height);
153: g = fieldImage.getGraphics();
154: xScale = size.width / gridWidth;
155: if(xScale < 1) {
156: xScale = GRID_VIEW_SCALING_FACTOR;
157: }
158: yScale = size.height / gridHeight;
159: if(yScale < 1) {
160: yScale = GRID_VIEW_SCALING_FACTOR;
161: }
162: }
163: }
164: /**
165: * Paint on grid location on this field in a given color.
166: */
167: public void drawMark(int x, int y, Color color)
168: {
169: g.setColor(color);
170: g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);
171: }
172: /**
173: * The field view component needs to be redisplayed. Copy the
174: * internal image to screen.
175: */
176: public void paintComponent(Graphics g)
177: {
178: if(fieldImage != null) {
179: Dimension currentSize = getSize();
180: if(size.equals(currentSize)) {
181: g.drawImage(fieldImage, 0, 0, null);
182: }
183: else {
184: // Rescale the previous image.
185: g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);
186: }
187: }
188: }
189: }
190: }
- Counter
1: import java.awt.Color;
2: /**
3: * Provide a counter for a participant in the simulation.
4: * This includes an identifying string and a count of how
5: * many participants of this type currently exist within
6: * the simulation.
7: *
8: * @author Haikal Almaz Said
9: * @version 19/11/2018
10: */
11: public class Counter
12: {
13: // A name for this type of simulation participant
14: private String name;
15: // How many of this type exist in the simulation.
16: private int count;
17: /**
18: * Provide a name for one of the simulation types.
19: * @param name A name, e.g. "Fox".
20: */
21: public Counter(String name)
22: {
23: this.name = name;
24: count = 0;
25: }
26: /**
27: * @return The short description of this type.
28: */
29: public String getName()
30: {
31: return name;
32: }
33: /**
34: * @return The current count for this type.
35: */
36: public int getCount()
37: {
38: return count;
39: }
40: /**
41: * Increment the current count by one.
42: */
43: public void increment()
44: {
45: count++;
46: }
47: /**
48: * Reset the current count to zero.
49: */
50: public void reset()
51: {
52: count = 0;
53: }
54: }
- Location
1: /**
2: * Represent a location in a rectangular grid.
3: *
4: * @author Haikal Almaz Said
5: * @version 19/11/2018
6: */
7: public class Location
8: {
9: // Row and column positions.
10: private int row;
11: private int col;
12: /**
13: * Represent a row and column.
14: * @param row The row.
15: * @param col The column.
16: */
17: public Location(int row, int col)
18: {
19: this.row = row;
20: this.col = col;
21: }
22: /**
23: * Implement content equality.
24: */
25: public boolean equals(Object obj)
26: {
27: if(obj instanceof Location) {
28: Location other = (Location) obj;
29: return row == other.getRow() && col == other.getCol();
30: }
31: else {
32: return false;
33: }
34: }
35: /**
36: * Return a string of the form row,column
37: * @return A string representation of the location.
38: */
39: public String toString()
40: {
41: return row + "," + col;
42: }
43: /**
44: * Use the top 16 bits for the row value and the bottom for
45: * the column. Except for very big grids, this should give a
46: * unique hash code for each (row, col) pair.
47: * @return A hashcode for the location.
48: */
49: public int hashCode()
50: {
51: return (row << 16) + col;
52: }
53: /**
54: * @return The row.
55: */
56: public int getRow()
57: {
58: return row;
59: }
60: /**
61: * @return The column.
62: */
63: public int getCol()
64: {
65: return col;
66: }
67: }
- Rabbit
1: import java.util.List;
2: import java.util.Random;
3: /**
4: * A simple model of a rabbit.
5: * Rabbits age, move, breed, and die.
6: *
7: * @author Haikal Almaz Said
8: * @version 19/11/2018
9: */
10: public class Rabbit
11: {
12: // Characteristics shared by all rabbits (static fields).
13: // The age at which a rabbit can start to breed.
14: private static final int BREEDING_AGE = 5;
15: // The age to which a rabbit can live.
16: private static final int MAX_AGE = 40;
17: // The likelihood of a rabbit breeding.
18: private static final double BREEDING_PROBABILITY = 0.15;
19: // The maximum number of births.
20: private static final int MAX_LITTER_SIZE = 4;
21: // A shared random number generator to control breeding.
22: private static final Random rand = Randomizer.getRandom();
23: // Individual characteristics (instance fields).
24: // The rabbit's age.
25: private int age;
26: // Whether the rabbit is alive or not.
27: private boolean alive;
28: // The rabbit's position.
29: private Location location;
30: // The field occupied.
31: private Field field;
32: /**
33: * Create a new rabbit. A rabbit may be created with age
34: * zero (a new born) or with a random age.
35: *
36: * @param randomAge If true, the rabbit will have a random age.
37: * @param field The field currently occupied.
38: * @param location The location within the field.
39: */
40: public Rabbit(boolean randomAge, Field field, Location location)
41: {
42: age = 0;
43: alive = true;
44: this.field = field;
45: setLocation(location);
46: if(randomAge) {
47: age = rand.nextInt(MAX_AGE);
48: }
49: }
50: /**
51: * This is what the rabbit does most of the time - it runs
52: * around. Sometimes it will breed or die of old age.
53: * @param newRabbits A list to add newly born rabbits to.
54: */
55: public void run(List<Rabbit> newRabbits)
56: {
57: incrementAge();
58: if(alive) {
59: giveBirth(newRabbits);
60: // Try to move into a free location.
61: Location newLocation = field.freeAdjacentLocation(location);
62: if(newLocation != null) {
63: setLocation(newLocation);
64: }
65: else {
66: // Overcrowding.
67: setDead();
68: }
69: }
70: }
71: /**
72: * Check whether the rabbit is alive or not.
73: * @return true if the rabbit is still alive.
74: */
75: public boolean isAlive()
76: {
77: return alive;
78: }
79: /**
80: * Indicate that the rabbit is no longer alive.
81: * It is removed from the field.
82: */
83: public void setDead()
84: {
85: alive = false;
86: if(location != null) {
87: field.clear(location);
88: location = null;
89: field = null;
90: }
91: }
92: /**
93: * Return the rabbit's location.
94: * @return The rabbit's location.
95: */
96: public Location getLocation()
97: {
98: return location;
99: }
100: /**
101: * Place the rabbit at the new location in the given field.
102: * @param newLocation The rabbit's new location.
103: */
104: private void setLocation(Location newLocation)
105: {
106: if(location != null) {
107: field.clear(location);
108: }
109: location = newLocation;
110: field.place(this, newLocation);
111: }
112: /**
113: * Increase the age.
114: * This could result in the rabbit's death.
115: */
116: private void incrementAge()
117: {
118: age++;
119: if(age > MAX_AGE) {
120: setDead();
121: }
122: }
123: /**
124: * Check whether or not this rabbit is to give birth at this step.
125: * New births will be made into free adjacent locations.
126: * @param newRabbits A list to add newly born rabbits to.
127: */
128: private void giveBirth(List<Rabbit> newRabbits)
129: {
130: // New rabbits are born into adjacent locations.
131: // Get a list of adjacent free locations.
132: List<Location> free = field.getFreeAdjacentLocations(location);
133: int births = breed();
134: for(int b = 0; b < births && free.size() > 0; b++) {
135: Location loc = free.remove(0);
136: Rabbit young = new Rabbit(false, field, loc);
137: newRabbits.add(young);
138: }
139: }
140: /**
141: * Generate a number representing the number of births,
142: * if it can breed.
143: * @return The number of births (may be zero).
144: */
145: private int breed()
146: {
147: int births = 0;
148: if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {
149: births = rand.nextInt(MAX_LITTER_SIZE) + 1;
150: }
151: return births;
152: }
153: /**
154: * A rabbit can breed if it has reached the breeding age.
155: * @return true if the rabbit can breed, false otherwise.
156: */
157: private boolean canBreed()
158: {
159: return age >= BREEDING_AGE;
160: }
161: }
- Fox
1: import java.util.List;
2: import java.util.Iterator;
3: import java.util.Random;
4: /**
5: * A simple model of a fox.
6: * Foxes age, move, eat rabbits, and die.
7: *
8: * @author Haikal Almaz Said
9: * @version 19/11/2018
10: */
11: public class Fox
12: {
13: // Characteristics shared by all foxes (static fields).
14: // The age at which a fox can start to breed.
15: private static final int BREEDING_AGE = 10;
16: // The age to which a fox can live.
17: private static final int MAX_AGE = 150;
18: // The likelihood of a fox breeding.
19: private static final double BREEDING_PROBABILITY = 0.35;
20: // The maximum number of births.
21: private static final int MAX_LITTER_SIZE = 5;
22: // The food value of a single rabbit. In effect, this is the
23: // number of steps a fox can go before it has to eat again.
24: private static final int RABBIT_FOOD_VALUE = 7;
25: // A shared random number generator to control breeding.
26: private static final Random rand = Randomizer.getRandom();
27: // Individual characteristics (instance fields).
28: // The fox's age.
29: private int age;
30: // Whether the fox is alive or not.
31: private boolean alive;
32: // The fox's position.
33: private Location location;
34: // The field occupied.
35: private Field field;
36: // The fox's food level, which is increased by eating rabbits.
37: private int foodLevel;
38: /**
39: * Create a fox. A fox can be created as a new born (age zero
40: * and not hungry) or with a random age and food level.
41: *
42: * @param randomAge If true, the fox will have random age and hunger level.
43: * @param field The field currently occupied.
44: * @param location The location within the field.
45: */
46: public Fox(boolean randomAge, Field field, Location location)
47: {
48: age = 0;
49: alive = true;
50: this.field = field;
51: setLocation(location);
52: if(randomAge) {
53: age = rand.nextInt(MAX_AGE);
54: foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);
55: }
56: else {
57: // leave age at 0
58: foodLevel = RABBIT_FOOD_VALUE;
59: }
60: }
61: /**
62: * This is what the fox does most of the time: it hunts for
63: * rabbits. In the process, it might breed, die of hunger,
64: * or die of old age.
65: * @param field The field currently occupied.
66: * @param newFoxes A list to add newly born foxes to.
67: */
68: public void hunt(List<Fox> newFoxes)
69: {
70: incrementAge();
71: incrementHunger();
72: if(alive) {
73: giveBirth(newFoxes);
74: // Move towards a source of food if found.
75: Location newLocation = findFood(location);
76: if(newLocation == null) {
77: // No food found - try to move to a free location.
78: newLocation = field.freeAdjacentLocation(location);
79: }
80: // See if it was possible to move.
81: if(newLocation != null) {
82: setLocation(newLocation);
83: }
84: else {
85: // Overcrowding.
86: setDead();
87: }
88: }
89: }
90: /**
91: * Check whether the fox is alive or not.
92: * @return True if the fox is still alive.
93: */
94: public boolean isAlive()
95: {
96: return alive;
97: }
98: /**
99: * Return the fox's location.
100: * @return The fox's location.
101: */
102: public Location getLocation()
103: {
104: return location;
105: }
106: /**
107: * Place the fox at the new location in the given field.
108: * @param newLocation The fox's new location.
109: */
110: private void setLocation(Location newLocation)
111: {
112: if(location != null) {
113: field.clear(location);
114: }
115: location = newLocation;
116: field.place(this, newLocation);
117: }
118: /**
119: * Increase the age. This could result in the fox's death.
120: */
121: private void incrementAge()
122: {
123: age++;
124: if(age > MAX_AGE) {
125: setDead();
126: }
127: }
128: /**
129: * Make this fox more hungry. This could result in the fox's death.
130: */
131: private void incrementHunger()
132: {
133: foodLevel--;
134: if(foodLevel <= 0) {
135: setDead();
136: }
137: }
138: /**
139: * Tell the fox to look for rabbits adjacent to its current location.
140: * Only the first live rabbit is eaten.
141: * @param location Where in the field it is located.
142: * @return Where food was found, or null if it wasn't.
143: */
144: private Location findFood(Location location)
145: {
146: List<Location> adjacent = field.adjacentLocations(location);
147: Iterator<Location> it = adjacent.iterator();
148: while(it.hasNext()) {
149: Location where = it.next();
150: Object animal = field.getObjectAt(where);
151: if(animal instanceof Rabbit) {
152: Rabbit rabbit = (Rabbit) animal;
153: if(rabbit.isAlive()) {
154: rabbit.setDead();
155: foodLevel = RABBIT_FOOD_VALUE;
156: // Remove the dead rabbit from the field.
157: return where;
158: }
159: }
160: }
161: return null;
162: }
163: /**
164: * Check whether or not this fox is to give birth at this step.
165: * New births will be made into free adjacent locations.
166: * @param newFoxes A list to add newly born foxes to.
167: */
168: private void giveBirth(List<Fox> newFoxes)
169: {
170: // New foxes are born into adjacent locations.
171: // Get a list of adjacent free locations.
172: List<Location> free = field.getFreeAdjacentLocations(location);
173: int births = breed();
174: for(int b = 0; b < births && free.size() > 0; b++) {
175: Location loc = free.remove(0);
176: Fox young = new Fox(false, field, loc);
177: newFoxes.add(young);
178: }
179: }
180: /**
181: * Generate a number representing the number of births,
182: * if it can breed.
183: * @return The number of births (may be zero).
184: */
185: private int breed()
186: {
187: int births = 0;
188: if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {
189: births = rand.nextInt(MAX_LITTER_SIZE) + 1;
190: }
191: return births;
192: }
193: /**
194: * A fox can breed if it has reached the breeding age.
195: */
196: private boolean canBreed()
197: {
198: return age >= BREEDING_AGE;
199: }
200: /**
201: * Indicate that the fox is no longer alive.
202: * It is removed from the field.
203: */
204: private void setDead()
205: {
206: alive = false;
207: if(location != null) {
208: field.clear(location);
209: location = null;
210: field = null;
211: }
212: }
213: }
- Randomizer
1: import java.util.Random;
2: /**
3: * Provide control over the randomization of the simulation.
4: *
5: * @author Haikal Almaz Said
6: * @version 19/11/2018
7: */
8: public class Randomizer
9: {
10: // The default seed for control of randomization.
11: private static final int SEED = 1111;
12: // A shared Random object, if required.
13: private static final Random rand = new Random(SEED);
14: // Determine whether a shared random generator is to be provided.
15: private static final boolean useShared = true;
16: /**
17: * Constructor for objects of class Randomizer
18: */
19: public Randomizer()
20: {
21: }
22: /**
23: * Provide a random generator.
24: * @return A random object.
25: */
26: public static Random getRandom()
27: {
28: if(useShared) {
29: return rand;
30: }
31: else {
32: return new Random();
33: }
34: }
35: /**
36: * Reset the randomization.
37: * This will have no effect if randomization is not through
38: * a shared Random generator.
39: */
40: public static void reset()
41: {
42: if(useShared) {
43: rand.setSeed(SEED);
44: }
45: }
46: }
- FieldStats
1: import java.awt.Color;
2: import java.util.HashMap;
3: /**
4: * This class collects and provides some statistical data on the state
5: * of a field. It is flexible: it will create and maintain a counter
6: * for any class of object that is found within the field.
7: *
8: * @author Haikal Almaz Said
9: * @version 19/11/2018
10: */
11: public class FieldStats
12: {
13: // Counters for each type of entity (fox, rabbit, etc.) in the simulation.
14: private HashMap<Class, Counter> counters;
15: // Whether the counters are currently up to date.
16: private boolean countsValid;
17: /**
18: * Construct a FieldStats object.
19: */
20: public FieldStats()
21: {
22: // Set up a collection for counters for each type of animal that
23: // we might find
24: counters = new HashMap<Class, Counter>();
25: countsValid = true;
26: }
27: /**
28: * Get details of what is in the field.
29: * @return A string describing what is in the field.
30: */
31: public String getPopulationDetails(Field field)
32: {
33: StringBuffer buffer = new StringBuffer();
34: if(!countsValid) {
35: generateCounts(field);
36: }
37: for(Class key : counters.keySet()) {
38: Counter info = counters.get(key);
39: buffer.append(info.getName());
40: buffer.append(": ");
41: buffer.append(info.getCount());
42: buffer.append(' ');
43: }
44: return buffer.toString();
45: }
46: /**
47: * Invalidate the current set of statistics; reset all
48: * counts to zero.
49: */
50: public void reset()
51: {
52: countsValid = false;
53: for(Class key : counters.keySet()) {
54: Counter count = counters.get(key);
55: count.reset();
56: }
57: }
58: /**
59: * Increment the count for one class of animal.
60: * @param animalClass The class of animal to increment.
61: */
62: public void incrementCount(Class animalClass)
63: {
64: Counter count = counters.get(animalClass);
65: if(count == null) {
66: // We do not have a counter for this species yet.
67: // Create one.
68: count = new Counter(animalClass.getName());
69: counters.put(animalClass, count);
70: }
71: count.increment();
72: }
73: /**
74: * Indicate that an animal count has been completed.
75: */
76: public void countFinished()
77: {
78: countsValid = true;
79: }
80: /**
81: * Determine whether the simulation is still viable.
82: * I.e., should it continue to run.
83: * @return true If there is more than one species alive.
84: */
85: public boolean isViable(Field field)
86: {
87: // How many counts are non-zero.
88: int nonZero = 0;
89: if(!countsValid) {
90: generateCounts(field);
91: }
92: for(Class key : counters.keySet()) {
93: Counter info = counters.get(key);
94: if(info.getCount() > 0) {
95: nonZero++;
96: }
97: }
98: return nonZero > 1;
99: }
100: /**
101: * Generate counts of the number of foxes and rabbits.
102: * These are not kept up to date as foxes and rabbits
103: * are placed in the field, but only when a request
104: * is made for the information.
105: * @param field The field to generate the stats for.
106: */
107: private void generateCounts(Field field)
108: {
109: reset();
110: for(int row = 0; row < field.getDepth(); row++) {
111: for(int col = 0; col < field.getWidth(); col++) {
112: Object animal = field.getObjectAt(row, col);
113: if(animal != null) {
114: incrementCount(animal.getClass());
115: }
116: }
117: }
118: countsValid = true;
119: }
120: }
(Tampilan Class dalam Bluej)
(Tampilan Simulator setelah 110 Step)
Sekian postingan saya kali ini, Terima Kasih.
No comments:
Post a Comment