Added headless updates!

This commit is contained in:
Max Robinson
2021-02-12 13:03:25 -07:00
parent 2e3ad6982d
commit d1119b65e8
10 changed files with 98 additions and 31 deletions

12
dist/css/style.css vendored
View File

@@ -9,7 +9,7 @@ body{
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
font-family: Arial, Helvetica, sans-serif; font-family: Arial, Helvetica, sans-serif;
} }
#env { #env {
@@ -239,6 +239,16 @@ button:hover{
display: none; display: none;
} }
#headless-notification {
display: none;
position: fixed;
color: white;
font-size: 200px;
left: 0;
top: 0;
padding-left: 10px;
}
#minimize { #minimize {
margin: 10px; margin: 10px;
float: right; float: right;

10
dist/index.html vendored
View File

@@ -27,8 +27,9 @@
<button id="clear-walls" title="Clear All Walls"><i class="fa fa-window-close"></i></button> <button id="clear-walls" title="Clear All Walls"><i class="fa fa-window-close"></i></button>
</div> </div>
<h2>Simulation Speed</h2> <h2>Simulation Speed</h2>
<input id="slider" type="range" min="1" max="300" value="60"> <input id="slider" type="range" min="1" max="500" value="60">
<button class='pause-button'><i class="fa fa-pause"></i></button> <button class='pause-button'><i class="fa fa-pause"></i></button>
<button class="headless" title="Disable rendering (increase efficiency)"><i class="fa fa-eye-slash"></i></button>
<p id='fps'>Target FPS: 60</p> <p id='fps'>Target FPS: 60</p>
<p id='fps-actual'></p> <p id='fps-actual'></p>
<button id='reset-env'>Reset Environment</button> <button id='reset-env'>Reset Environment</button>
@@ -230,7 +231,7 @@
<select name="chart-option" id="chart-option"> <select name="chart-option" id="chart-option">
<option value="population">Population</option> <option value="population">Population</option>
<option value="species">Species</option> <option value="species">Species</option>
<option value="mut-rate">Organism Size</option> <option value="mut-rate">Organism Structure</option>
<option value="mut-rate">Mutation Rate</option> <option value="mut-rate">Mutation Rate</option>
</select> </select>
<p id='chart-note'></p> <p id='chart-note'></p>
@@ -266,7 +267,10 @@
<button class="edit-mode-btn" id="food-drop" title="Drop/Remove Food"><i class="fa fa-cutlery"></i></button> <button class="edit-mode-btn" id="food-drop" title="Drop/Remove Food"><i class="fa fa-cutlery"></i></button>
<button class="edit-mode-btn" id="click-kill" title="Click to kill"><i class="fa fa-bolt"></i></button> <button class="edit-mode-btn" id="click-kill" title="Click to kill"><i class="fa fa-bolt"></i></button>
<button class='pause-button'><i class="fa fa-pause"></i></button> <button class='pause-button'><i class="fa fa-pause"></i></button>
<button class="headless" title="Disable rendering (increase efficiency)"><i class="fa fa-eye-slash"></i></button>
</div>
<div id="headless-notification">
<i class="fa fa-eye-slash" ></i>
</div> </div>
<div id='maximize-hot-control' class='hot-controls'> <div id='maximize-hot-control' class='hot-controls'>
<button id="maximize" title="Show Control Panel"><i class="fa fa-plus-square"></i></button> <button id="maximize" title="Show Control Panel"><i class="fa fa-plus-square"></i></button>

