diff --git a/dist/css/style.css b/dist/css/style.css index aecddcdd..17f80f57 100644 --- a/dist/css/style.css +++ b/dist/css/style.css @@ -294,3 +294,7 @@ input:hover,input:active { #reset-with-editor-org{ margin-top: 5px; } + +input[type=number]{ + max-width: 47px; +} \ No newline at end of file diff --git a/dist/index.html b/dist/index.html index d36ce90b..50ae1308 100644 --- a/dist/index.html +++ b/dist/index.html @@ -37,7 +37,6 @@

Simulation Speed

-

About

Editor

@@ -105,8 +104,9 @@

The Life Engine

Organism Details

Cell count:

Move Range:

-

Mutation Rate:

-
+

+ Mutation Rate: (Add: 33, Change: 33, Remove: 33) +

Brain

@@ -125,6 +125,15 @@

Edit Organism

+ ( + + + + + + + ) +
@@ -221,14 +230,6 @@

Mutation Rate


-

Mutation Type Probabilities

- - - - - - -

@@ -252,7 +253,7 @@

Statistics

diff --git a/src/Controllers/ControlPanel.js b/src/Controllers/ControlPanel.js index f57b94b4..be747fe9 100644 --- a/src/Controllers/ControlPanel.js +++ b/src/Controllers/ControlPanel.js @@ -246,22 +246,6 @@ class ControlPanel { $('#global-mutation').change( function() { Hyperparams.globalMutability = parseInt($('#global-mutation').val()); }); - $('.mut-prob').change( function() { - switch(this.id){ - case "add-prob": - Hyperparams.addProb = this.value; - break; - case "change-prob": - Hyperparams.changeProb = this.value; - break; - case "remove-prob": - Hyperparams.removeProb = this.value; - break; - } - $('#add-prob').val(Math.floor(Hyperparams.addProb)); - $('#change-prob').val(Math.floor(Hyperparams.changeProb)); - $('#remove-prob').val(Math.floor(Hyperparams.removeProb)); - }); $('#movers-produce').change( function() { Hyperparams.moversCanProduce = this.checked; }); @@ -307,9 +291,6 @@ class ControlPanel { $('#rot-enabled').prop('checked', Hyperparams.rotationEnabled); $('#insta-kill').prop('checked', Hyperparams.instaKill); $('#evolved-mutation').prop('checked', !Hyperparams.useGlobalMutability); - $('#add-prob').val(Hyperparams.addProb); - $('#change-prob').val(Hyperparams.changeProb); - $('#remove-prob').val(Hyperparams.removeProb); $('#movers-produce').prop('checked', Hyperparams.moversCanProduce); $('#food-blocks').prop('checked', Hyperparams.foodBlocksReproduction); $('#food-drop-rate').val(Hyperparams.foodDropProb); diff --git a/src/Controllers/EditorController.js b/src/Controllers/EditorController.js index d5c2cb75..0b568004 100644 --- a/src/Controllers/EditorController.js +++ b/src/Controllers/EditorController.js @@ -97,6 +97,19 @@ class EditorController extends CanvasController{ $('#mutation-rate-edit').change ( function() { this.env.organism.mutability = parseInt($('#mutation-rate-edit').val()); }.bind(this)); + + $('#mutation-add-edit').change ( function() { + this.env.organism.addProb = parseFloat($('#mutation-add-edit').val()); + }.bind(this)); + + $('#mutation-change-edit').change ( function() { + this.env.organism.changeProb = parseFloat($('#mutation-change-edit').val()); + }.bind(this)); + + $('#mutation-remove-edit').change ( function() { + this.env.organism.removeProb = parseFloat($('#mutation-remove-edit').val()); + }.bind(this)); + $('#observation-type-edit').change ( function() { this.setBrainEditorValues($('#observation-type-edit').val()); this.setBrainDetails(); @@ -129,12 +142,13 @@ class EditorController extends CanvasController{ $('.cell-count').text("Cell count: "+org.anatomy.cells.length); $('#move-range').text("Move Range: "+org.move_range); $('#mutation-rate').text("Mutation Rate: "+org.mutability); + $('#mutation-probs').text(" (Add: "+org.addProb.toFixed(2)+", Change: "+org.changeProb.toFixed(2)+", Remove: "+org.removeProb.toFixed(2)+")"); if (Hyperparams.useGlobalMutability) { $('#mutation-rate').css('display', 'none'); } else { - $('#mutation-rate').css('display', 'block'); + $('#mutation-rate').css('display', 'inline'); } this.setMoveRangeVisibility(); @@ -156,6 +170,10 @@ class EditorController extends CanvasController{ } $('#mutation-rate-edit').val(org.mutability); + $('#mutation-add-edit').val(org.addProb); + $('#mutation-change-edit').val(org.changeProb); + $('#mutation-remove-edit').val(org.removeProb); + if (Hyperparams.useGlobalMutability) { $('#mutation-rate-cont').css('display', 'none'); } diff --git a/src/Environments/WorldEnvironment.js b/src/Environments/WorldEnvironment.js index 6f47b273..a21cca3a 100644 --- a/src/Environments/WorldEnvironment.js +++ b/src/Environments/WorldEnvironment.js @@ -19,6 +19,9 @@ class WorldEnvironment extends Environment{ this.organisms = []; this.walls = []; this.total_mutability = 0; + this.total_add_mutability = 0; + this.total_change_mutability = 0; + this.total_remove_mutability = 0; this.largest_cell_count = 0; this.reset_count = 0; this.total_ticks = 0; @@ -61,6 +64,9 @@ class WorldEnvironment extends Environment{ let start_pop = this.organisms.length; for (var i of org_indeces.reverse()){ this.total_mutability -= this.organisms[i].mutability; + this.total_add_mutability -= this.organisms[i].addProb; + this.total_change_mutability -= this.organisms[i].changeProb; + this.total_remove_mutability -= this.organisms[i].removeProb; this.organisms.splice(i, 1); } if (this.organisms.length === 0 && start_pop > 0) { @@ -86,6 +92,9 @@ class WorldEnvironment extends Environment{ addOrganism(organism) { organism.updateGrid(); this.total_mutability += organism.mutability; + this.total_add_mutability += organism.addProb; + this.total_change_mutability += organism.changeProb; + this.total_remove_mutability += organism.removeProb; this.organisms.push(organism); if (organism.anatomy.cells.length > this.largest_cell_count) this.largest_cell_count = organism.anatomy.cells.length; @@ -100,6 +109,24 @@ class WorldEnvironment extends Environment{ return this.total_mutability / this.organisms.length; } + avarageAddMutability() { + if (this.organisms.length < 1) + return 0; + return this.total_add_mutability / this.organisms.length; + } + + avarageChangeMutability() { + if (this.organisms.length < 1) + return 0; + return this.total_change_mutability / this.organisms.length; + } + + avarageRemoveMutability() { + if (this.organisms.length < 1) + return 0; + return this.total_remove_mutability / this.organisms.length; + } + changeCell(c, r, state, owner) { super.changeCell(c, r, state, owner); this.renderer.addToRender(this.grid_map.cellAt(c, r)); @@ -144,6 +171,9 @@ class WorldEnvironment extends Environment{ this.grid_map.fillGrid(CellStates.empty, !WorldConfig.clear_walls_on_reset); this.renderer.renderFullGrid(this.grid_map.grid); this.total_mutability = 0; + this.total_add_mutability = 0; + this.total_change_mutability = 0; + this.total_remove_mutability = 0; this.total_ticks = 0; FossilRecord.clear_record(); if (reset_life) diff --git a/src/Hyperparameters.js b/src/Hyperparameters.js index 9579f11d..92a18747 100644 --- a/src/Hyperparameters.js +++ b/src/Hyperparameters.js @@ -10,9 +10,6 @@ const Hyperparams = { this.useGlobalMutability = false; this.globalMutability = 5; - this.addProb = 33; - this.changeProb = 33; - this.removeProb = 33; this.rotationEnabled = true; diff --git a/src/Organism/Organism.js b/src/Organism/Organism.js index 2d00ee64..8616d467 100644 --- a/src/Organism/Organism.js +++ b/src/Organism/Organism.js @@ -22,6 +22,9 @@ class Organism { this.move_range = 4; this.ignore_brain_for = 0; this.mutability = 5; + this.addProb = 33; + this.changeProb = 33; + this.removeProb = 33; this.damage = 0; this.brain = new Brain(this); if (parent != null) { @@ -32,6 +35,9 @@ class Organism { inherit(parent) { this.move_range = parent.move_range; this.mutability = parent.mutability; + this.addProb = parent.addProb; + this.changeProb = parent.changeProb; + this.removeProb = parent.removeProb; this.species = parent.species; // this.birth_distance = parent.birth_distance; for (var c of parent.anatomy.cells){ @@ -78,6 +84,35 @@ class Organism { if (org.mutability < 1) org.mutability = 1; } + var amount; + var mutation_type_mutability = 5; + //mutate the add probability + amount = Math.random()*mutation_type_mutability - mutation_type_mutability/2; + org.addProb += amount; + org.addProb = Math.min(Math.max(org.addProb, 0), 100); + org.changeProb -= amount/2; + org.removeProb -= amount/2; + //fix the probabilities (floating point errors) + org.changeProb = Math.min(Math.max(100 - org.addProb - org.removeProb, 0), 100); + org.removeProb = Math.min(Math.max(100 - org.addProb - org.changeProb, 0), 100); + //mutate the change probability + amount = Math.random()*mutation_type_mutability - mutation_type_mutability/2; + org.changeProb += amount; + org.changeProb = Math.min(Math.max(org.changeProb, 0), 100); + org.addProb -= amount/2; + org.removeProb -= amount/2; + //fix the probabilities (floating point errors) + org.addProb = Math.min(Math.max(100 - org.changeProb - org.removeProb, 0), 100); + org.removeProb = Math.min(Math.max(100 - org.changeProb - org.addProb, 0), 100); + //mutate the remove probability + amount = Math.random()*mutation_type_mutability - mutation_type_mutability/2; + org.removeProb += amount; + org.removeProb = Math.min(Math.max(org.removeProb, 0), 100); + org.addProb -= amount/2; + org.changeProb -= amount/2; + //fix the probabilities (floating point errors) + org.addProb = Math.min(Math.max(100 - org.removeProb - org.changeProb, 0), 100); + org.changeProb = Math.min(Math.max(100 - org.removeProb - org.addProb, 0), 100); } var mutated = false; if (Math.random() * 100 <= prob) { @@ -123,7 +158,7 @@ class Organism { mutate() { let mutated = false; - if (this.calcRandomChance(Hyperparams.addProb)) { + if (this.calcRandomChance(this.addProb)) { let branch = this.anatomy.getRandomCell(); let state = CellStates.getRandomLivingType();//branch.state; let growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)] @@ -134,13 +169,13 @@ class Organism { this.anatomy.addRandomizedCell(state, c, r); } } - if (this.calcRandomChance(Hyperparams.changeProb)){ + if (this.calcRandomChance(this.changeProb)){ let cell = this.anatomy.getRandomCell(); let state = CellStates.getRandomLivingType(); this.anatomy.replaceCell(state, cell.loc_col, cell.loc_row); mutated = true; } - if (this.calcRandomChance(Hyperparams.removeProb)){ + if (this.calcRandomChance(this.removeProb)){ if(this.anatomy.cells.length > 1) { let cell = this.anatomy.getRandomCell(); mutated = this.anatomy.removeCell(cell.loc_col, cell.loc_row); diff --git a/src/Stats/StatsPanel.js b/src/Stats/StatsPanel.js index 44878614..0558993b 100644 --- a/src/Stats/StatsPanel.js +++ b/src/Stats/StatsPanel.js @@ -52,7 +52,13 @@ class StatsPanel { $('#org-count').text("Total Population: " + org_count); $('#species-count').text("Number of Species: " + FossilRecord.extant_species.length); $('#largest-org').text("Largest Organism Ever: " + this.env.largest_cell_count + " cells"); - $('#avg-mut').text("Average Mutation Rate: " + Math.round(this.env.averageMutability() * 100) / 100); + var mutation_info = "Average Mutation Rate: " + this.env.averageMutability().toFixed(2); + + mutation_info += " (Add: " + this.env.avarageAddMutability().toFixed(2) ; + mutation_info += ", Change: " + this.env.avarageChangeMutability().toFixed(2); + mutation_info += ", Remove: " + this.env.avarageRemoveMutability().toFixed(2) + ")"; + + $('#avg-mut').text(mutation_info); }