more control panel stuff

This commit is contained in:
MaxRobinsonTheGreat
2020-07-12 18:48:51 -06:00
parent c39ece309d
commit 9f13068cda
10 changed files with 135 additions and 275 deletions

245
dist/bundle.js vendored

File diff suppressed because one or more lines are too long

18
dist/html/index.html vendored
View File

@@ -25,17 +25,29 @@
<h2>Stats</h2>
<p id='org-count'>Organism count: </p>
<p id='org-record'>Highest count: </p>
<p id='avg-mut'>Average Mutation Rate: </p>
</div>
<div id='hyperparameters' class='control-set'>
<h2>Hyperparameters</h2>
<label for="food-prod-prob">Probability of producing food:</label>
<input type="number" id="food-prod-prob" min=".001" max="100" value=1 step="1">
<input type="number" id="food-prod-prob" min=".001" max="100" value=4 step="1">
<label for="lifespan-multiplier">Lifespan multiplier:</label>
<input type="number" id="lifespan-multiplier" min="1" max="10000" value=100 step="1">
<br/>
<label for="fixed-ratio">Use fixed ratio</label>
<input type="checkbox" id="fixed-ratio" name="scales" checked>
<br><br/>
<h4>Mutation Probabilities</h4>
<label for="add-prob">Add Cell:</label>
<input class="mut-prob" type="number" id="add-prob" min="0" max="100" value=33>
<br/>
<label for="change-prob">Change Cell:</label>
<input class="mut-prob" type="number" id="change-prob" min="0" max="100" value=33>
<br/>
<label for="remove-prob">Remove Cell:</label>
<input class="mut-prob" type="number" id="remove-prob" min="0" max="100" value=33>
<br/>
</div>
<div id='abilities' class='control-set'>
@@ -44,6 +56,10 @@
<button class='control-mode-button' id='wall-button'>Drop Wall</button>
<button class='control-mode-button' id='kill-button'>Kill Organism</button>
<button class='control-mode-button' id='none-button'>None</button>
<br><br/>
<button id='reset-env'>Reset Environment</button>
<button id='kill-all'>Kill All Organisms</button>
<button id='clear-walls'>Clear All Walls</button>
</div>
</div>

View File