2
dist/js/bundle.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -19,6 +19,9 @@ class ControlPanel {
this.env_controller.setControlPanel(this); this.env_controller.setControlPanel(this);
this.editor_controller.setControlPanel(this); this.editor_controller.setControlPanel(this);
this.stats_panel = new StatsPanel(this.engine.env); this.stats_panel = new StatsPanel(this.engine.env);
this.headless_opacity = 1;
this.opacity_change_rate = -0.8;
this.paused=false;
} }
defineMinMaxControls(){ defineMinMaxControls(){
@@ -43,13 +46,13 @@ class ControlPanel {
this.fps = this.slider.value this.fps = this.slider.value
if (this.engine.running) { if (this.engine.running) {
this.changeEngineSpeed(this.fps); this.changeEngineSpeed(this.fps);
} }
$('#fps').text("Target FPS: "+this.fps); $('#fps').text("Target FPS: "+this.fps);
}.bind(this); }.bind(this);
$('.pause-button').click(function() { $('.pause-button').click(function() {
$('.pause-button').find("i").toggleClass("fa fa-pause"); $('.pause-button').find("i").toggleClass("fa fa-pause");
$('.pause-button').find("i").toggleClass("fa fa-play"); $('.pause-button').find("i").toggleClass("fa fa-play");
this.paused = !this.paused;
if (this.engine.running) { if (this.engine.running) {
this.engine.stop(); this.engine.stop();
} }
@@ -57,6 +60,16 @@ class ControlPanel {
this.engine.start(this.fps); this.engine.start(this.fps);
} }
}.bind(this)); }.bind(this));
$('.headless').click(function() {
if (Hyperparams.headless){
$('#headless-notification').css('display', 'none');
this.engine.env.renderFull();
}
else {
$('#headless-notification').css('display', 'block');
}
Hyperparams.headless = !Hyperparams.headless;
}.bind(this));
} }
defineGridSizeControls() { defineGridSizeControls() {
@@ -274,10 +287,29 @@ class ControlPanel {
this.fps = this.engine.fps; this.fps = this.engine.fps;
} }
update() { updateHeadlessIcon(delta_time) {
if (this.paused)
return;
var op = this.headless_opacity + (this.opacity_change_rate*delta_time/1000);
if (op <= 0.4){
op=0.4;
this.opacity_change_rate = -this.opacity_change_rate;
}
else if (op >= 1){
op=1;
this.opacity_change_rate = -this.opacity_change_rate;
}
this.headless_opacity = op;
$('#headless-notification').css('opacity',(op*100)+'%');
}
update(delta_time) {
$('#fps-actual').text("Actual FPS: " + Math.floor(this.engine.actual_fps)); $('#fps-actual').text("Actual FPS: " + Math.floor(this.engine.actual_fps));
$('#reset-count').text("Auto reset count: " + this.engine.env.reset_count); $('#reset-count').text("Auto reset count: " + this.engine.env.reset_count);
this.stats_panel.updateDetails(); this.stats_panel.updateDetails();
if (Hyperparams.headless)
this.updateHeadlessIcon(delta_time);
} }
} }

View File

