Assignment is a pandemic simulation. It randomizes the starting condition and plays the simulation out according to the simulation parameters and shows how many people are sick at any one point. It allows the user to explore the parameters being used live.
You are provided with a partially working template and a video of how the final product will work.
You are expected to fill in the incomplete methods. You may find it helpful to create tests for each of your methods since they will be tested with a test harness. We don't provide the test harness, you must correctly interpret the JavaDoc, we won't test anything not made clear in the JavaDoc.
However, quite a few of the methods are empty so it is not working well at all.
Main runs the application by building a Population and stepping the simulation each 16 milliseconds. A Population is made of Stimulants.
The two classes that you must work on are,
The description for each method is provided as JavaDoc.
You are not required to edit other files. You will be able to tell if your implementations are correct by running the main application and seeing if all the functionality is there. However, we strongly encourage you to supplement this with unit tests because it is hard to test everything via use alone.
import java.util.*;
import java.awt.geom.*;
class Population {
public ArrayList< Simulant> sims = new ArrayList< Simulant>();
public Random rand = new Random();
public Population() {
for (int i = 0; i < Main.SIMS; i++) {
sims.add(new Simulant());
}
// make the first one sick
sims.get(0).sick = 1; // to be completed
}
/**
* update an entire population for each simulant update their location and
* illness then check each pair of simulants to see if they are in touch
* with one another. If they are, they might get sick
*/
public void update() {
for (Simulant s : sims) {
s.updateLoc();
s.updateIllness();
}
// check every pair of sims to see if they are in contact, if so, pass on any sickness
for (Simulant s1 : sims) {
for (Simulant s2 : sims) {
if (s1.loc.distance(s2.loc) < Simulant.SIZE) {
s1.sick = s1.sick == 0 && s2.sick > Main.CONT_AFTER && !s1.immune && rand.nextInt(100) < Main.TRANS_RATE ? 1 : s1.sick;
s2.sick = s2.sick == 0 && s1.sick > Main.CONT_AFTER && !s2.immune && rand.nextInt(100) < Main.TRANS_RATE ? 1 : s2.sick;
}
}
}
}
/**
* @return the average of the x locations of all sick simulants answer is
* zero if no sims are sick
*/
public double averageXOfSick() {
int numSimulantsFound = 0;
double totalXLocations = 0;
for (Simulant simulant : sims) {
if (simulant.sick > 0) {
totalXLocations += simulant.loc.getX();
numSimulantsFound++;
}
}
if (numSimulantsFound == 0) {
return 0;
}
return totalXLocations / numSimulantsFound;
}
/**
* @return the average of the y locations of all sick simulants answer is
* zero if no sims are sick
*
*/
public double averageYOfSick() {
}
/**
* @return the first sim found who's is over the given point you should use
* the whole area the simulant is drawn on (i.e. center plus radius) to
* determine if the sim is at this location. Return null if no sim found.
*
*/
public Simulant simAtLocation(Point2D loc) {
}
/**
* @param sim the simulant to find in the population
* @return the simulant one index greater than the given simulant. Return
* null if `sim` not found or there is no simulant after the found one.
*
*/
public Simulant nextAfter(Simulant sim) {
}
/**
* @param sim the simulant to find in the population
* @return the simulant one index less than the given simulant. Return null
* if `sim` not found or there is no simulant before the found one.
*
*/
public Simulant prevBefore(Simulant sim) {
}
/**
* @return the total number of sick simulants
*
*/
public int numberSick() {
}
/**
* @return An array list of all the simulants sorted by "sickness". Sorting
* order is determined by the `compareTo` method on the simulants.
*
*/
public ArrayList< Simulant> sort() {
}
}
import java.awt.geom.*;
import java.util.*;
class Simulant implements Comparable< Simulant> {
public static final int SIZE = 5;
public Point2D loc;
public int sick;
public boolean immune;
private double dir;
private double speed;
public Point2D homeLoc;
public double mobility;
private Random rand;
public Simulant() {
rand = new Random();
homeLoc = new Point2D.Double(rand.nextInt(Main.WIDTH), rand.nextInt(Main.HEIGHT));
loc = new Point2D.Double(homeLoc.getX(), homeLoc.getY());
sick = 0;
immune = false;
dir = Math.random() * 2 * Math.PI;
speed = Math.random();
mobility = rand.nextInt(Main.MAX_MOVE);
}
/**
* updates the location of the simulant on each animation frame according to
* it's movement settings
*/
public void updateLoc() {
if (sick >= 0) {
Point2D nLoc = (Point2D) loc.clone();
nLoc.setLocation(nLoc.getX() + speed * Math.cos(dir),
nLoc.getY() + speed * Math.sin(dir));
if (nLoc.distance(homeLoc) > mobility || nLoc.getX() < 0 || nLoc.getY() < 0 || nLoc.getX() > Main.WIDTH || nLoc.getY() > Main.HEIGHT) {
dir = Math.random() * 2 * Math.PI;
} else {
loc = nLoc;
}
}
}
/**
* adjusts the simulant's illness status according to the rules * of the
* illness. Is asymptomatic for 240 frames, then is ill * with a 3% chance
* of dying and then is immune if they survive * to 240 frames
*
*/
public void updateIllness() {
if (sick > Main.CONT_AFTER) {
if (rand.nextInt((Main.ILL_FOR - Main.CONT_AFTER) * 100) < Main.DEATH_RATE) {
sick = -1;
}
}
if (sick > 0) {
sick++;
}
if (sick > Main.ILL_FOR) {
sick = 0;
immune = true;
}
}
/**
* compares simulants using sickness. A simulant who is earlier in their
* sickness is "less than" one later in their sickness. A simulant who is
* dead is "less than" any other. A simulant who is immune is "greater than"
* any that is sick. A simulant that has never been sick is "less than" one
* that has been sick.
*
* @return 0 if this simulant is equal to the other, less than zero if it is
* less than and greater than zero if it is greater than
*
*/
@Override
public int compareTo(Simulant other) {
}
}