Predator model
This commit is contained in:
commit
f2e9bfb2c6
1 changed files with 504 additions and 0 deletions
504
src/Predator.java
Normal file
504
src/Predator.java
Normal file
|
@ -0,0 +1,504 @@
|
|||
import processing.core.PApplet;
|
||||
import processing.core.PFont;
|
||||
import processing.core.PImage;
|
||||
|
||||
public class Predator extends PApplet{
|
||||
|
||||
String[] myFileArray = {"pictures/fox.jpeg", "pictures/rabbit.jpeg", "pictures/grass.jpeg", "pictures/desert.jpeg", "pictures/road.jpeg"}; // picture names,, add more
|
||||
String[] myNames = {"fox", "rabbit", "grass", "desert"}; // picture names,, add more
|
||||
|
||||
int n_boxes = 30;
|
||||
int nn = n_boxes *n_boxes;
|
||||
boolean DIAGONAL = false;
|
||||
Box [] boxes = new Box[nn];
|
||||
Neighbours [] neighs = new Neighbours[nn] ;
|
||||
|
||||
double rabbits= 0.3;
|
||||
double foxes = 0.3;
|
||||
double desert = 0.15;
|
||||
double grass = 0.15;
|
||||
int FOX = 0;
|
||||
int RABBIT = 1;
|
||||
int GRASS = 2;
|
||||
int DESERT = 3;
|
||||
int ROAD = 4;
|
||||
|
||||
// visualization
|
||||
PImage[] images = new PImage[5];
|
||||
PImage[] images_g = new PImage[5];
|
||||
Box [] colors = new Box[5];
|
||||
int WIDTH = 1900;
|
||||
int HEIGHT = 1000;
|
||||
int SIZE = 50;
|
||||
int PIC_SIZE = 80;
|
||||
int TRACES = 40;
|
||||
PFont f;
|
||||
int[] counter = new int[5];
|
||||
int[][] traces = new int[4][TRACES];
|
||||
int box = -1 ;
|
||||
int time = 0;
|
||||
boolean INIT_TODO = true;
|
||||
|
||||
// @Override
|
||||
// public void mouseClicked()
|
||||
// {
|
||||
// print("ciao");
|
||||
// INIT_TODO = false;
|
||||
// }
|
||||
@Override
|
||||
public void settings() {
|
||||
size(WIDTH, HEIGHT);
|
||||
}
|
||||
private void normalize_densities() {
|
||||
double total = 0.5 / (rabbits + foxes);
|
||||
rabbits *= total;
|
||||
foxes *= total;
|
||||
desert = 0.25;
|
||||
grass = 0.25;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
// smooth();
|
||||
SIZE = HEIGHT/n_boxes;
|
||||
set_traces();
|
||||
load_image();
|
||||
f = createFont("Arial",16,true);
|
||||
|
||||
for (int t = 0; t < 4; t += 1) {
|
||||
colors[t] = new Box(SIZE*n_boxes+PIC_SIZE*2*(t+1), PIC_SIZE/2, t, PIC_SIZE);
|
||||
} // for
|
||||
} // setup()
|
||||
|
||||
private void initialize() {
|
||||
get_values();
|
||||
normalize_densities();
|
||||
int k=0;
|
||||
for (int j = 0; j < n_boxes; j += 1) {
|
||||
// run over the ys
|
||||
for (int i = 0; i < n_boxes; i += 1) {
|
||||
int type = weighted_type();
|
||||
boxes[k] = new Box(i * SIZE, j * SIZE, type);
|
||||
neighs[k] = new Neighbours(i, j);
|
||||
k++;
|
||||
} // for
|
||||
} // for
|
||||
}
|
||||
private void get_values(){
|
||||
|
||||
|
||||
}
|
||||
|
||||
private int weighted_type(){
|
||||
float r = random(0,1);
|
||||
if (r < foxes) { return FOX;}
|
||||
else if (r < rabbits+foxes) {return RABBIT;}
|
||||
else if (r < rabbits+foxes+grass) {return GRASS;}
|
||||
else {return DESERT;}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (INIT_TODO){
|
||||
background(255);
|
||||
fill(255);
|
||||
stroke(0);
|
||||
textSize(60);
|
||||
rect(WIDTH*1/4 ,HEIGHT*1/2,WIDTH/2, PIC_SIZE);
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text("Scegli la percentuale di volpi e conigli", WIDTH/2, HEIGHT/2 -100);
|
||||
image(images_g[1], WIDTH*1/4 -2 - PIC_SIZE, HEIGHT*1/2 );
|
||||
image(images_g[0], WIDTH*3/4 +2, HEIGHT*1/2 );
|
||||
if (mousePressed){
|
||||
INIT_TODO = false;
|
||||
rect(WIDTH*1/4,HEIGHT*1/2,mouseX -WIDTH/4, PIC_SIZE);
|
||||
rabbits = (float) (mouseX - WIDTH *1/4);
|
||||
rabbits /= WIDTH/2;
|
||||
print(rabbits);
|
||||
print("\n");
|
||||
initialize();
|
||||
mousePressed = false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (keyPressed == true) {
|
||||
if (key == 'b' || key == 'B') {
|
||||
background(0);
|
||||
INIT_TODO = true;
|
||||
}
|
||||
}
|
||||
delay(20);
|
||||
time += 1;
|
||||
if (mousePressed) {
|
||||
box = get_clicked_box(mouseX, mouseY);
|
||||
if (box > -1) boxes[box].type = ROAD;
|
||||
print("the box", box, " ");
|
||||
print("\n");
|
||||
}
|
||||
if (time > 4) {
|
||||
time = 0;
|
||||
update_grid();
|
||||
update_traces();
|
||||
}
|
||||
background(255);
|
||||
|
||||
|
||||
plot_traces();
|
||||
for (int k = 0; k < 4; k++) {
|
||||
colors[k].make_borders();
|
||||
image(images_g[k],SIZE*n_boxes+PIC_SIZE*2*(k+1), PIC_SIZE/2);
|
||||
}
|
||||
for (int i = 0; i < nn; i++) {
|
||||
boxes[i].display(boxes[i].type);
|
||||
} // for
|
||||
|
||||
// print("size");
|
||||
// print(boxes[0].x);
|
||||
// print(boxes[0].x+boxes[0].w);
|
||||
}
|
||||
} // draw()
|
||||
|
||||
// ===============================================================
|
||||
private void count_boxes(){
|
||||
for (int n=0; n<5; n++) {
|
||||
counter[n] = 0;
|
||||
}
|
||||
for (int i = 0; i < nn; i++) {
|
||||
counter[boxes[i].type] +=1;
|
||||
}
|
||||
}
|
||||
|
||||
private void set_traces(){
|
||||
for (int i = 0; i < TRACES; i += 1) {
|
||||
traces[FOX][i] = (int) foxes;
|
||||
}
|
||||
for (int i = 0; i < TRACES; i += 1) {
|
||||
traces[RABBIT][i] = (int) rabbits;
|
||||
}
|
||||
for (int i = 0; i < TRACES; i += 1) {
|
||||
traces[GRASS][i] = (int) grass;
|
||||
}
|
||||
for (int i = 0; i < TRACES; i += 1) {
|
||||
traces[DESERT][i] = (int) desert;
|
||||
}
|
||||
}
|
||||
|
||||
private void update_traces(){
|
||||
count_boxes();
|
||||
for (int j = 0; j < 4; j += 1) {
|
||||
if (TRACES - 1 >= 0) {
|
||||
System.arraycopy(traces[j], 1, traces[j], 0, TRACES - 1);
|
||||
traces[j][TRACES-1] = counter[j];
|
||||
} else {
|
||||
traces[j][TRACES-1] = counter[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
public void arrow(int x1, int y1, int x2, int y2) {
|
||||
line(x1, y1, x2, y2);
|
||||
pushMatrix();
|
||||
translate(x2, y2);
|
||||
float a = atan2(x1-x2, y2-y1);
|
||||
rotate(a);
|
||||
line(0, 0, -10, -10);
|
||||
line(0, 0, 10, -10);
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
|
||||
private void plot_traces() {
|
||||
// float scale = 40 * PIC_SIZE;
|
||||
float mean;
|
||||
strokeWeight((float) 2.5);
|
||||
|
||||
textSize(20);
|
||||
textAlign(LEFT);
|
||||
stroke(182,22,63);
|
||||
text("Volpi", WIDTH/2 + 2*PIC_SIZE, 2*PIC_SIZE );
|
||||
arrow(WIDTH/2 + 2* PIC_SIZE, HEIGHT/2, WIDTH/2 + 2*PIC_SIZE, 2*PIC_SIZE);
|
||||
stroke(4,54,84);
|
||||
arrow(WIDTH/2 + 2* PIC_SIZE, HEIGHT/2, WIDTH- 2*PIC_SIZE, HEIGHT/2);
|
||||
text("Conigli", WIDTH - 2*PIC_SIZE + 5, HEIGHT/2 );
|
||||
stroke(0);
|
||||
for (int i = 0; i < TRACES-1; i += 1) {
|
||||
if (traces[RABBIT][i] > 0) {
|
||||
line(WIDTH/2+ 2*PIC_SIZE +WIDTH/2 *traces[RABBIT][i]/nn,
|
||||
HEIGHT/2 *(nn-traces[FOX][i])/nn,
|
||||
WIDTH/2+ 2*PIC_SIZE + WIDTH/2 *traces[RABBIT][i+1]/nn ,
|
||||
HEIGHT/2*(nn-traces[FOX][i + 1])/nn);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 4; j += 1) {
|
||||
mean = 0;
|
||||
for (int i = 0; i < TRACES-1; i += 1) {
|
||||
mean += traces[j][i];
|
||||
}
|
||||
mean /= TRACES;
|
||||
if (j==GRASS) {stroke(77,137,99);}
|
||||
else if (j==FOX) {stroke(182,22,63);}
|
||||
else if (j==DESERT) {stroke(244,148,0);}
|
||||
else if (j==RABBIT) {stroke(4,54,84);}
|
||||
|
||||
strokeWeight((float) 2.5);
|
||||
for (int i = 0; i < TRACES-1; i += 1) {
|
||||
if (traces[j][i] > 0) {
|
||||
line(HEIGHT + 200 +i*15,
|
||||
HEIGHT/2 +PIC_SIZE +(10 * PIC_SIZE * (traces[j][i] )/nn),
|
||||
HEIGHT + 200 +i*15+15,
|
||||
HEIGHT/2+ +PIC_SIZE +(10 * PIC_SIZE * (traces[j][i + 1])/nn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void load_image(){
|
||||
PImage im ;
|
||||
PImage im_g;
|
||||
for (int x=0; x < 5; x++ ) {
|
||||
im = loadImage(myFileArray[x]);
|
||||
im.resize(SIZE, SIZE);
|
||||
images[x] = im;
|
||||
}
|
||||
|
||||
for (int x=0; x < 5; x++ ) {
|
||||
im_g = loadImage(myFileArray[x]);
|
||||
im_g.resize(PIC_SIZE, PIC_SIZE);
|
||||
images_g[x] = im_g;
|
||||
}
|
||||
}
|
||||
|
||||
private void update_grid(){
|
||||
|
||||
int k =0;
|
||||
//for each box evolve by the rules
|
||||
//run over xs and ys
|
||||
boolean starve;
|
||||
for (int j = 0; j < n_boxes; j += 1) {
|
||||
for (int i = 0; i < n_boxes; i += 1) {
|
||||
// run over the ys
|
||||
// death conditions
|
||||
// fox dies if no rabbits
|
||||
if (boxes[k].type == ROAD) {
|
||||
boxes[k].next = ROAD;
|
||||
}
|
||||
if (boxes[k].type == FOX) {
|
||||
starve = true;
|
||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||
if (boxes[neighs[k].surround[n]].type == RABBIT) {
|
||||
// there is AT LEAST a rabbit, no starvation
|
||||
starve = false;
|
||||
break;
|
||||
}
|
||||
if (boxes[neighs[k].surround[n]].type == DESERT) {
|
||||
// there is AT LEAST a desert, starvation
|
||||
// break;
|
||||
}
|
||||
}
|
||||
if (starve) {boxes[k].next = DESERT;}
|
||||
}
|
||||
// rabbit dies if no grass
|
||||
if (boxes[k].type == RABBIT) {
|
||||
starve = true;
|
||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||
if (boxes[neighs[k].surround[n]].type == GRASS) {
|
||||
// there is AT LEAST a grass, no starvation
|
||||
starve = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (starve) {boxes[k].next = DESERT;}
|
||||
}
|
||||
// birth conditions
|
||||
// fox is born eating rabbit
|
||||
if (boxes[k].type == RABBIT) {
|
||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||
if (boxes[neighs[k].surround[n]].type == FOX) {
|
||||
boxes[k].next = FOX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// rabbit is born eating grass
|
||||
if (boxes[k].type == GRASS) {
|
||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||
if (boxes[neighs[k].surround[n]].type == RABBIT) {
|
||||
boxes[k].next = RABBIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// grass grows where desert
|
||||
if (boxes[k].type == DESERT) {
|
||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||
if (boxes[neighs[k].surround[n]].type == GRASS) {
|
||||
boxes[k].next = GRASS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
k = 0;
|
||||
for (int j = 0; j < n_boxes; j += 1) {
|
||||
// run over the ys
|
||||
for (int i = 0; i < n_boxes; i += 1) {
|
||||
boxes[k].type = boxes[k].next;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int get_clicked_box(int x, int y){
|
||||
int box =-1;
|
||||
for (int i = 0; i < nn; i += n_boxes) {
|
||||
if (boxes[i].y < y && y < +boxes[i].yend) {
|
||||
print(i);
|
||||
for (int j = 0; j < n_boxes; j += 1) {
|
||||
if (boxes[j+i].x < x && x < + boxes[j+i].xend){
|
||||
box = j+i;
|
||||
print(boxes[j+i].y, " ", y, " ", boxes[j+i].yend, i, " ");
|
||||
print(boxes[j+i].x, " ", x, " ", boxes[j+i].xend, i, " ");
|
||||
print("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return box;
|
||||
|
||||
}
|
||||
|
||||
class Box {
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float xend;
|
||||
float yend;
|
||||
|
||||
float w=SIZE;
|
||||
float h=SIZE;
|
||||
|
||||
int type;
|
||||
int next;
|
||||
|
||||
|
||||
// constr
|
||||
|
||||
Box ( float x, float y, int type, int size) {
|
||||
this.x=x;
|
||||
this.y=y;
|
||||
this.w = size;
|
||||
this.h = size;
|
||||
this.xend=x+size;
|
||||
this.yend=y+size;
|
||||
this.type =type;
|
||||
this.next =type;
|
||||
} // constr
|
||||
Box ( float x, float y, int type) {
|
||||
this.x=x;
|
||||
this.y=y;
|
||||
this.type =type;
|
||||
this.next =type;
|
||||
this.xend=x+this.w;
|
||||
this.yend=y+this.h;
|
||||
} // constr
|
||||
|
||||
void make_borders() {
|
||||
int j = type;
|
||||
if (j==GRASS) {stroke(77,137,99);}
|
||||
else if (j==FOX) {stroke(182,22,63);}
|
||||
else if (j==DESERT) {stroke(244,148,0);}
|
||||
else if (j==RABBIT) {stroke(4,54,84);}
|
||||
strokeWeight(10);
|
||||
rect(x, y, w, h);
|
||||
}
|
||||
|
||||
void display(int n) {
|
||||
// fill(50*type, 32, 0);
|
||||
// stroke(0);
|
||||
// rect (x, y, w, h);
|
||||
// print(n);
|
||||
image(images[n], x, y);
|
||||
// image(images[type], x,y);
|
||||
|
||||
|
||||
// println (x);
|
||||
} // method
|
||||
} // class
|
||||
|
||||
class Neighbours {
|
||||
int x;
|
||||
int y;
|
||||
int [] surround;
|
||||
|
||||
Neighbours( int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
if (DIAGONAL) {
|
||||
int N = 8;
|
||||
int[] xs= new int[N];
|
||||
int[] ys= new int[N];
|
||||
|
||||
ys[0] = (n_boxes + y-1)%n_boxes;
|
||||
ys[1] = ys[0];
|
||||
ys[2] = ys[0];
|
||||
ys[3] = y; ys[4] = y;
|
||||
ys[5] = (y+1)%n_boxes;
|
||||
ys[6] = ys[5];
|
||||
ys[7] = ys[5];
|
||||
|
||||
xs[0] = (n_boxes + x-1)%n_boxes;
|
||||
xs[1] = x;
|
||||
xs[2] = (x+1) %n_boxes;
|
||||
xs[3] = xs[0]; xs[4] =xs[2];
|
||||
xs[5] = xs[0];
|
||||
xs[6] = x;
|
||||
xs[7] = xs[2];
|
||||
|
||||
this.surround = new int[N];
|
||||
|
||||
for (int i=0; i<N; i++){
|
||||
surround[i] = xs[i]+ys[i]*n_boxes;
|
||||
}
|
||||
}
|
||||
else{
|
||||
int N = 4;
|
||||
int[] xs= new int[N];
|
||||
int[] ys= new int[N];
|
||||
this.surround = new int[N];
|
||||
|
||||
ys[0] = (n_boxes + y-1)%n_boxes;
|
||||
ys[1] = y;
|
||||
ys[2] = y;
|
||||
ys[3] = (y+1)%n_boxes;
|
||||
xs[0] = x;
|
||||
xs[1] = (n_boxes + x-1)%n_boxes;
|
||||
xs[2] = (x+1) %n_boxes;
|
||||
xs[3] = x;
|
||||
// print("\n##");
|
||||
for (int i=0; i<N; i++){
|
||||
surround[i] = xs[i]+(ys[i]*n_boxes);
|
||||
}
|
||||
// print("\n##\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public static void main (String... args) {
|
||||
Predator pt = new Predator();
|
||||
PApplet.runSketch(new String[]{"ProcessingTest"}, pt);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue