![]() |
Jupyter at Bryn Mawr College |
|
|
Public notebooks: /services/public/dblank / CS110 Intro to Computing / 2015-Spring / Notes |
Consider a simple disease that follows these simple rules:
Sounds like zombies?
What would happen? How can we model this world?
First, we must identify the objects we wish to model. Possibilities include:
First, let's consider what properties a person should have:
Also, what actions must a person be able to do:
We might want to add other methods, but it needs to at least support those.
So, let's put together a person class. It might look something like:
class Person {
int x;
int y;
int vx;
int vy;
int carrying; // zero - not carrying disease; 1 - carrying disease
Person(int x, int y) {
this.x = int(x);
this.y = int(y);
this.randomizeDirection();
this.carrying = 0;
}
...
}
Like the termites, instead of having them bounce off of the walls (like a ball simulation) we will instead have them "wrap" around (like a torus). For example, if a person goes too far to the left, it will wrap around to the right, and instantly appear there. Likewise, if a turtle goes below 0 or above height, then it wraps back around. Thus, we implement an infinite, repeating surface.
This putting it all together might look like the following.
Note:
People [] person; // the array of people; we'll decide how many later
int RADIUS = 5; // distance that we can sense a wood chip
class Person {
int x;
int y;
int vx;
int vy;
int carrying; // zero - not carrying disease; 1 - carrying disease
Person(int x, int y) {
this.x = int(x);
this.y = int(y);
this.randomizeDirection();
this.carrying = 0;
}
void draw() {
if (this.carrying == 0) {
fill(128, 0, 0);
} else {
fill(0, 255, 0);
}
ellipse(this.x, this.y, 10, 10);
}
int get_x(int delta) {
int dx = this.x + delta;
if (dx >= width)
dx -= width;
if (dx < 0)
dx += width;
return dx;
}
int get_y(int delta) {
int dy = this.y + delta;
if (dy >= height)
dy -= height;
if (dy < 0)
dy += height;
return dy;
}
void step() {
this.x = this.get_x(this.vx);
this.y = this.get_y(this.vy);
}
void randomizeDirection() {
this.vx = 0;
this.vy = 0;
while (this.vx == 0 && this.vy == 0) {
this.vx = floor(random(3)) - 1;
this.vy = floor(random(3)) - 1;
}
}
float distance(Person person) {
return sqrt( pow(this.x - person.x, 2) + pow(this.y - person.y, 2));
}
void move() {
if (this.carrying == 1) {
if (random() < 1.0) { // 10% of the time, change directions
this.randomizeDirection();
}
} else {
if (random() < .01) { // 10% of the time, change directions
this.randomizeDirection();
}
}
this.step();
// carrying a disease
if (this.carrying == 1) {
// find people within radius, and infect them
// some percentage of time
for (int p = 0; p < people.length; p++) {
if (this.distance(people[p]) < RADIUS) {
people[p].carrying = 1;
}
}
}
}
}
void setup() {
size(500, 250); // the world
people = new Person[500]; // start termites
for (int i =0; i < people.length; i++) {
people[i] = new Person(random(width), random(height));
}
// How many to infect initially?
people[0].carrying = 1;
}
void draw() {
background();
noStroke();
// Move the termites:
for (int i =0; i < people.length; i++) {
people[i].move();
people[i].draw();
}
}