diff --git a/dist/css/style.css b/dist/css/style.css index 5c7d20c7..0ad5ebe4 100644 --- a/dist/css/style.css +++ b/dist/css/style.css @@ -222,6 +222,29 @@ button:active{ height: 50px; margin: 1px; } +.cell-legend-type-living { + width: 50px; + height: 50px; + margin: 1px; + cursor: pointer; +} +/* p is white with a black outline */ +.cell-legend-type-living p { + opacity: 0; + color: black; + font-size: 20px; + font-weight: bolder; + text-align: center; + transition: opacity 0.5s; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} +.cell-legend-type-living p:hover { + opacity: 1; +} .cell-legend-hover { border-color: black; border: 5px; diff --git a/dist/index.html b/dist/index.html index d2fe2742..7770aa7c 100644 --- a/dist/index.html +++ b/dist/index.html @@ -51,14 +51,14 @@

Simulation Speed

The Life Engine

The Life Engine is a virtual ecosystem that allows organisms to reproduce, compete, and evolve.

-

Each organism is made up of different colored cells. Hover over each color to learn what it does.

+

Each organism is made up of different colored cells. Hover over each color to learn what it does and change the cell cost by clicking it.

-
-
-
-
-
-
+
+
+
+
+
+

@@ -209,10 +209,6 @@

Evolution Controls


-
- - -
diff --git a/package-lock.json b/package-lock.json index d276bd27..e905a510 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3609,4 +3609,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/Controllers/ControlPanel.js b/src/Controllers/ControlPanel.js index f57b94b4..ac975b32 100644 --- a/src/Controllers/ControlPanel.js +++ b/src/Controllers/ControlPanel.js @@ -228,9 +228,6 @@ class ControlPanel { $('#food-drop-rate').change(function() { Hyperparams.foodDropProb = $('#food-drop-rate').val(); }); - $('#extra-mover-cost').change(function() { - Hyperparams.extraMoverFoodCost = parseInt($('#extra-mover-cost').val()); - }); $('#evolved-mutation').change( function() { if (this.checked) { @@ -313,7 +310,6 @@ class ControlPanel { $('#movers-produce').prop('checked', Hyperparams.moversCanProduce); $('#food-blocks').prop('checked', Hyperparams.foodBlocksReproduction); $('#food-drop-rate').val(Hyperparams.foodDropProb); - $('#extra-mover-cost').val(Hyperparams.extraMoverFoodCost); $('#look-range').val(Hyperparams.lookRange); if (!Hyperparams.useGlobalMutability) { @@ -388,6 +384,22 @@ class ControlPanel { this.engine.organism_editor.resetWithRandomOrgs(this.engine.env); }.bind(this)); + $('.cell-legend-type-living').click(function() { + if(Hyperparams.cost[this.id] != null) { + let val = parseFloat(prompt('Enter the reproduce cost(food count) of ' + this.id + ' cell:', Hyperparams.cost[this.id].toFixed(2))); + + Hyperparams.cost[this.id] = isNaN(val) ? Hyperparams.cost[this.id] : Math.max(val, 0.001); + + if(val != null) {//check and if not then add a p inside of .cell-legend-type-living with the cost of the cell or just set its text to the cost + if($(this).find('p').length > 0) { + $(this).find('p').text(Hyperparams.cost[this.id].toFixed(2)); + } else { + $(this).append('

' + Hyperparams.cost[this.id].toFixed(2) + '

'); + } + } + } + }); + window.onbeforeunload = function (e) { e = e || window.event; let return_str = 'this will cause a confirmation on page close' diff --git a/src/Hyperparameters.js b/src/Hyperparameters.js index 9579f11d..9c5323c9 100644 --- a/src/Hyperparameters.js +++ b/src/Hyperparameters.js @@ -1,4 +1,5 @@ const Neighbors = require("./Grid/Neighbors"); +const CellStates = require('./Organism/Cell/CellStates'); const Hyperparams = { setDefaults: function() { @@ -25,7 +26,11 @@ const Hyperparams = { this.foodDropProb = 0; - this.extraMoverFoodCost = 0; + this.cost = {}; + + for (var cell of CellStates.living) { + this.cost[cell.name] = 1; + } }, loadJsonObj(obj) { diff --git a/src/Organism/Anatomy.js b/src/Organism/Anatomy.js index b1c3cb68..9430e2db 100644 --- a/src/Organism/Anatomy.js +++ b/src/Organism/Anatomy.js @@ -1,5 +1,6 @@ const CellStates = require("./Cell/CellStates"); const BodyCellFactory = require("./Cell/BodyCells/BodyCellFactory"); +const Hyperparams = require("../Hyperparameters"); class Anatomy { constructor(owner) { @@ -9,6 +10,7 @@ class Anatomy { this.is_mover = false; this.has_eyes = false; this.birth_distance = 4; + this.total_cost = 0; } canAddCellAt(c, r) { @@ -23,6 +25,7 @@ class Anatomy { addDefaultCell(state, c, r) { var new_cell = BodyCellFactory.createDefault(this.owner, state, c, r); this.cells.push(new_cell); + this.total_cost += Hyperparams.cost[state.name]; return new_cell; } @@ -32,12 +35,14 @@ class Anatomy { } var new_cell = BodyCellFactory.createRandom(this.owner, state, c, r); this.cells.push(new_cell); + this.total_cost += Hyperparams.cost[state.name]; return new_cell; } addInheritCell(parent_cell) { var new_cell = BodyCellFactory.createInherited(this.owner, parent_cell); this.cells.push(new_cell); + this.total_cost += Hyperparams.cost[new_cell.state.name]; return new_cell; } @@ -58,6 +63,7 @@ class Anatomy { var cell = this.cells[i]; if (cell.loc_col == c && cell.loc_row == r){ this.cells.splice(i, 1); + this.total_cost -= Hyperparams.cost[cell.state.name]; break; } } @@ -107,6 +113,10 @@ class Anatomy { return neighbors; } + + getTotalCost() { + return this.total_cost; + } } module.exports = Anatomy; \ No newline at end of file diff --git a/src/Organism/Cell/BodyCells/MouthCell.js b/src/Organism/Cell/BodyCells/MouthCell.js index 56e0daa9..52b924df 100644 --- a/src/Organism/Cell/BodyCells/MouthCell.js +++ b/src/Organism/Cell/BodyCells/MouthCell.js @@ -22,7 +22,7 @@ class MouthCell extends BodyCell{ return; if (n_cell.state == CellStates.food){ env.changeCell(n_cell.col, n_cell.row, CellStates.empty, null); - this.org.food_collected++; + this.org.food_collected += (n_cell.cell_owner && n_cell.cell_owner.food_value) ? n_cell.food_value : 1; } } } diff --git a/src/Organism/Organism.js b/src/Organism/Organism.js index 2d00ee64..c0e7b9bd 100644 --- a/src/Organism/Organism.js +++ b/src/Organism/Organism.js @@ -47,7 +47,7 @@ class Organism { // amount of food required before it can reproduce foodNeeded() { - return this.anatomy.is_mover ? this.anatomy.cells.length + Hyperparams.extraMoverFoodCost : this.anatomy.cells.length; + return this.anatomy.getTotalCost(); } lifespan() { @@ -261,7 +261,11 @@ class Organism { for (var cell of this.anatomy.cells) { var real_c = this.c + cell.rotatedCol(this.rotation); var real_r = this.r + cell.rotatedRow(this.rotation); - this.env.changeCell(real_c, real_r, CellStates.food, null); + if(Hyperparams.cost[cell.state.name] > 0.001) { + this.env.changeCell(real_c, real_r, CellStates.food, {food_value: Hyperparams.cost[cell.state.name]}); + }else{ + this.env.changeCell(real_c, real_r, CellStates.empty, null); + } } this.species.decreasePop(); this.living = false; diff --git a/src/Rendering/ColorScheme.js b/src/Rendering/ColorScheme.js index 30ce7f90..15b8b5e9 100644 --- a/src/Rendering/ColorScheme.js +++ b/src/Rendering/ColorScheme.js @@ -28,6 +28,7 @@ class ColorScheme { for (var cell_type in color_scheme) { $('#'+cell_type+'.cell-type ').css('background-color', color_scheme[cell_type]); $('#'+cell_type+'.cell-legend-type').css('background-color', color_scheme[cell_type]); + $('#'+cell_type+'.cell-legend-type-living').css('background-color', color_scheme[cell_type]); } this.world_env.renderer.renderFullGrid(this.world_env.grid_map.grid);