Merge pull request #81 from MaxRobinsonTheGreat/random-walls
Random walls
This commit is contained in:
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
46
src/Utils/Perlin.js
Normal 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;
|
||||
Reference in New Issue
Block a user