Added control panel

This commit is contained in:
MaxRobinsonTheGreat
2020-07-08 19:32:05 -06:00
parent 2ba56abb1d
commit c6b0a5bafc
9 changed files with 176 additions and 37 deletions

21
dist/bundle.js vendored

File diff suppressed because one or more lines are too long

35
dist/css/style.css vendored
View File

@@ -6,9 +6,44 @@ body{
canvas {
display: block;
}
* {
margin: 0;
padding: 0;
}
.env {
height: 80vh;
position: static;
}
.control-panel {
height: 20vh;
width: 100vw;
background-color: gray;
position: fixed;
display: grid;
}
.control-set {
margin: 5px;
padding: 5px;
border: 10px;
border-color: black;
grid-row: 1;
height: 100%;
}
#speed-controller {
grid-column: 1;
}
#hyperparameters {
grid-column: 2;
}
#powers {
grid-column: 3;
}

22
dist/html/index.html vendored
View File

@@ -4,9 +4,29 @@
<meta charste="UTF-8">
<title>Evolution Simulator</title>
<link rel="stylesheet" href="../css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<canvas id='canvas'></canvas>
<script src="../bundle.js"></script>
<div class='env'>
<canvas id='canvas'></canvas>
</div>
<div class='control-panel'>
<div id='speed-controller' class='control-set'>
<h2>Simulation Speed</h2>
<input id="slider" type="range" min="1" max="300" value="60">
<button id='pause-button'>Pause</button>
</div>
<div id='hyperparameters' class='control-set'>
<h2>Hyperparameters</h2>
</div>
<div id='powers' class='control-set'>
<h2>Powers</h2>
</div>
</div>
</body>
</html>

View File

