Public
Edited
Jul 2, 2024
Insert cell
Insert cell
function convolution(matrix, oriArr, loc, index = 0) {
const locX = loc[0], locY = loc[1];
const oriH = oriArr.length
const oriW = oriArr[0].length;
const matSizeX = matrix.length;
if (matSizeX % 2 === 0 || matSizeX < 1) return oriArr[locY,locX];
const matSizeY = matrix[0].length;
if (matSizeY % 2 === 0 || matSizeY < 1) return oriArr[locY,locX];
const offsetX = Math.floor(matSizeX / 2);
const offsetY = Math.floor(matSizeY / 2);
let res = 0;
for (let y = 0; y < matSizeY; y ++) {
for (let x = 0; x < matSizeX; x ++) {
const matValue = matrix[y][x];
const readX = (oriW + (locX - offsetX + x)) % oriW;
const readY = (oriH + (locY - offsetY + y)) % oriH;
const readState = oriArr[readY][readX].state;
const reading = Array.isArray(readState) ? readState[index] : readState;
res += matValue * reading;
}
}
return res;
}
Insert cell
Insert cell
class Cell{
constructor(grid, loc, state){
this.grid = grid; // reference to the grid
this.loc = loc; // array of [x, y]
this.state = state;
}
}
Insert cell
Insert cell
Insert cell
perception_gameOfLife = function() {
const convolutionMatrix = [[1,1,1],[1,0,1],[1,1,1]];
return convolution(convolutionMatrix, this.grid, this.loc)
}
Insert cell
update_gameOfLife = function () {
const perception = this.perceive()
if(this.state === 1) {
if (perception < 2 || perception > 3) this.state = 0;
} else {
if (perception === 3) this.state = 1;
}
}
Insert cell
Insert cell
init_gameOfLife = function () {
grid.forEach(row => {
row.forEach(cell => {
cell.state = Math.random() > 0.9 ? 1 : 0;
//bind the perception and update function to the cell
(cell.perceive = perception_gameOfLife).bind(cell);
(cell.update = update_gameOfLife).bind(cell);
})
})
}
Insert cell
Insert cell
step_gameOfLife = function () {
grid.forEach(row =>{
row.forEach(cell => {
cell.update()
})
})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
perception_nca1 = function(){
const mat = reshape(input1.mat.map(el => el.value),[3,3]);
return convolution(mat, this.grid, this.loc);
}
Insert cell
update_nca1 = function(){
const perception = this.perceive();
const F = new Function("x", input1.activationFunction.value);
this.state = F(perception);
if (this.state < 0) this.state = 0;
if (this.state > 1) this.state = 1;
}
Insert cell
init_nca1 = function () {
grid2.forEach(row => {
row.forEach(cell => {
cell.state = Math.random();
//bind the perception and update function to the cell
(cell.perceive = perception_nca1).bind(cell);
(cell.update = update_nca1).bind(cell);
})
})
}
Insert cell
step_nca1 = function () {
grid2.forEach(row =>{
row.forEach(cell => {
cell.update()
})
})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
perception_rgb = function () {
const mats = input2.mats.map(mat => reshape(mat.map(e => e.value),[3,3]))
let res = new Array(this.state.length);
for (let i = 0; i < this.state.length; ++i) {
res[i] = convolution(mats[i], this.grid, this.loc, i);
}
return res;
}
Insert cell
update_rgb = function () {
const perception = this.perceive();
const F = new Function("x", input2.activationFunction.value);
this.state = perception.map(c => F(c));
}
Insert cell
init_rgb = function () {
grid3.forEach(row => {
row.forEach(cell => {
cell.state = [Math.random(), Math.random(), Math.random()];
//bind the perception and update function to the cell
(cell.perceive = perception_rgb).bind(cell);
(cell.update = update_rgb).bind(cell);
})
})
}
Insert cell
step_rgb = function () {
grid3.forEach(row =>{
row.forEach(cell => {
cell.update()
})
})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
perception_async = perception_rgb
Insert cell
update_async = function () {
if (this.updateTimer > 0) {
this.updateTimer --;
} else {
const perception = this.perceive();
const F = new Function("x", input2.activationFunction.value);
this.state = perception.map(c => F(c));
this.updateTimer = Math.floor(Math.random() * 15);
}
}
Insert cell
init_async = function () {
grid4.forEach(row => {
row.forEach(cell => {
cell.state = [Math.random(), Math.random(), Math.random()];
cell.updateTimer = Math.floor(Math.random() * 15);
//bind the perception and update function to the cell
(cell.perceive = perception_async).bind(cell);
(cell.update = update_async).bind(cell);
})
})
}
Insert cell
step_async = function () {
grid4.forEach(row =>{
row.forEach(cell => {
cell.update()
})
})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more