//size versus energy //real proportions // -------------------------------- step begin -------------------------------- function reproduce_haploid(repro_list, number) { var len = repro_list.size; if (len % 2 != 0) len = repro_list.size - 1; for (var i = 0; i < len - 2 ; i = i + 2) { var parent = Populations[0].get(repro_list[i]); var parent2 = Populations[0].get(repro_list[i + 1]); number = parent.user2["Va"] / ExpParams.ofnumd + parent2.user2["Va"] / ExpParams.ofnumd; for (var j = 0; j < number; j++) { //size var rsize = (parent.user1["delta_d"] + ExpParams.diplo_rad); if (Math.rnd01 < 0.5) { rsize = parent2.user1["delta_d"] + ExpParams.diplo_rad; } var deltas = parent.user1["delta_d"]; //mutation if (Math.rnd01 < ExpParams.mutationprob) { var diff = delta_change * deltas; if (Math.rnd01 < 0.5) { deltas -= diff; } else { deltas += diff; } rsize = ExpParams.diplo_rad + deltas; } var cr = Populations[0].add("//0\np:sh=1,sx=" + rsize + ",sy=" + rsize + ",sz=" + rsize + ", rz=3.14159265358979"); cr.energ0 = ExpParams.ofnumd; cr.energy = cr.energ0; var dsize = ExpParams.diplo_rad * ExpParams.delta_rate + ExpParams.diplo_rad; cr.user1 = [ {"vamin" : (rsize / dsize) * ExpParams.v_min_d, "amin": parent.user1["amin"], "delta_h" : parent.user1["delta_h"], "delta_d" : deltas }, {"vamin" : (rsize / dsize) * ExpParams.v_min_d, "amin": parent2.user1["amin"], "delta_h" : parent2.user1["delta_h"], "delta_d" : deltas }]; cr.user2 = { "Va" : cr.energ0, "gen" : 1 , "growth_step" : ExpParams.growth_step, "rsize": rsize, "vinit": cr.energ0}; placeRandomlyNotColliding(cr); } } for (var j = 0; j < repro_list.size; j++) { Populations[0].kill(repro_list[j]); } } function reproduce_diploid(repro_list, number) { for (var i = 0; i < repro_list.size; i++) { var parent = Populations[0].get(repro_list[i]); if (parent.user2["gen"] == 1) { var number = parent.user2["Va"] / ExpParams.ofnumh; for (var j = 0; j < number / 2; j++) { var crossed = 0; //crossover if (Math.rnd01 < ExpParams.crossprob) { var tmp = parent.user1[0]["vamin"]; parent.user1[0]["vamin"] = parent.user1[1]["vamin"]; parent.user1[1]["vamin"] = tmp; crossed = 1; } for (var k = 0; k < 2; k++) { var rsize = parent.user1[k]["delta_h"] + ExpParams.haplo_rad; var vamin = parent.user1[k]["vamin"]; var deltas = parent.user1[k]["delta_h"]; if (Math.rnd01 < ExpParams.mutationprob) { var diff = delta_change * deltas; if (Math.rnd01 < 0.5) { deltas -= diff; } else { deltas += diff; } rsize = ExpParams.diplo_rad + deltas; } var geno = "//0\np:sh=1,sx=" + rsize + ",sy=" + rsize + ",sz=" + rsize + ", rz=3.14159265358979"; geno += "\nn:p=0,d=\"S\""; //TODO is this the only difference with haploid code? TODO why initial genotypes are not used as defined in ExpParams? var cr = Populations[0].add(geno); cr.energ0 = ExpParams.ofnumh; cr.energy = cr.energ0; //vamin depends on rsize var hsize = ExpParams.haplo_rad * ExpParams.delta_rate + ExpParams.haplo_rad; cr.user1 = {"vamin" : (rsize / hsize) * ExpParams.v_min_h, "amin": ExpParams.age_min_d, "delta_h" : deltas, "delta_d" : parent.user1[0]["delta_d"]}; cr.user2 = { "Va" : cr.energ0, "gen" : 0 , "growth_step" : ExpParams.growth_step, "rsize" : rsize, "vinit": cr.energ0}; placeRandomlyNotColliding(cr); } //reverse of crossover for fossilization if (crossed == 1) { var tmp = parent.user1[0]["vamin"]; parent.user1[0]["vamin"] = parent.user1[1]["vamin"]; parent.user1[1]["vamin"] = tmp; crossed = 0; } } } } for (var j = 0; j < repro_list.size; j++) { Populations[0].kill(repro_list[j]); } } function onStep() { var haploids = 0; var diploids = 0; var e_inc_h = 0.0; var e_inc_d = 0.0; var e_nut = 0.0; var size_h = 0.0; var size_d = 0.0; var vmin_h = 0.0; var vmin_d = 0.0; for (var i = 0; i < Populations[0].size; i++) { var cr = Populations[0].get(i); if (cr.user2["gen"] == 0) { haploids += 1; e_inc_h += cr.energy; size_h += cr.user1["delta_h"] + ExpParams.haplo_rad; vmin_h += cr.user1["vamin"]; } else if (cr.user2["gen"] == 1) { diploids += 1; e_inc_d += cr.energy; size_d += cr.user1[0]["delta_d"] + ExpParams.diplo_rad; vmin_d += cr.user1[0]["vamin"]; } } for (var i = 0; i < Populations[1].size; i++) { var cr = Populations[1].get(i); e_nut += cr.energy; } if (haploids < 2 && diploids == 0) { Simulator.print("no more creatures, stopped."); Simulator.stop(); } var l1 = [haploids, diploids, Populations[1].size]; var l2 = [e_inc_h, e_inc_d, e_nut]; var dp = diploids; var hp = haploids; if (dp == 0) dp = 0.000001; if (hp == 0) hp = 0.000001; var l3 = [size_h / hp, vmin_h / hp, size_d / dp, vmin_d / dp]; if (ExpParams.logging == 1) { log(l1, "log.txt"); log(l2, "log2.txt"); log(l3, "log3.txt"); } //food growth --------------------------------------------- foodenergywaiting = foodenergywaiting + ExpParams.feedrate; if (foodenergywaiting > ExpParams.feede0) { for (var i = 0; i < ExpParams.foodPop; i++) { addfood(); } foodenergywaiting = 0.0; Simulator.checkpoint(); } //reproduction -------------------------------------------- reprocounter += 1; if (reprocounter > ExpParams.repro_time) { reprocounter = 0; var to_repro_h = []; var to_repro_d = []; for (var i = 0; i < Populations[0].size; i++) { var cr = Populations[0].get(i); if (cr.signals.size > 0) { if (cr.user2["gen"] == 0) { to_repro_h.add(i); } else if (cr.user2["gen"] == 1) { to_repro_d.add(i); } } } if (to_repro_h.size > 1) { reproduce_haploid(to_repro_h, ExpParams.ofnumh); } if (to_repro_d.size > 0) { reproduce_diploid(to_repro_d, ExpParams.ofnumd); } } //check for death ----------------------------------------------- if (Populations[0].size == 0) { if (ExpParams.autorestart) { Simulator.print("no more creatures, restarting..."); onExpInit(); } else { Simulator.print("no more creatures, stopped."); Simulator.stop(); } } } // -------------------------------- step end --------------------------------