@@ -64,7 +64,7 @@ function growFood(self, env){
if (r==0 && c==0)
continue;
var cell = env.grid_map.cellAt(self.col+c, self.row+r);
if (cell != null && cell.type == CellTypes.empty && Math.random() * 100 <= 0.5){
if (cell != null && cell.type == CellTypes.empty && Math.random() * 100 <= 1){
env.changeCell(self.col+c, self.row+r, CellTypes.food, null);
return;
}
@@ -73,21 +73,38 @@ function growFood(self, env){
}
function killNeighbors(self, env) {
killNeighbor(env.grid_map.cellAt(self.col+1, self.row));
killNeighbor(env.grid_map.cellAt(self.col-1, self.row));
killNeighbor(env.grid_map.cellAt(self.col, self.row+1));
killNeighbor(env.grid_map.cellAt(self.col, self.row-1));
killNeighbor(self, env.grid_map.cellAt(self.col+1, self.row));
killNeighbor(self, env.grid_map.cellAt(self.col-1, self.row));
killNeighbor(self, env.grid_map.cellAt(self.col, self.row+1));
killNeighbor(self, env.grid_map.cellAt(self.col, self.row-1));
}
function killNeighbor(n_cell) {
function killNeighbor(self, n_cell) {
if(n_cell == null) {
// console.log("null cell")
return;
}
if(n_cell.owner == null) {
// console.log("is no one's cell")
return;
}
if(n_cell.owner == self.owner) {
// console.log("is my cell")
return;
}
if (!n_cell.owner.living) {
// console.log("cell is dead")
return;
}
if (n_cell.type == CellTypes.armor) {
// console.log("armor block")
// self.owner.die();
return
}
if (n_cell.type != CellTypes.armor && n_cell.owner != null && n_cell.owner != self.owner && n_cell.owner.living){
n_cell.owner.die();
if (n_cell == CellTypes.killer){
self.owner.die();
}
var should_die = n_cell.type == CellTypes.killer; // has to be calculated before death
n_cell.owner.die();
if (should_die){
self.owner.die();
}
}

39
src/ControlPanel.js Normal file
View File

@@ -0,0 +1,39 @@
class ControlPanel {
constructor(engine) {
this.engine = engine;
this.defineEngineSpeedControls();
this.fps = engine.fps;
}
defineEngineSpeedControls(){
this.slider = document.getElementById("slider");
this.slider.oninput = function() {
this.fps = this.slider.value
if (this.engine.running) {
this.changeEngineSpeed(this.fps);
}
}.bind(this);
$('#pause-button').click(function() {
if ($('#pause-button').text() == "Pause" && this.engine.running) {
$('#pause-button').text("Play")
this.engine.stop();
}
else if (!this.engine.running){
$('#pause-button').text("Pause")
this.engine.start(this.fps);
}
console.log()
}.bind(this));
}
changeEngineSpeed(change_val) {
this.engine.stop();
this.engine.start(change_val)
this.fps = this.engine.fps;
}
}
module.exports = ControlPanel;

View File

@@ -1,19 +1,26 @@
const Environment = require('./Environment');
const ControlPanel = require('./ControlPanel');
class Engine{
constructor(){
this.fps = 0;
this.environment = new Environment(5);
this.controlpanel = new ControlPanel(this);
this.environment.OriginOfLife();
this.last_update = Date.now();
this.delta_time = 0;
this.actual_fps = 0;
this.running = false;
}
start(fps=60) {
if (fps <= 0)
fps = 1;
if (fps > 500)
fps = 500;
this.fps = fps;
this.game_loop = setInterval(function(){this.update();}.bind(this), 1000/fps);
this.runnning = true;
this.running = true;
}
stop() {
@@ -27,6 +34,7 @@ class Engine{
this.last_update = Date.now();
this.environment.update(this.delta_time);
this.environment.render();
this.actual_fps = 1/this.delta_time*1000;
}
}

View File

@@ -39,7 +39,7 @@ class Organism {
for (var i=0; i<this.cells.length; i++) {
var cell = this.cells[i];
if (cell.loc_col == c && cell.loc_row == r){
if (cell.type == this.producer || cell.type == this.mover) {
if (cell.type == CellTypes.producer || cell.type == CellTypes.mover) {
check_change = true;
}
this.cells.splice(i, 1);
@@ -77,7 +77,7 @@ class Organism {
}
lifespan() {
return this.cells.length * 150;
return this.cells.length * 100;
}
reproduce() {
@@ -87,7 +87,9 @@ class Organism {
if (Math.random() * 100 <= this.mutability) {
org.mutate();
}
else if (Math.random() * 100 <= 2) {
if (Math.random() <= 0.5)
org.mutability++;
else{
org.mutability--;
if (org.mutability < 1)
org.mutability = 1;
@@ -96,7 +98,7 @@ class Organism {
var direction = this.getRandomDirection();
var direction_c = direction[0];
var direction_r = direction[1];
var offset = (Math.floor(Math.random() * 2));
var offset = (Math.floor(Math.random() * 2)) * 2;
var new_c = this.c + (direction_c*this.cells.length*2) + (direction_c*offset);
var new_r = this.r + (direction_r*this.cells.length*2) + (direction_r*offset);
@@ -113,14 +115,17 @@ class Organism {
}
mutate() {
this.mutability += 2;
var choice = Math.floor(Math.random() * 3);
if (choice == 0) {
// add cell
var type = CellTypes.getRandomLivingType();
var branch = this.cells[Math.floor(Math.random() * this.cells.length)];
var c = branch.loc_col+Math.floor(Math.random() * 2) - 1;
var r = branch.loc_row+Math.floor(Math.random() * 2) - 1;
return this.addCell(type, c, r);
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 c = branch.loc_col+Math.floor(Math.random() * 2) - 1;
var r = branch.loc_row+Math.floor(Math.random() * 2) - 1;
return this.addCell(type, c, r);
}
}
else if (choice == 1){
// change cell
@@ -157,7 +162,9 @@ class Organism {
this.c = new_c;
this.r = new_r;
this.updateGrid();
return true;
}
return false;
}
getRandomDirection(){
@@ -236,6 +243,9 @@ class Organism {
this.die();
return this.living;
}
if (this.food_collected >= this.foodNeeded()) {
this.reproduce();
}
for (var cell of this.cells) {
this.getRealCell(cell).performFunction(this.env);
}
@@ -244,14 +254,11 @@ class Organism {
}
if (this.is_mover) {
this.move_count++;
if (this.move_count > this.move_range){
var success = this.attemptMove(this.direction);
if (this.move_count > this.move_range || !success){
this.move_count = 0;
this.direction = this.getRandomDirection()
}
this.attemptMove(this.direction);
}
if (this.food_collected >= this.foodNeeded()) {
this.reproduce();
}
return this.living;

View File

@@ -5,9 +5,9 @@ class Renderer {
this.cell_size = cell_size;
this.env = env;
this.canvas = document.getElementById(canvas_id);
this.ctx = canvas.getContext("2d");
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.ctx = this.canvas.getContext("2d");
this.canvas.width = $('.env').width();
this.canvas.height = $('.env').height();
this.height = canvas.height;
this.width = canvas.width;
this.cells_to_render = new Set();

View File

@@ -2,5 +2,7 @@
import Engine from './Engine';
var engine = new Engine();
engine.start(45);
$('document').ready(function(){
var engine = new Engine();
engine.start(60);
});