Merge pull request #81 from MaxRobinsonTheGreat/random-walls

Random walls
This commit is contained in:
Max Robinson
2021-12-17 19:01:28 -06:00
committed by GitHub
6 changed files with 88 additions and 8 deletions

View File

@@ -327,6 +327,9 @@ class ControlPanel {
env.auto_reset = false;
$('#auto-reset').prop('checked', false);;
});
$('#random-walls').click( function() {
this.env_controller.randomizeWalls();
}.bind(this));
$('#auto-reset').change(function() {
env.auto_reset = this.checked;
});

View File

@@ -5,6 +5,7 @@ const CellStates = require("../Organism/Cell/CellStates");
const Neighbors = require("../Grid/Neighbors");
const FossilRecord = require("../Stats/FossilRecord");
const Hyperparams = require("../Hyperparameters");
const Perlin = require("../Utils/Perlin");
class EnvironmentController extends CanvasController{
constructor(env, canvas) {
@@ -51,8 +52,34 @@ class EnvironmentController extends CanvasController{
this.scale = 1;
}
/*
Iterate over grid from 0,0 to env.num_cols,env.num_rows and create random walls using perlin noise to create a more organic shape.
*/
randomizeWalls(thickness=1) {
this.env.clearWalls();
const noise_threshold = -0.017;
let avg_noise = 0;
let resolution = 20;
Perlin.seed();
for (let r = 0; r < this.env.num_rows; r++) {
for (let c = 0; c < this.env.num_cols; c++) {
let xval = c/this.env.num_cols*(resolution/this.env.renderer.cell_size*(this.env.num_cols/this.env.num_rows));
let yval = r/this.env.num_rows*(resolution/this.env.renderer.cell_size*(this.env.num_rows/this.env.num_cols));
let noise = Perlin.get(xval, yval);
avg_noise += noise/(this.env.num_rows*this.env.num_cols);
if (noise > noise_threshold && noise < noise_threshold + thickness/resolution) {
let cell = this.env.grid_map.cellAt(c, r);
if (cell != null) {
if(cell.owner != null) cell.owner.die();
this.env.changeCell(c, r, CellStates.wall, null);
}
}
}
}
}
updateMouseLocation(offsetX, offsetY){
super.updateMouseLocation(offsetX, offsetY);
}

View File

@@ -12,9 +12,9 @@ class WorldEnvironment extends Environment{
super();
this.renderer = new Renderer('env-canvas', 'env', cell_size);
this.controller = new EnvironmentController(this, this.renderer.canvas);
var grid_rows = Math.ceil(this.renderer.height / cell_size);
var grid_cols = Math.ceil(this.renderer.width / cell_size);
this.grid_map = new GridMap(grid_cols, grid_rows, cell_size);
this.num_rows = Math.ceil(this.renderer.height / cell_size);
this.num_cols = Math.ceil(this.renderer.width / cell_size);
this.grid_map = new GridMap(this.num_cols, this.num_rows, cell_size);
this.organisms = [];
this.walls = [];
this.total_mutability = 0;
@@ -104,7 +104,8 @@ class WorldEnvironment extends Environment{
clearWalls() {
for(var wall of this.walls){
if (this.grid_map.cellAt(wall.col, wall.row).state == CellStates.wall)
let wcell = this.grid_map.cellAt(wall.col, wall.row);
if (wcell && wcell.state == CellStates.wall)
this.changeCell(wall.col, wall.row, CellStates.empty, null);
}
}
@@ -154,9 +155,9 @@ class WorldEnvironment extends Environment{
resizeFillWindow(cell_size) {
this.renderer.cell_size = cell_size;
this.renderer.fillWindow('env');
var cols = Math.ceil(this.renderer.width / cell_size);
var rows = Math.ceil(this.renderer.height / cell_size);
this.grid_map.resize(cols, rows, cell_size);
this.num_cols = Math.ceil(this.renderer.width / cell_size);
this.num_rows = Math.ceil(this.renderer.height / cell_size);
this.grid_map.resize(this.num_cols, this.num_rows, cell_size);
}
}

46
src/Utils/Perlin.js Normal file
View File

@@ -0,0 +1,46 @@
let perlin = {
rand_vect: function(){
let theta = Math.random() * 2 * Math.PI;
return {x: Math.cos(theta), y: Math.sin(theta)};
},
dot_prod_grid: function(x, y, vx, vy){
let g_vect;
let d_vect = {x: x - vx, y: y - vy};
if (this.gradients[[vx,vy]]){
g_vect = this.gradients[[vx,vy]];
} else {
g_vect = this.rand_vect();
this.gradients[[vx, vy]] = g_vect;
}
return d_vect.x * g_vect.x + d_vect.y * g_vect.y;
},
smootherstep: function(x){
return 6*x**5 - 15*x**4 + 10*x**3;
},
interp: function(x, a, b){
return a + this.smootherstep(x) * (b-a);
},
seed: function(){
this.gradients = {};
this.memory = {};
},
get: function(x, y) {
if (this.memory.hasOwnProperty([x,y]))
return this.memory[[x,y]];
let xf = Math.floor(x);
let yf = Math.floor(y);
//interpolate
let tl = this.dot_prod_grid(x, y, xf, yf);
let tr = this.dot_prod_grid(x, y, xf+1, yf);
let bl = this.dot_prod_grid(x, y, xf, yf+1);
let br = this.dot_prod_grid(x, y, xf+1, yf+1);
let xt = this.interp(x-xf, tl, tr);
let xb = this.interp(x-xf, bl, br);
let v = this.interp(y-yf, xt, xb);
this.memory[[x,y]] = v;
return v;
}
}
perlin.seed();
module.exports = perlin;