//greyscale_5_bridge //Tonje Stolpestad // 10/06/09 // Dynamics of Genetic information in biological populations // Hampshire Collge // A simple reproduction of simulations shown in "What, if anything, is a wolf" by Coppinger, Spector and Miller // Version 5_bridge: simple road with a fence to keep the marbles off the road // the road has a bridge over it. // This particular version has a collision rate of 40, max age of 600, and a normal move rate. // No bridges. Base version 7_3 PrintWriter output; //window int winWidth = 1000; int winHeight = 700; //road and bridge int roadWidth = 200; int halfBridgeHeight = 0; int road1X1; int road1X2; int road2X1; int road2X2; int road1Y1; int road1Y2; int road2Y1; int road2Y2; //circles int rad = 7; int movrat = 2; int maxAge = 600; int timeStep = 0; int coor1 = 0; int coor2 = 0; int[] id = {0, 1, 2, 3}; int[] age = {1, 1, 1, 1}; int[] generation = {1,1,1,1}; int[] parent = {0,0,0,0}; int[] gene1 = {int(random(230)), int(random(230)), int(random(230)), int(random(230))}; int[] gene2 = {int(random(230)), int(random(230)), int(random(230)), int(random(230))}; int[] gene3 = {int(random(230)), int(random(230)), int(random(230)), int(random(230))}; int[] xcoor = {winWidth/5, winWidth/2, winWidth/2, winWidth/5}; int[] xBirth = {xcoor[0], xcoor[1], xcoor[2], xcoor[3]}; int[] ycoor = {winHeight/2, winHeight/5, 600, winHeight/5}; int[] yBirth = {ycoor[0], ycoor[1], ycoor[2], ycoor[3]}; int[] xmov = {int(random(-movrat,movrat)), int(random(-movrat,movrat)), int(random(-movrat,movrat)), int(random(-movrat,movrat))}; int[] ymov = {int(random(-movrat,movrat)), int(random(-movrat,movrat)), int(random(-movrat,movrat)), int(random(-movrat,movrat))}; int[][] tag = new int[510][1]; int[] mates ={}; String filename; void setup(){ size (winWidth, winHeight); //halfBridgeHeight = (5*rad); road1X1 = winWidth/3 - roadWidth/2; road1X2 = winWidth/3 + roadWidth/2; road1Y1 = 2*halfBridgeHeight; road1Y2 = winHeight - 2*halfBridgeHeight; road2X1 = road1X2; road2X2 = winWidth - 2*halfBridgeHeight; road2Y1 = winHeight/2 - roadWidth/2; road2Y2 = winHeight/2 + roadWidth/2; for (int n =0; n < 4; n++){ tag[n][0] = 1; } int mDate = month(); int dDate = day(); int hDate = hour(); int minDate = minute(); String s = String.valueOf(mDate) + String.valueOf(dDate) + String.valueOf(hDate)+String.valueOf(minDate); filename = "data" + s + ".txt"; output = createWriter(filename); output.println("Id, Generation, Parent, Bridge Width, Birth place x, Birth place y, color1, color2, color3, Place of death x, Place of Death y, Time of death, Tag Array "); } void draw() { background(255); if (timeStep < 10000){ fill(0); rect(winWidth/3 - roadWidth/2, 2*halfBridgeHeight, roadWidth, winHeight-4*halfBridgeHeight); rect(winWidth/3+roadWidth/2, winHeight/2-roadWidth/2, (winWidth - (winWidth/3 + roadWidth/2) -2*halfBridgeHeight), roadWidth); timeStep = timeStep +1; if( gene1.length < 2){ extinct(); } for( int i = 0; i 0) & (xcoor[i] < road1X1)){ int tagIndex = tag[i].length -1; if (tag[i][tagIndex] != 1){ tag[i] = append(tag[i], 1);} } else if ((xcoor[i] > road1X2) & (xcoor[i] < winWidth) & (ycoor[i] > 0) &(ycoor[i] < road2Y1)){ int tagIndex = tag[i].length -1; if (tag[i][tagIndex] != 2){ tag[i] = append(tag[i], 2);} } else if ((xcoor[i] > road1X2) & (xcoor[i] < winWidth) & (ycoor[i] > road2Y2) & (ycoor[i] < winHeight)){ int tagIndex = tag[i].length -1; if (tag[i][tagIndex] != 3){ tag[i] = append(tag[i], 3);} } else { int tagIndex = tag[i].length -1; if (tag[i][tagIndex] != 0){ tag[i] = append(tag[i], 0);}} if (age[i] > maxAge){//get rid of the dead marbles, //saving the data //write the tag array to a string String tagString = ""; for (int q = 0; q < tag[i].length; q++){ tagString = tagString + tag[i][q] + " ";} output.println(id[i] + ", " + generation[i] + ", " +parent[i] +", " + 2*halfBridgeHeight + ", " +xBirth[i] +", "+ yBirth[i] + ", " + gene1[i] +", " + xcoor[i] + ", " + ycoor[i] + ", " + timeStep +", " + tagString ); marbleDecay(i); } else if (age[i] < maxAge) { // check for the age, do only work with alive subjects //drawing the circle fill(gene1[i], gene2[i], gene3[i]); ellipse(xcoor[i], ycoor[i], rad, rad); //moving and collision detection smoosh(i); colDect(i); xcoor[i] = xcoor[i] + xmov[i]; ycoor[i] = ycoor[i] + ymov[i]; //Breeding breeding(i); } } } } else{ theEndIsNear();} } void smoosh(int i){ //chance of getting hit by a car //Jumping the fences if ((xcoor[i] +rad >road1X1) & (xcoor[i] +rad road1Y1)& (ycoor[i]-rad < road1Y2)){ xmov[i] = -1; } if ((ycoor[i] +rad >road2Y1) & (ycoor[i] +rad road2X1)& (xcoor[i]-rad < road2X2)){ ymov[i] = -1; } if ((xcoor[i] -rad <(road1X2)) & (xcoor[i] -rad >road1X2-3)&(ycoor[i]+rad > road1Y1)&(ycoor[i]-rad < road1Y2)){ xmov[i] = 1; } if ((ycoor[i] -rad <(road2Y2)) & (ycoor[i] -rad >road2Y2-3)&(xcoor[i]+rad > road2X1)&(xcoor[i]-rad < road2X2)){ ymov[i] = 1; } // bridge walls if ((xcoor[i]+rad > road1X1)&(xcoor[i]-rad < road1X2) & (ycoor[i]+rad > road1Y1) & (ycoor[i]+rad < road1Y1+3)){ ymov[i] = -1;} if ((xcoor[i]+rad > road1X1)&(xcoor[i]-rad < road1X2) & (ycoor[i]-rad > road1Y2) & (ycoor[i]-rad < road1Y2+3)){ ymov[i] = 1;} if ((ycoor[i]+rad > road2Y1)&(ycoor[i]-rad < road2Y2) & (xcoor[i]-rad > road2X2) & (xcoor[i]-rad < road2X2+3)){ xmov[i] = 1;} } void colDect(int i){ // Collision detection on the walls // x coor if (xcoor[i] < rad+1){ xmov[i] = int(random(1,movrat));} if (xcoor[i] > winWidth-(rad+1)){ xmov[i] = int(random(-1,-movrat));} // y coor if (ycoor[i] < rad+1){ ymov[i] = int(random(1,movrat));} if (ycoor[i] > winHeight-(rad+1)){ ymov[i] = int(random(-1,-movrat));} //Collision detection on other circles for (int j = 0; j< age.length; j++){ if (j!=i){ if ((xcoor[j] > (xcoor[i]-rad-1) & xcoor[j] < (xcoor[i] +rad+1)) &(ycoor[j] > (ycoor[i] -rad-1) & ycoor[j] < (ycoor[i] +rad+1))){ // xmov[i] = - xmov[i]; // ymov[i] = - ymov[i]; age[i] = age[i] +10; }}} } void breeding(int i){ int breed = int(random(100)); int mutate = int(random(20)); if (breed == 1){ // it had a baby! Let's name it Dolly for (int k =0; k (xcoor[i]-3*rad) & xcoor[k] < (xcoor[i] +3*rad)) &(ycoor[k] > (ycoor[i] -3*rad) & ycoor[k] < (ycoor[i] +3*rad))){ mates = append(mates, k); } }} if (mates.length > 0){ int parent = int(random(1,2)); // choose parent if (parent ==1){ //mate is used int highestMate = mates.length - 1; int whichMate = int(random(mates.length -1)); int mateIndex = mates[whichMate]; if (mutate == 2){// it mutates gene1 = append(gene1, int(random(gene1[mateIndex]-20, gene1[mateIndex]+20))); gene2 = append(gene2, gene2[mateIndex]); gene3 = append(gene3, gene3[mateIndex]);} else {//no mutation, mates genes used gene1 = append(gene1, gene1[mateIndex]); gene2 = append(gene2, gene2[mateIndex]); gene3 = append(gene3, gene3[mateIndex]);} int [] noMates = {}; mates = noMates; } else { // we are using parent breedFromParent(i, mutate); } } else{ // asexual reproduction breedFromParent(i, mutate); } coor1 = xcoor[i]; coor2 = ycoor[i]; xcoor = append(xcoor, coor1); ycoor = append(ycoor, coor2); xBirth = append(xBirth, coor1); yBirth = append(yBirth, coor2); //age and test for breeding on road if ((coor1 >road1X1) & (coor1 road1X1) &(coor2 > road2Y1) & (coor2 < road2Y2)){ age = append(age, 300);} else{ age = append(age, 1);} //tagging int tagIndex = tag[i].length -1; int newTag = tag [i][tagIndex]; int newTagIndex = gene1.length -1; tag[newTagIndex][0] = newTag; //generation, id and parent generation = append(generation, generation[i] +1); int maxid = id[(id.length -1)]; id = append(id, maxid+1); parent = append(parent, id[i]); //movement xmov = append(xmov, int(random(-movrat,movrat))); ymov = append(ymov, int(random(-movrat,movrat))); }} void marbleDecay(int i){ //id int[] newid = {}; for (int p =0; p