@@ -4,6 +4,7 @@ const Modes = require("./ControlModes");
const CellStates = require("../Organism/Cell/CellStates"); const CellStates = require("../Organism/Cell/CellStates");
const Neighbors = require("../Grid/Neighbors"); const Neighbors = require("../Grid/Neighbors");
const FossilRecord = require("../Stats/FossilRecord"); const FossilRecord = require("../Stats/FossilRecord");
const Hyperparams = require("../Hyperparameters");
class EnvironmentController extends CanvasController{ class EnvironmentController extends CanvasController{
constructor(env, canvas) { constructor(env, canvas) {
@@ -78,6 +79,8 @@ class EnvironmentController extends CanvasController{
} }
performModeAction() { performModeAction() {
if (Hyperparams.headless)
return;
var mode = this.mode; var mode = this.mode;
var right_click = this.right_click; var right_click = this.right_click;
var left_click = this.left_click; var left_click = this.left_click;

View File

@@ -23,10 +23,8 @@ class Engine {
start(fps=60) { start(fps=60) {
if (fps <= 0) if (fps <= 0)
fps = 1; fps = 1;
if (fps > 300)
fps = 300;
this.fps = fps; this.fps = fps;
this.game_loop = setInterval(function(){this.environmentUpdate();}.bind(this), 1000/fps); this.game_loop = setInterval(function(){this.updateDeltaTime();this.environmentUpdate();}.bind(this), 1000/fps);
this.running = true; this.running = true;
if (this.fps >= render_speed) { if (this.fps >= render_speed) {
if (this.render_loop != null) { if (this.render_loop != null) {
@@ -46,14 +44,17 @@ class Engine {
setRenderLoop() { setRenderLoop() {
if (this.render_loop == null) { if (this.render_loop == null) {
this.render_loop = setInterval(function(){this.necessaryUpdate();}.bind(this), 1000/render_speed); this.render_loop = setInterval(function(){this.updateDeltaTime();this.necessaryUpdate();}.bind(this), 1000/render_speed);
} }
} }
updateDeltaTime() {
this.delta_time = Date.now() - this.last_update;
this.last_update = Date.now();
}
environmentUpdate() { environmentUpdate() {
this.delta_time = Date.now() - this.last_update;
this.last_update = Date.now();
this.env.update(this.delta_time); this.env.update(this.delta_time);
this.actual_fps = 1/this.delta_time*1000; this.actual_fps = 1/this.delta_time*1000;
if(this.render_loop == null){ if(this.render_loop == null){
@@ -64,7 +65,7 @@ class Engine {
necessaryUpdate() { necessaryUpdate() {
this.env.render(); this.env.render();
this.controlpanel.update(); this.controlpanel.update(this.delta_time);
this.organism_editor.update(); this.organism_editor.update();
} }

View File

@@ -22,7 +22,6 @@ class WorldEnvironment extends Environment{
this.largest_cell_count = 0; this.largest_cell_count = 0;
this.reset_count = 0; this.reset_count = 0;
this.total_ticks = 0; this.total_ticks = 0;
this.total_cells = 0;
this.data_update_rate = 100; this.data_update_rate = 100;
FossilRecord.setEnv(this); FossilRecord.setEnv(this);
} }
@@ -46,14 +45,21 @@ class WorldEnvironment extends Environment{
} }
render() { render() {
if (Hyperparams.headless) {
this.renderer.cells_to_render.clear();
return;
}
this.renderer.renderCells(); this.renderer.renderCells();
this.renderer.renderHighlights(); this.renderer.renderHighlights();
} }
renderFull() {
this.renderer.renderFullGrid(this.grid_map.grid);
}
removeOrganisms(org_indeces) { removeOrganisms(org_indeces) {
for (var i of org_indeces.reverse()){ for (var i of org_indeces.reverse()){
this.total_mutability -= this.organisms[i].mutability; this.total_mutability -= this.organisms[i].mutability;
this.total_cells -= this.organisms[i].anatomy.cells.length;
this.organisms.splice(i, 1); this.organisms.splice(i, 1);
} }
if (this.organisms.length == 0 && this.auto_reset){ if (this.organisms.length == 0 && this.auto_reset){
@@ -78,7 +84,6 @@ class WorldEnvironment extends Environment{
this.organisms.push(organism); this.organisms.push(organism);
if (organism.anatomy.cells.length > this.largest_cell_count) if (organism.anatomy.cells.length > this.largest_cell_count)
this.largest_cell_count = organism.anatomy.cells.length; this.largest_cell_count = organism.anatomy.cells.length;
this.total_cells += organism.anatomy.cells.length;
} }
averageMutability() { averageMutability() {
@@ -131,7 +136,6 @@ class WorldEnvironment extends Environment{
this.renderer.renderFullGrid(this.grid_map.grid); this.renderer.renderFullGrid(this.grid_map.grid);
this.total_mutability = 0; this.total_mutability = 0;
this.total_ticks = 0; this.total_ticks = 0;
this.total_cells = 0;
FossilRecord.clear_record(); FossilRecord.clear_record();
this.OriginOfLife(); this.OriginOfLife();
} }

View File

@@ -2,6 +2,8 @@ const Neighbors = require("./Grid/Neighbors");
const Hyperparams = { const Hyperparams = {
setDefaults: function() { setDefaults: function() {
this.headless = false;
this.lifespanMultiplier = 100; this.lifespanMultiplier = 100;
this.foodProdProb = 4; this.foodProdProb = 4;
this.foodProdProbScalar = 4; this.foodProdProbScalar = 4;

View File

@@ -8,6 +8,12 @@ class ChartController {
title:{ title:{
text: title text: title
}, },
axisX:{
minimum: 0,
},
axisY:{
minimum: 0,
},
data: this.data data: this.data
}); });
this.chart.render(); this.chart.render();
@@ -18,6 +24,13 @@ class ChartController {
alert("Must override updateData!"); alert("Must override updateData!");
} }
setMinimum() {
var min = 0;
if (this.data[0].dataPoints != [])
min = this.data[0].dataPoints[0].x;
this.chart.options.axisX.minimum = min;
}
addAllDataPoints(){ addAllDataPoints(){
for (var i in FossilRecord.tick_record) { for (var i in FossilRecord.tick_record) {
this.addDataPoint(i) this.addDataPoint(i)
@@ -25,6 +38,7 @@ class ChartController {
} }
render() { render() {
this.setMinimum();
this.chart.render(); this.chart.render();
} }

View File

@@ -8,7 +8,6 @@ const FossilRecord = {
// if an organism has fewer than this cumulative pop, discard them on extinction // if an organism has fewer than this cumulative pop, discard them on extinction
this.min_discard = 10; this.min_discard = 10;
this.total_relavent_organisms = 0; // organisms with greater than ^ cumulative pop
this.record_size_limit = 500; // store this many data points this.record_size_limit = 500; // store this many data points
}, },
@@ -67,10 +66,10 @@ const FossilRecord = {
setData() { setData() {
// all parallel arrays // all parallel arrays
this.tick_record = [0]; this.tick_record = [0];
this.pop_counts = [1]; this.pop_counts = [0];
this.species_counts = [1]; this.species_counts = [0];
this.av_mut_rates = [5]; this.av_mut_rates = [0];
this.av_cells = [3]; this.av_cells = [0];
this.av_cell_counts = [this.calcCellCountAverages()]; this.av_cell_counts = [this.calcCellCountAverages()];
}, },
@@ -80,12 +79,7 @@ const FossilRecord = {
this.pop_counts.push(this.env.organisms.length); this.pop_counts.push(this.env.organisms.length);
this.species_counts.push(this.extant_species.length); this.species_counts.push(this.extant_species.length);
this.av_mut_rates.push(this.env.averageMutability()); this.av_mut_rates.push(this.env.averageMutability());
this.av_cell_counts.push(this.calcCellCountAverages()); this.calcCellCountAverages();
let av_cell = 0;
if (this.total_relavent_organisms > 0) {
av_cell = this.env.total_cells / this.total_relavent_organisms;
}
this.av_cells.push(av_cell);
if (this.tick_record.length > this.record_size_limit) { if (this.tick_record.length > this.record_size_limit) {
this.tick_record.shift(); this.tick_record.shift();
@@ -116,11 +110,14 @@ const FossilRecord = {
} }
if (total_org == 0) if (total_org == 0)
return cell_counts; return cell_counts;
var total_cells = 0;
for (let c in cell_counts) { for (let c in cell_counts) {
total_cells += cell_counts[c];
cell_counts[c] /= total_org; cell_counts[c] /= total_org;
} }
this.total_relavent_organisms = total_org; this.av_cells.push(total_cells / total_org);
return cell_counts; this.av_cell_counts.push(cell_counts);
}, },
clear_record: function() { clear_record: function() {