@@ -1,5 +1,5 @@
const CellTypes = require("./CellTypes");
var Hyperparams = require("./Hyperparameters");
const Hyperparams = require("./Hyperparameters");
// A cell exists in a grid system.
class Cell{
@@ -61,12 +61,12 @@ function growFood(self, env){
if (self.owner.is_mover)
return;
var prob = Hyperparams.foodProdProb;
// console.log(prob)
for (var loc of Hyperparams.growableNeighbors){
if (Math.random() * 100 <= prob){
var loc = Hyperparams.growableNeighbors[Math.floor(Math.random() * Hyperparams.growableNeighbors.length)]
var c=loc[0];
var r=loc[1];
var cell = env.grid_map.cellAt(self.col+c, self.row+r);
if (cell != null && cell.type == CellTypes.empty && Math.random() * 100 <= prob){
if (cell != null && cell.type == CellTypes.empty){
env.changeCell(self.col+c, self.row+r, CellTypes.food, null);
return;
}

View File

@@ -8,7 +8,7 @@ const CellTypes = {
killer: 6,
armor: 7,
colors: ['#121D29', 'green', 'gray', 'orange', 'white', 'blue', 'red', 'purple'],
getRandomLivingType: function(){
getRandomLivingType: function() {
return Math.floor(Math.random() * 5) + 3;
}
}

View File

@@ -1,5 +1,5 @@
var Hyperparams = require("./Hyperparameters");
var Modes = require("./ControlModes");
const Hyperparams = require("./Hyperparameters");
const Modes = require("./ControlModes");
const CellTypes = require("./CellTypes");
class ControlPanel {
@@ -59,6 +59,25 @@ class ControlPanel {
Hyperparams.lifespanMultiplier = lifespan;
}
}.bind(this));
$('.mut-prob').change( function() {
switch(this.id){
case "add-prob":
Hyperparams.addProb = this.value;
Hyperparams.balanceMutationProbs(1);
break;
case "change-prob":
Hyperparams.changeProb = this.value;
Hyperparams.balanceMutationProbs(2);
break;
case "remove-prob":
Hyperparams.removeProb = this.value;
Hyperparams.balanceMutationProbs(3);
break;
}
$('#add-prob').val(Math.floor(Hyperparams.addProb));
$('#change-prob').val(Math.floor(Hyperparams.changeProb));
$('#remove-prob').val(Math.floor(Hyperparams.removeProb));
});
}
defineModeControls() {
@@ -81,6 +100,17 @@ class ControlPanel {
$(".control-mode-button" ).css( "background-color", "lightgray" );
$("#"+this.id).css("background-color", "darkgray");
});
$('#reset-env').click( function() {
this.engine.env.reset();
}.bind(this));
$('#kill-all').click( function() {
this.engine.env.clearOrganisms();
}.bind(this));
$('#clear-walls').click( function() {
this.engine.env.clearWalls();
}.bind(this));
}
changeEngineSpeed(change_val) {
@@ -96,7 +126,7 @@ class ControlPanel {
if (org_count > this.organism_record)
this.organism_record = org_count;
$('#org-record').text("Highest count: " + this.organism_record);
// this.env_controller.performModeAction();
$('#avg-mut').text("Average Mutation Rate: " + Math.round(this.engine.env.averageMutability() * 100) / 100);
}
}

View File

@@ -15,6 +15,8 @@ class Environment{
this.grid_map = new GridMap(this.grid_cols, this.grid_rows, cell_size);
this.renderer.renderFullGrid();
this.organisms = [];
this.walls = [];
this.total_mutability = 0;
}
update(delta_time) {
@@ -35,6 +37,7 @@ class Environment{
removeOrganisms(org_indeces) {
for (var i of org_indeces.reverse()){
this.total_mutability -= this.organisms[i].mutability;
this.organisms.splice(i, 1);
}
}
@@ -44,19 +47,47 @@ class Environment{
var org = new Organism(center[0], center[1], this);
org.addCell(CellTypes.mouth, 1, 1);
org.addCell(CellTypes.producer, 0, 0);
// org.addCell(CellTypes.mouth, 1, -1);
org.addCell(CellTypes.mouth, -1, -1);
this.addOrganism(org);
}
addOrganism(organism) {
organism.updateGrid();
this.total_mutability += organism.mutability;
this.organisms.push(organism);
}
averageMutability() {
if (this.organisms.length < 1)
return 0;
return this.total_mutability / this.organisms.length;
}
changeCell(c, r, type, owner) {
this.grid_map.setCellType(c, r, type);
this.grid_map.setCellOwner(c, r, owner);
this.renderer.addToRender(this.grid_map.cellAt(c, r));
if(type == CellTypes.wall)
this.walls.push(this.grid_map.cellAt(c, r));
}
clearWalls() {
for(var wall of this.walls)
this.changeCell(wall.col, wall.row, CellTypes.empty, null);
}
clearOrganisms() {
for (var org of this.organisms)
org.die();
this.organisms = [];
}
reset() {
this.organisms = [];
this.grid_map.fillGrid(CellTypes.empty);
this.renderer.renderFullGrid();
this.total_mutability = 0;
this.OriginOfLife();
}
}

View File

@@ -1,4 +1,4 @@
var Modes = require("./ControlModes");
const Modes = require("./ControlModes");
const CellTypes = require("./CellTypes");
class EnvironmentController{

View File

@@ -19,9 +19,10 @@ class GridMap {
}
fillGrid(type) {
for (var col of grid) {
for (var col of this.grid) {
for (var cell of col){
cell.setType(type);
cell.owner = null;
}
}
}

View File

@@ -1,22 +1,47 @@
const Neighbors = require("./Neighbors");
var Hyperparams = {
const Hyperparams = {
lifespanMultiplier: 100,
foodProdProb: 1,
foodProdProb: 4,
foodProdProbScalar: 4,
killableNeighbors: Neighbors.adjacent,
edibleNeighbors: Neighbors.adjacent,
growableNeighbors: Neighbors.adjacent,
useGlobalMutability: false,
globalMutability: 0,
addProb: 33,
changeProb: 33,
removeProb: 33,
// calculates the optimal ratio where a producer cell is most likely to produce 1 food in its lifespan.
// calculates the optimal ratio where a producer cell is most likely to produce 1 food in its lifespan * a scalar of my choice :)
calcProducerFoodRatio : function(lifespan_fixed=true) {
if (lifespan_fixed) {
// change the foodProdProb
this.foodProdProb = 100 / this.lifespanMultiplier;
this.foodProdProb = (100 / this.lifespanMultiplier) * this.foodProdProbScalar;
}
else {
// change the lifespanMultiplier
this.lifespanMultiplier = Math.floor(100 / this.foodProdProb);
this.lifespanMultiplier = Math.floor(100 / (this.foodProdProb/this.foodProdProbScalar));
}
},
balanceMutationProbs : function(choice) {
if (choice == 1) {
var remaining = 100 - this.addProb;
this.changeProb = remaining/2;
this.removeProb = remaining/2;
}
else if (choice == 2) {
var remaining = 100 - this.changeProb;
this.addProb = remaining/2;
this.removeProb = remaining/2;
}
else {
var remaining = 100 - this.removeProb;
this.changeProb = remaining/2;
this.addProb = remaining/2;
}
}
}

View File

@@ -2,9 +2,8 @@ const CellTypes = require("./CellTypes");
const Cell = require("./Cell");
const GridMap = require("./GridMap");
const LocalCell = require("./LocalCell");
const { producer } = require("./CellTypes");
const Neighbors = require("./Neighbors");
var Hyperparams = require("./Hyperparameters");
const Hyperparams = require("./Hyperparameters");
const directions = [[0,1],[0,-1],[1,0],[-1,0]]
@@ -89,7 +88,10 @@ class Organism {
//produce mutated child
//check nearby locations (is there room and a direct path)
var org = new Organism(0, 0, this.env, this);
if (Math.random() * 100 <= 3) {
var prob = this.mutability;
if (Hyperparams.useGlobalMutability)
prob = Hyperparams.globalMutability;
if (Math.random() * 100 <= this.mutability) {
org.mutate();
}
if (Math.random() <= 0.5)
@@ -120,27 +122,25 @@ class Organism {
}
mutate() {
var choice = Math.floor(Math.random() * 3);
if (choice == 0) {
var choice = Math.floor(Math.random() * 100);
if (choice <= Hyperparams.addProb) {
// add cell
var type = CellTypes.getRandomLivingType();
var num_to_add = Math.floor(Math.random() * 3) + 1;
// for (var i=0; i<num_to_add; i++){
var branch = this.cells[Math.floor(Math.random() * this.cells.length)];
var growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)]
var c = branch.loc_col+growth_direction[0];
var r = branch.loc_row+growth_direction[1];
return this.addCell(type, c, r);
// }
var branch = this.cells[Math.floor(Math.random() * this.cells.length)];
var growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)]
var c = branch.loc_col+growth_direction[0];
var r = branch.loc_row+growth_direction[1];
return this.addCell(type, c, r);
}
else if (choice == 1){
else if (choice <= Hyperparams.addProb + Hyperparams.changeProb){
// change cell
var cell = this.cells[Math.floor(Math.random() * this.cells.length)];
cell.type = CellTypes.getRandomLivingType();
this.checkProducerMover(cell.type);
return true;
}
else {
else if (choice <= Hyperparams.addProb + Hyperparams.changeProb + Hyperparams.removeProb){
// remove cell
if(this.cells.length > 1) {
this.cells.splice(Math.floor(Math.random() * this.cells.length), 1);