//size versus energy //real proportions function init_chambers() { colors = ["1.0,1.0,0.0","1.0,0.5,0.0"]; chambers = [ ["0.0,0.0,0.0,", //longitudal "0.98089325428009, 0.00591040402650833, 0.00389722990803421,", "1.90962779521942, -0.256769120693207, -0.16194811463356,", "2.63965249061584, -0.727959632873535, -0.609036147594452,", "3.17575979232788, -1.34843015670776, -1.14828503131866,", "3.55273032188416, -2.22369408607483, -1.3917418718338,", "3.64916682243347, -3.11888360977173, -1.01666414737701,", "3.50461649894714, -3.84039807319641, -0.377427101135254,", "3.15921688079834, -4.50001525878906, 0.261153399944305,", "2.51528453826904, -5.16421365737915, 0.59241509437561,"], ["0.0,0.0,0.0,", //coiled "1.08020961284637, -0.0597195439040661, -0.0393781512975693,", "1.08020961284637, -0.0597195439040661, -0.0393781512975693,", "0.615013539791107, 0.778662621974945, 0.535521030426025,", "0.488581955432892, 0.826426684856415, -0.381044268608093,", "0.732419908046722, -0.0084995785728097, -1.02214300632477,", "1.35288727283478, 0.875738024711609, -1.03719782829285,", "0.342692613601685, 0.938660383224487, -1.45657968521118,", "1.0958571434021, 0.316927701234818, -1.813929438591,", "0.903768002986908, 1.11856341362, -2.53161096572876,", "0.21014116704464, 0.295340299606323, -2.45328187942505,"] ]; } function createForamGenotype(gen, species, chamber_num) { var rad = getProperty(gen, "chamber_proculus"); var geno = "//0\np:" + chambers[species][0] + "sh=1,sx=" + rad + ",sy=" + rad + ",sz=" + rad + ", rz=3.14159265358979,vr=" + colors[gen]; chamber_num = Math.min(chamber_num, chambers[species].size - 1); for (var i = 0; i < chamber_num; i++) { rad = getProperty(gen, "chamber_proculus") + getProperty(gen, "chamber_difference") * (i + 1); geno += "\n" + "p:" + chambers[species][i+1] + "sh=1,sx=" + rad + ",sy=" + rad + ",sz=" + rad + ",vr=" + colors[gen]; } for (var i = 0; i < chamber_num; i++) { geno += "\n" + "j:"+ i +", "+ (i+1) +", sh=1"; } if (species == 1) geno += "\nn:p=0,d=\"S\""; return geno; } function setGenotype(mode) { if (mode["opt"] == 0) //initial { mode["cr"].user1 = {"min_repro_energies" : [max_chamber_energ[0][getProperty(0, "min_repro_energ")], max_chamber_energ[1][getProperty(1, "min_repro_energ")]], "hibernation" : 1 - mode["species"]}; mode["cr"].user2 = {"max_energy_level" : getProperty(0,"energies0"), "gen" : 0, "hibernated" : 0, "species" : mode["species"], "reproduce" : 0}; } else if (mode["opt"] == 1) //child { mode["cr"].user2 = {"max_energy_level" : getProperty(1 - mode["parent_user2"]["gen"],"energies0"), "gen" : 1 - mode["parent_user2"]["gen"], "hibernated" : 0, "species" : mode["parent_user2"]["species"], "reproduce" : 0}; mode["cr"].user1 = mode["parent_user1"]; } else //grow { mode["cr"].user1 = mode["parent_user1"]; mode["cr"].user2 = mode["parent_user2"]; } } function reproduce_haploid(parent, parent2, clone) { var number, energy0, new_user1, gen; if (clone == 1) { energy0 = getProperty(0,"energies0"); number = (( 1 - getProperty(1, "e_repro_cost")) * parent.energy) / energy0; new_user1 = parent.user1; parent.user2["gen"] = 1 - parent.user2["gen"]; //because of reversal of "gen" in createOffspring function gen = parent.user2["gen"]; } else { energy0 = getProperty(1,"energies0"); number = (((1 - getProperty(parent.user2["gen"], "e_repro_cost")) * parent.energy) + ((1 -(getProperty(parent.user2["gen"], "e_repro_cost"))) * parent2.energy)) / energy0; new_user1 = [parent.user1, parent2.user1]; gen = 1 - parent.user2["gen"]; } Simulator.print("haploid number of offspring: " + number + " energ0: " + energy0); for (var j = 0; j < number; j++) { createOffspring(createForamGenotype(gen, parent.user2["species"], 0), energy0, new_user1, parent.user2); } } function reproduce_diploid(parent) { var energy0 = getProperty(0,"energies0"); var number = ((1 - (getProperty(parent.user2["gen"], "e_repro_cost"))) * parent.energy) / energy0; Simulator.print("diploid number of offspring: " + number+ " energ0: " + energy0); for (var j = 0; j < number / 2; j++) { var crossed = 0; //crossover if (Math.rnd01 < ExpParams.crossprob) { crossover(parent, "min_repro_energies"); crossed = 1; } for (var k = 0; k < 2; k++) { createOffspring(createForamGenotype(1 - parent.user2["gen"], parent.user2["species"], 0), energy0, parent.user1[0], parent.user2); } //reverse of crossover for fossilization if (crossed == 1) { crossover(parent, "min_repro_energies"); crossed = 0; } } } function reproduce_parents(species) { var parent1 = null; var parent2 = null; var pop = Populations[0]; for (var i = pop.size-1; i >= 0; i--) { if (pop[i].user2["reproduce"] == 1 && pop[i].user2["species"] == species) { if ((pop[i].user2["gen"]==1) || ((pop[i].user2["gen"]==0) && ExpParams.stress == 0)) { continue; } else if (parent1 == null) { parent1 = pop[i]; } else if (parent2 == null) { parent2 = pop[i]; } if (parent1 != null && parent2 != null) { reproduce_haploid(parent1, parent2, 0); print_repro_info(parent1); print_repro_info(parent2); pop.kill(parent1); pop.kill(parent2); parent1 = null; parent2 = null; } } } } function readyToRepro(cr) { var reproduced = 1; if (cr.user2["gen"] == 1) { reproduce_diploid(cr); } else if (ExpParams.stress == 0) { reproduce_haploid(cr, null, 1); } else { if (cr.signals.size == 0) { cr.signals.add("repro"+cr.user2["species"]); cr.signals[0].power = 1; } reproduced = 0; cr.user2["reproduce"] = 1; } if (reproduced == 1) { print_repro_info(cr); Populations[0].kill(cr); } return reproduced; } function print_repro_info(cr) { Simulator.print("Reproduced " + cr.user2["gen"] + " of species " + cr.user2["species"] + " energy: " + cr.energy); } function foramReproduce(cr) { var properEnergy = 0; var reproduced = 0; if (cr.user2["gen"] == 0) { properEnergy = ( cr.energy >= cr.user1["min_repro_energies"][cr.user2["gen"]] ); } else { properEnergy = ( cr.energy >= cr.user1[0]["min_repro_energies"][cr.user2["gen"]] ); //TODO gene selection } //if creature has proper energy if ( properEnergy && cr.signals.size == 0) { //reproduce with probability repro_prob if (Math.rnd01 <= ExpParams.repro_prob) //TODO env trigger { reproduced = readyToRepro(cr); } else if (cr.signals.receive("repro"+cr.user2["species"]) > 0) { reproduced = readyToRepro(cr); } if (reproduced == 1) return 1; } else if (!properEnergy) { cr.signals.clear(); cr.user2["reproduce"] = 0; } return 0; } function crossover(parent, gene) { var tmp = parent.user1[0][gene]; parent.user1[0][gene] = parent.user1[1][gene]; parent.user1[1][gene] = tmp; } function createOffspring(geno, energy, parent_user1, parent_user2) { var cr = Populations[0].add(geno); cr.energy0 = energy; cr.energy = cr.energy0; setGenotype({"cr" : cr, "parent_user1" : parent_user1, "parent_user2" : parent_user2, "opt" : 1}); placeRandomlyNotColliding(cr); }