PopulationModel.java 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. package main.java.com.lotkavolterra;
  2. import processing.core.PFont;
  3. import processing.core.PApplet;
  4. public class PopulationModel extends Graphs {
  5. // Distributions
  6. Densities densities = new Densities(0.,0.,0.5,0.5);
  7. Bar fox_bar;
  8. Bar rabbit_bar;
  9. Button start;
  10. Button restart;
  11. Slider speed;
  12. // visualization
  13. PFont f;
  14. int box = -1 ;
  15. double time = 0;
  16. boolean INIT_TODO = true;
  17. boolean RUN_SIMULATION = false;
  18. @Override
  19. public void settings() {
  20. size(WIDTH, HEIGHT);
  21. }
  22. @Override
  23. public void setup() {
  24. SIZE =HEIGHT/n_boxes;
  25. set_traces(densities);
  26. load_image();
  27. f = createFont("Arial",16,true);
  28. for (int t = 0; t < 4; t += 1) {
  29. colors[t] = new Structs.Box(SIZE*n_boxes+PIC_SIZE*2*(t+1), PIC_SIZE/2, t, PIC_SIZE);
  30. } // for
  31. strokeWeight(3);
  32. fox_bar = new Bar(WIDTH * 1 / 4, HEIGHT * 1 / 2, WIDTH / 2, PIC_SIZE);
  33. rabbit_bar = new Bar(WIDTH * 1 / 4, HEIGHT * 1 / 2 +100, WIDTH / 2, PIC_SIZE);
  34. start = new Button("Start", WIDTH * 3/4-100, HEIGHT * 3/4, WIDTH/4, PIC_SIZE);
  35. speed = new Slider("Speed", WIDTH* 85/100, HEIGHT* 3/10, WIDTH*1/10);
  36. restart = new Button("Restart", WIDTH* 85/100, (float)(HEIGHT* 3/10 + PIC_SIZE), WIDTH*1/10, PIC_SIZE);
  37. } // setup()
  38. @Override
  39. public void draw() {
  40. if (INIT_TODO){
  41. background(255);
  42. fill(0);
  43. stroke(0);
  44. textSize(40);
  45. textAlign(CENTER);
  46. text("Scegli la percentuale di volpi e conigli", WIDTH/2, HEIGHT/2 -200);
  47. image(images_g[1], WIDTH*1/4 - PIC_SIZE -5 , HEIGHT*1/2 +100);
  48. image(images_g[0], WIDTH*1/4 - PIC_SIZE -5, HEIGHT*1/2 );
  49. draw_box(fox_bar);
  50. draw_box(rabbit_bar);
  51. draw_button(start);
  52. if (mousePressed){
  53. fox_bar.MouseIsOver(mouseX, mouseY);
  54. rabbit_bar.MouseIsOver(mouseX, mouseY);
  55. if (start.MouseIsOver(mouseX, mouseY)){
  56. INIT_TODO = false;
  57. densities.foxes= fox_bar.get_value();
  58. densities.rabbits= rabbit_bar.get_value();
  59. println(densities.desert, densities.foxes, densities.grass, densities.rabbits);
  60. initialize();
  61. println(densities.foxes, densities.rabbits);
  62. println(counter);
  63. }
  64. mousePressed = false;
  65. }
  66. }
  67. else{
  68. if (keyPressed == true) {
  69. if (key == 'q' || key == 'Q') {
  70. background(0);
  71. INIT_TODO = true;
  72. }
  73. }
  74. time += 5*speed.get_speed();
  75. delay(20);
  76. if (mousePressed) {
  77. box = get_clicked_box(mouseX, mouseY);
  78. if (box > -1) boxes[box].type = ROAD;
  79. speed.MouseIsOver(mouseX, mouseY);
  80. if (restart.MouseIsOver(mouseX, mouseY)) {INIT_TODO = true;}
  81. }
  82. if (time >10)
  83. {
  84. time=0;
  85. update_grid();
  86. update_traces();
  87. }
  88. background(255);
  89. draw_slider(speed);
  90. draw_button(restart);
  91. plot_traces();
  92. for (int k = 0; k < 4; k++) {
  93. colors[k].make_borders();
  94. image(images_g[k],SIZE*n_boxes+PIC_SIZE*2*(k+1), PIC_SIZE/2);
  95. }
  96. for (int i = 0; i < nn; i++) {
  97. boxes[i].display(boxes[i].type);
  98. } // for
  99. // print("size");
  100. // print(boxes[0].x);
  101. // print(boxes[0].x+boxes[0].w);
  102. }
  103. } // draw()
  104. // ===============================================================
  105. private void normalize_densities(Densities d) {
  106. d.rabbits = d.rabbits/2;
  107. d.foxes = d.foxes/2;
  108. d.desert = 0.25;
  109. d.grass = 0.25;
  110. }
  111. private int weighted_type(Densities d) {
  112. float r = random(0, 1);
  113. if (r < d.foxes) {
  114. return FOX;
  115. } else if (r < d.rabbits + d.foxes) {
  116. return RABBIT;
  117. } else if (r < d.rabbits + d.foxes + d.grass) {
  118. return GRASS;
  119. } else {
  120. return DESERT;
  121. }
  122. }
  123. private void initialize() {
  124. normalize_densities(densities);
  125. int k=0;
  126. for (int j = 0; j < n_boxes; j += 1) {
  127. // run over the ys
  128. for (int i = 0; i < n_boxes; i += 1) {
  129. int type = weighted_type(densities);
  130. boxes[k] = new Structs.Box(i * SIZE, j * SIZE, type);
  131. neighs[k] = new Structs.Neighbours(i, j);
  132. k++;
  133. } // for
  134. } // for
  135. }
  136. //===============================================================
  137. // Evolution algorithm
  138. private void update_grid(){
  139. int k =0;
  140. //for each box evolve by the rules
  141. //run over xs and ys
  142. boolean starve;
  143. for (int j = 0; j < n_boxes; j += 1) {
  144. for (int i = 0; i < n_boxes; i += 1) {
  145. // run over the ys
  146. // death conditions
  147. // fox dies if no rabbits
  148. if (boxes[k].type == ROAD) {
  149. boxes[k].next = ROAD;
  150. }
  151. if (boxes[k].type == FOX) {
  152. starve = true;
  153. for (int n = 0; n < neighs[k].surround.length; n++) {
  154. if (boxes[neighs[k].surround[n]].type == RABBIT) {
  155. // there is AT LEAST a rabbit, no starvation
  156. starve = false;
  157. break;
  158. }
  159. if (boxes[neighs[k].surround[n]].type == DESERT) {
  160. // there is AT LEAST a desert, starvation
  161. // break;
  162. }
  163. }
  164. if (starve) {boxes[k].next = DESERT;}
  165. }
  166. // rabbit dies if no grass
  167. if (boxes[k].type == RABBIT) {
  168. starve = true;
  169. for (int n = 0; n < neighs[k].surround.length; n++) {
  170. if (boxes[neighs[k].surround[n]].type == GRASS) {
  171. // there is AT LEAST a grass, no starvation
  172. starve = false;
  173. break;
  174. }
  175. }
  176. if (starve) {boxes[k].next = DESERT;}
  177. }
  178. // birth conditions
  179. // fox is born eating rabbit
  180. if (boxes[k].type == RABBIT) {
  181. for (int n = 0; n < neighs[k].surround.length; n++) {
  182. if (boxes[neighs[k].surround[n]].type == FOX) {
  183. boxes[k].next = FOX;
  184. break;
  185. }
  186. }
  187. }
  188. // rabbit is born eating grass
  189. if (boxes[k].type == GRASS) {
  190. for (int n = 0; n < neighs[k].surround.length; n++) {
  191. if (boxes[neighs[k].surround[n]].type == RABBIT) {
  192. boxes[k].next = RABBIT;
  193. break;
  194. }
  195. }
  196. }
  197. // grass grows where desert
  198. if (boxes[k].type == DESERT) {
  199. for (int n = 0; n < neighs[k].surround.length; n++) {
  200. if (boxes[neighs[k].surround[n]].type == GRASS) {
  201. boxes[k].next = GRASS;
  202. break;
  203. }
  204. }
  205. }
  206. k++;
  207. }
  208. }
  209. k = 0;
  210. for (int j = 0; j < n_boxes; j += 1) {
  211. // run over the ys
  212. for (int i = 0; i < n_boxes; i += 1) {
  213. boxes[k].type = boxes[k].next;
  214. k++;
  215. }
  216. }
  217. }
  218. private int get_clicked_box(int x, int y){
  219. int box =-1;
  220. for (int i = 0; i < nn; i += n_boxes) {
  221. if (boxes[i].y < y && y < +boxes[i].yend) {
  222. for (int j = 0; j < n_boxes; j += 1) {
  223. if (boxes[j+i].x < x && x < + boxes[j+i].xend){
  224. box = j+i;
  225. break;
  226. }
  227. }
  228. }
  229. }
  230. return box;
  231. }
  232. public static void main (String... args) {
  233. PopulationModel pt = new PopulationModel();
  234. runSketch(new String[]{"PopulationModel"}, pt);
  235. }
  236. // public static void main(String[] passedArgs) {
  237. // String[] appletArgs = new String[] { "PopulationModel" };
  238. // PApplet.main(appletArgs);
  239. // }
  240. }