class Doctor { private PVector position; private PVector direction; private int size = 10; public Doctor() { position = new PVector(random(size, width - size), random(size, height - size)); direction = new PVector(random(-1, 1), random(-1, 1)); } public void update() { if (position.x <= size || position.x >= width - 10) { direction.x = -1 * direction.x; } if (position.y <= size || position.y >= height - 10) { direction.y = -1 * direction.y; } position.x += direction.x; position.y += direction.y; } public void draw() { stroke(0, 0, 0); fill(255, 255, 255); ellipse(position.x, position.y, size, size); noStroke(); fill(255, 0, 0); rect(position.x - 1.5, position.y - 4, 3, 8); rect(position.x - 4, position.y - 1.5, 8, 3); } public boolean checkCollision(int xPos1, int yPos1, int xPos2, int yPos2) { if (position.x > xPos1 && position.x < xPos2 && position.y > yPos1 && position.y < yPos2) { return true; } return false; } public void interact(ArrayList population) { int xBounds = size / 2; int yBounds = size / 2; for (Patient neighbor : population) { if (neighbor.checkCollision((int)position.x - xBounds, (int)position.y - yBounds, (int)position.x + xBounds, (int)position.y + yBounds)) { neighbor.vaccinate(); } } } }ArrayList population = new ArrayList(); ArrayList medicalCommunity = new ArrayList(); void setup() { size(800, 600); boolean isVaccinated = false; for (int i = 0; i < Settings.population; i++) { isVaccinated = Settings.vaccinationPercentage >= random(0, 100); population.add(new Patient(isVaccinated)); } for (int i = 0; i < Settings.doctorPopulation; i++) { medicalCommunity.add(new Doctor()); } } void draw() { for (Patient patient : population) { patient.update(); patient.interact(population); } for (Doctor doctor : medicalCommunity) { doctor.update(); doctor.interact(population); } background(255, 255, 255); noStroke(); for (Patient patient : population) { patient.draw(); } for (Doctor doctor : medicalCommunity) { doctor.draw(); } int[] counts = {0, 0, 0, 0, 0}; for (Patient patient : population) { counts[patient.getState()]++; } String message = "Uninfected: " + nf(counts[Patient.UNINFECTED], 4)+ " Vaccinated: "+nf(counts[Patient.VACCINATED], 4)+" Sick: "+nf(counts[Patient.SICK], 4)+" Immune: "+nf(counts[Patient.IMMUNE], 4)+" Dead: "+nf(counts[Patient.DEAD], 4); fill(0, 0, 0); textSize(18); text(message, 60, height - 5); fill(0, 0, 255, 180); ellipse(55, height - 12, 10, 10); fill(255, 127, 0, 180); ellipse(220, height - 12, 10, 10); fill(0, 255, 0, 180); ellipse(390, height - 12, 10, 10); fill(255, 127, 127, 180); ellipse(496, height - 12, 10, 10); fill(127, 127, 127, 180); ellipse(643, height - 12, 10, 10); } void mouseClicked() { fill(255, 0, 0); int clickSize = Settings.infectionClickSize; ellipse(mouseX, mouseY, clickSize * 2, clickSize * 2); for (Patient patient : population) { if (patient.checkCollision(mouseX - clickSize, mouseY - clickSize, mouseX + clickSize, mouseY + clickSize)) { patient.infect(); } } }class Patient { private PVector position; private PVector direction; public static final int UNINFECTED = 0; public static final int VACCINATED = 1; public static final int SICK = 2; public static final int IMMUNE = 3; public static final int DEAD = 4; private int size = 10; private int infectedTimer = 0; private int immuneTimer = 0; private boolean hasDeath = false; private int state = UNINFECTED; public Patient(boolean isVaccinated) { position = new PVector(random(size, width - size), random(size, height - size - 20)); direction = new PVector(random(-1, 1), random(-1, 1)); if (isVaccinated) { state = VACCINATED; } hasDeath = Settings.deathProbability >= random(0, 100); } public int getState() { return state; } public void update() { if (state != DEAD) { if (position.x <= size || position.x >= width - size) { direction.x = -1 * direction.x; } if (position.y <= size || position.y >= height - size - 20) { direction.y = -1 * direction.y; } position.x += direction.x; position.y += direction.y; } if (state == SICK) { infectedTimer--; if (infectedTimer <= 0) { state = UNINFECTED; if (Settings.canBecomeImmune) { this.immunize(); } if (hasDeath) { state = DEAD; } } } if (state == IMMUNE && !Settings.immuneForLife) { immuneTimer--; if (immuneTimer <= 0) { state = UNINFECTED; } } if (state == VACCINATED && !Settings.vaccinatedForLife) { immuneTimer--; if (immuneTimer <= 0) { state = UNINFECTED; } } } public void draw() { switch(state) { case UNINFECTED: fill(0, 0, 255, 180); break; case VACCINATED: fill(255, 127, 0, 180); break; case SICK: fill(0, 255, 0, 180); break; case IMMUNE: fill(255, 127, 127, 180); break; case DEAD: fill(127, 127, 127, 180); break; } ellipse(position.x, position.y, size, size); } public boolean checkCollision(int xPos1, int yPos1, int xPos2, int yPos2) { if (position.x > xPos1 && position.x < xPos2 && position.y > yPos1 && position.y < yPos2) { return true; } return false; } public void infect() { if (state == UNINFECTED) { state = SICK; infectedTimer = Settings.sickDuration; } } public void immunize() { if (state == UNINFECTED || state == IMMUNE) { state = IMMUNE; immuneTimer = max(Settings.immuneDuration, immuneTimer); } } public void vaccinate() { if (state == UNINFECTED || state == IMMUNE) { state = VACCINATED; immuneTimer = max(Settings.vaccineDuration, immuneTimer); } } public void interact(ArrayList population) { if ((Settings.canDeadInfect && state == DEAD) || state == SICK) { int xBounds = size / 2; int yBounds = size / 2; for (Patient neighbor : population) { if (neighbor.checkCollision((int)position.x - xBounds, (int)position.y - yBounds, (int)position.x + xBounds, (int)position.y + yBounds)) { neighbor.infect(); } } } } }abstract static class Settings { public static int population = 1000; public static float vaccinationPercentage = 0.0; public static float deathProbability = 5.0; public static int sickDuration = 200; public static int infectionClickSize = 10; public static boolean canBecomeImmune = true; public static boolean immuneForLife = false; public static boolean vaccinatedForLife = false; public static int immuneDuration = 3000; public static int vaccineDuration = 3000; public static boolean canDeadInfect = false; public static int doctorPopulation = 0; }