mirror of
https://github.com/rileyjshaw/terra.git
synced 2024-11-21 04:54:23 +00:00
parent
080547d05b
commit
86440d10bf
@ -123,6 +123,7 @@ var factory = (function () {
|
|||||||
} else return this.energy !== this.maxEnergy;
|
} else return this.energy !== this.maxEnergy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
baseCA.prototype.actionRadius = 1;
|
||||||
baseCA.prototype.boundEnergy = function () {};
|
baseCA.prototype.boundEnergy = function () {};
|
||||||
baseCA.prototype.isDead = function () { return false; };
|
baseCA.prototype.isDead = function () { return false; };
|
||||||
baseCA.prototype.process = function (neighbors, x, y) {};
|
baseCA.prototype.process = function (neighbors, x, y) {};
|
||||||
@ -154,7 +155,7 @@ var factory = (function () {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var color = options.color;
|
var color = options.color || options.colour;
|
||||||
// set the color randomly if none is provided
|
// set the color randomly if none is provided
|
||||||
if (typeof color !== 'object' || color.length !== 3) {
|
if (typeof color !== 'object' || color.length !== 3) {
|
||||||
options.color = [_.random(255), _.random(255), _.random(255)];
|
options.color = [_.random(255), _.random(255), _.random(255)];
|
||||||
@ -185,12 +186,14 @@ var factory = (function () {
|
|||||||
function () { init.call(this); } :
|
function () { init.call(this); } :
|
||||||
function () {};
|
function () {};
|
||||||
|
|
||||||
var color = options.color;
|
var color = options.color = options.color || options.colour;
|
||||||
// set the color randomly if none is provided
|
// set the color randomly if none is provided
|
||||||
if (typeof color !== 'object' || color.length !== 3) {
|
if (typeof color !== 'object' || color.length !== 3) {
|
||||||
options.color = [_.random(255), _.random(255), _.random(255)];
|
options.color = [_.random(255), _.random(255), _.random(255)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.colorFn = options.colorFn || options.colourFn;
|
||||||
|
|
||||||
types[type].prototype = new baseCA();
|
types[type].prototype = new baseCA();
|
||||||
types[type].prototype.constructor = types[type];
|
types[type].prototype.constructor = types[type];
|
||||||
|
|
||||||
|
@ -16,9 +16,13 @@ var dom = require('./dom.js');
|
|||||||
* "background" option is required if trails is set
|
* "background" option is required if trails is set
|
||||||
* @param {array} background an RGB triplet for the canvas' background
|
* @param {array} background an RGB triplet for the canvas' background
|
||||||
*/
|
*/
|
||||||
function Terrarium(width, height, options) {
|
function Terrarium (width, height, options) {
|
||||||
|
var cellSize, neighborhood;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var cellSize = options.cellSize || 10;
|
cellSize = options.cellSize || 10;
|
||||||
|
neighborhood = options.neighborhood || options.neighbourhood;
|
||||||
|
if (typeof neighborhood === 'string') neighborhood = neighborhood.toLowerCase();
|
||||||
|
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.cellSize = cellSize;
|
this.cellSize = cellSize;
|
||||||
@ -28,6 +32,7 @@ function Terrarium(width, height, options) {
|
|||||||
this.grid = [];
|
this.grid = [];
|
||||||
this.nextFrame = false;
|
this.nextFrame = false;
|
||||||
this.hasChanged = false;
|
this.hasChanged = false;
|
||||||
|
this.getNeighborCoords = _.getNeighborCoordsFn(width, height, neighborhood === 'vonneumann', options.periodic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,7 +115,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
function processCreaturesInner (creature, x, y) {
|
function processCreaturesInner (creature, x, y) {
|
||||||
if (creature) {
|
if (creature) {
|
||||||
var neighbors = _.map(
|
var neighbors = _.map(
|
||||||
_.getNeighborCoords(x, y, gridWidth - 1, gridHeight - 1, creature.actionRadius),
|
self.getNeighborCoords(x, y, creature.actionRadius),
|
||||||
zipCoordsWithNeighbors
|
zipCoordsWithNeighbors
|
||||||
);
|
);
|
||||||
var result = creature.process(neighbors, x, y);
|
var result = creature.process(neighbors, x, y);
|
||||||
|
107
app/util.js
107
app/util.js
@ -9,26 +9,105 @@ var _ = require('../lodash_custom/lodash.custom.min.js')._;
|
|||||||
* Takes a cell and returns the coordinates of its neighbors
|
* Takes a cell and returns the coordinates of its neighbors
|
||||||
* @param {int} x0 - x position of cell
|
* @param {int} x0 - x position of cell
|
||||||
* @param {int} y0 - y position of cell
|
* @param {int} y0 - y position of cell
|
||||||
* @param {int} xMax - maximum x index i.e. grid width - 1
|
* @param {int} xMax - maximum x index i.e. grid width
|
||||||
* @param {int} yMax - maximum x index i.e. grid height - 1
|
* @param {int} yMax - maximum x index i.e. grid height
|
||||||
* @param {int} radius - (default = 1) neighbor radius
|
* @param {int} radius - (default = 1) neighbor radius
|
||||||
* @return {array} - an array of [x, y] pairs of the neighboring cells
|
* @return {array} - an array of [x, y] pairs of the neighboring cells
|
||||||
*/
|
*/
|
||||||
_.getNeighborCoords = function (x0, y0, xMax, yMax, radius) {
|
_.getNeighborCoordsFn = function (xMax, yMax, vonNeumann, periodic) {
|
||||||
var coords = [], current, xLo, xHi, yLo, yHi;
|
if (periodic) {
|
||||||
if (typeof radius !== 'number' || radius < 1) radius = 1;
|
if (vonNeumann) {
|
||||||
|
// periodic von neumann
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, rX, y, rY, rYMax;
|
||||||
|
|
||||||
xLo = Math.max(0, x0 - radius);
|
for (rX = -radius; rX <= radius; ++rX) {
|
||||||
yLo = Math.max(0, y0 - radius);
|
rYMax = radius - Math.abs(rX);
|
||||||
xHi = Math.min(x0 + radius, xMax);
|
for (rY = -rYMax; rY <= rYMax; ++rY) {
|
||||||
yHi = Math.min(y0 + radius, yMax);
|
x = ((rX + x0) % xMax + xMax) % xMax;
|
||||||
|
y = ((rY + y0) % yMax + yMax) % yMax;
|
||||||
|
if (x !== x0 || y !== y0) {
|
||||||
|
coords.push({
|
||||||
|
x: x,
|
||||||
|
y: y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var x = xLo; x <= xHi; x++)
|
return coords;
|
||||||
for (var y = yLo; y <= yHi; y++)
|
};
|
||||||
if (x !== x0 || y !== y0)
|
}
|
||||||
coords.push({ x: x, y: y });
|
else {
|
||||||
|
// periodic moore
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, xLo, xHi, y, yLo, yHi;
|
||||||
|
|
||||||
return coords;
|
xLo = x0 - radius;
|
||||||
|
yLo = y0 - radius;
|
||||||
|
xHi = x0 + radius;
|
||||||
|
yHi = y0 + radius;
|
||||||
|
|
||||||
|
for (x = xLo; x <= xHi; ++x) {
|
||||||
|
for (y = yLo; y <= yHi; ++y) {
|
||||||
|
if (x !== x0 || y !== y0) {
|
||||||
|
coords.push({
|
||||||
|
x: (x % xMax + xMax) % xMax,
|
||||||
|
y: (y % yMax + yMax) % yMax
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coords;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// non-periodic, need to restrict to within [0, max)
|
||||||
|
xMax -= 1;
|
||||||
|
yMax -= 1;
|
||||||
|
|
||||||
|
if (vonNeumann) {
|
||||||
|
//non-periodic von-neumann
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, rX, y, rY, rYMax;
|
||||||
|
|
||||||
|
for (rX = -radius; rX <= radius; ++rX) {
|
||||||
|
rYMax = radius - Math.abs(rX);
|
||||||
|
for (rY = -rYMax; rY <= rYMax; ++rY) {
|
||||||
|
x = rX + x0;
|
||||||
|
y = rY + y0;
|
||||||
|
if (x >= 0 && y >=0 && x <= xMax && y <= yMax && (x !== x0 || y !== y0)) {
|
||||||
|
coords.push({
|
||||||
|
x: x,
|
||||||
|
y: y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coords;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// non-periodic moore
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, xLo, xHi, y, yLo, yHi;
|
||||||
|
|
||||||
|
xLo = Math.max(0, x0 - radius);
|
||||||
|
yLo = Math.max(0, y0 - radius);
|
||||||
|
xHi = Math.min(x0 + radius, xMax);
|
||||||
|
yHi = Math.min(y0 + radius, yMax);
|
||||||
|
|
||||||
|
for (x = xLo; x <= xHi; ++x)
|
||||||
|
for (y = yLo; y <= yHi; ++y)
|
||||||
|
if (x !== x0 || y !== y0)
|
||||||
|
coords.push({ x: x, y: y });
|
||||||
|
|
||||||
|
return coords;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_.pickRandomWeighted = function (weightedArrays) {
|
_.pickRandomWeighted = function (weightedArrays) {
|
||||||
|
125
dist/terra.js
vendored
125
dist/terra.js
vendored
@ -134,6 +134,7 @@ var factory = (function () {
|
|||||||
} else return this.energy !== this.maxEnergy;
|
} else return this.energy !== this.maxEnergy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
baseCA.prototype.actionRadius = 1;
|
||||||
baseCA.prototype.boundEnergy = function () {};
|
baseCA.prototype.boundEnergy = function () {};
|
||||||
baseCA.prototype.isDead = function () { return false; };
|
baseCA.prototype.isDead = function () { return false; };
|
||||||
baseCA.prototype.process = function (neighbors, x, y) {};
|
baseCA.prototype.process = function (neighbors, x, y) {};
|
||||||
@ -165,7 +166,7 @@ var factory = (function () {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var color = options.color;
|
var color = options.color || options.colour;
|
||||||
// set the color randomly if none is provided
|
// set the color randomly if none is provided
|
||||||
if (typeof color !== 'object' || color.length !== 3) {
|
if (typeof color !== 'object' || color.length !== 3) {
|
||||||
options.color = [_.random(255), _.random(255), _.random(255)];
|
options.color = [_.random(255), _.random(255), _.random(255)];
|
||||||
@ -196,12 +197,14 @@ var factory = (function () {
|
|||||||
function () { init.call(this); } :
|
function () { init.call(this); } :
|
||||||
function () {};
|
function () {};
|
||||||
|
|
||||||
var color = options.color;
|
var color = options.color = options.color || options.colour;
|
||||||
// set the color randomly if none is provided
|
// set the color randomly if none is provided
|
||||||
if (typeof color !== 'object' || color.length !== 3) {
|
if (typeof color !== 'object' || color.length !== 3) {
|
||||||
options.color = [_.random(255), _.random(255), _.random(255)];
|
options.color = [_.random(255), _.random(255), _.random(255)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.colorFn = options.colorFn || options.colourFn;
|
||||||
|
|
||||||
types[type].prototype = new baseCA();
|
types[type].prototype = new baseCA();
|
||||||
types[type].prototype.constructor = types[type];
|
types[type].prototype.constructor = types[type];
|
||||||
|
|
||||||
@ -317,9 +320,13 @@ var dom = require('./dom.js');
|
|||||||
* "background" option is required if trails is set
|
* "background" option is required if trails is set
|
||||||
* @param {array} background an RGB triplet for the canvas' background
|
* @param {array} background an RGB triplet for the canvas' background
|
||||||
*/
|
*/
|
||||||
function Terrarium(width, height, options) {
|
function Terrarium (width, height, options) {
|
||||||
|
var cellSize, neighborhood;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var cellSize = options.cellSize || 10;
|
cellSize = options.cellSize || 10;
|
||||||
|
neighborhood = options.neighborhood || options.neighbourhood;
|
||||||
|
if (typeof neighborhood === 'string') neighborhood = neighborhood.toLowerCase();
|
||||||
|
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.cellSize = cellSize;
|
this.cellSize = cellSize;
|
||||||
@ -329,6 +336,7 @@ function Terrarium(width, height, options) {
|
|||||||
this.grid = [];
|
this.grid = [];
|
||||||
this.nextFrame = false;
|
this.nextFrame = false;
|
||||||
this.hasChanged = false;
|
this.hasChanged = false;
|
||||||
|
this.getNeighborCoords = _.getNeighborCoordsFn(width, height, neighborhood === 'vonneumann', options.periodic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -411,7 +419,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
function processCreaturesInner (creature, x, y) {
|
function processCreaturesInner (creature, x, y) {
|
||||||
if (creature) {
|
if (creature) {
|
||||||
var neighbors = _.map(
|
var neighbors = _.map(
|
||||||
_.getNeighborCoords(x, y, gridWidth - 1, gridHeight - 1, creature.actionRadius),
|
self.getNeighborCoords(x, y, creature.actionRadius),
|
||||||
zipCoordsWithNeighbors
|
zipCoordsWithNeighbors
|
||||||
);
|
);
|
||||||
var result = creature.process(neighbors, x, y);
|
var result = creature.process(neighbors, x, y);
|
||||||
@ -553,26 +561,105 @@ var _ = require('../lodash_custom/lodash.custom.min.js')._;
|
|||||||
* Takes a cell and returns the coordinates of its neighbors
|
* Takes a cell and returns the coordinates of its neighbors
|
||||||
* @param {int} x0 - x position of cell
|
* @param {int} x0 - x position of cell
|
||||||
* @param {int} y0 - y position of cell
|
* @param {int} y0 - y position of cell
|
||||||
* @param {int} xMax - maximum x index i.e. grid width - 1
|
* @param {int} xMax - maximum x index i.e. grid width
|
||||||
* @param {int} yMax - maximum x index i.e. grid height - 1
|
* @param {int} yMax - maximum x index i.e. grid height
|
||||||
* @param {int} radius - (default = 1) neighbor radius
|
* @param {int} radius - (default = 1) neighbor radius
|
||||||
* @return {array} - an array of [x, y] pairs of the neighboring cells
|
* @return {array} - an array of [x, y] pairs of the neighboring cells
|
||||||
*/
|
*/
|
||||||
_.getNeighborCoords = function (x0, y0, xMax, yMax, radius) {
|
_.getNeighborCoordsFn = function (xMax, yMax, vonNeumann, periodic) {
|
||||||
var coords = [], current, xLo, xHi, yLo, yHi;
|
if (periodic) {
|
||||||
if (typeof radius !== 'number' || radius < 1) radius = 1;
|
if (vonNeumann) {
|
||||||
|
// periodic von neumann
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, rX, y, rY, rYMax;
|
||||||
|
|
||||||
xLo = Math.max(0, x0 - radius);
|
for (rX = -radius; rX <= radius; ++rX) {
|
||||||
yLo = Math.max(0, y0 - radius);
|
rYMax = radius - Math.abs(rX);
|
||||||
xHi = Math.min(x0 + radius, xMax);
|
for (rY = -rYMax; rY <= rYMax; ++rY) {
|
||||||
yHi = Math.min(y0 + radius, yMax);
|
x = ((rX + x0) % xMax + xMax) % xMax;
|
||||||
|
y = ((rY + y0) % yMax + yMax) % yMax;
|
||||||
|
if (x !== x0 || y !== y0) {
|
||||||
|
coords.push({
|
||||||
|
x: x,
|
||||||
|
y: y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var x = xLo; x <= xHi; x++)
|
return coords;
|
||||||
for (var y = yLo; y <= yHi; y++)
|
};
|
||||||
if (x !== x0 || y !== y0)
|
}
|
||||||
coords.push({ x: x, y: y });
|
else {
|
||||||
|
// periodic moore
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, xLo, xHi, y, yLo, yHi;
|
||||||
|
|
||||||
return coords;
|
xLo = x0 - radius;
|
||||||
|
yLo = y0 - radius;
|
||||||
|
xHi = x0 + radius;
|
||||||
|
yHi = y0 + radius;
|
||||||
|
|
||||||
|
for (x = xLo; x <= xHi; ++x) {
|
||||||
|
for (y = yLo; y <= yHi; ++y) {
|
||||||
|
if (x !== x0 || y !== y0) {
|
||||||
|
coords.push({
|
||||||
|
x: (x % xMax + xMax) % xMax,
|
||||||
|
y: (y % yMax + yMax) % yMax
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coords;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// non-periodic, need to restrict to within [0, max)
|
||||||
|
xMax -= 1;
|
||||||
|
yMax -= 1;
|
||||||
|
|
||||||
|
if (vonNeumann) {
|
||||||
|
//non-periodic von-neumann
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, rX, y, rY, rYMax;
|
||||||
|
|
||||||
|
for (rX = -radius; rX <= radius; ++rX) {
|
||||||
|
rYMax = radius - Math.abs(rX);
|
||||||
|
for (rY = -rYMax; rY <= rYMax; ++rY) {
|
||||||
|
x = rX + x0;
|
||||||
|
y = rY + y0;
|
||||||
|
if (x >= 0 && y >=0 && x <= xMax && y <= yMax && (x !== x0 || y !== y0)) {
|
||||||
|
coords.push({
|
||||||
|
x: x,
|
||||||
|
y: y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coords;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// non-periodic moore
|
||||||
|
return function (x0, y0, radius) {
|
||||||
|
var coords = [], x, xLo, xHi, y, yLo, yHi;
|
||||||
|
|
||||||
|
xLo = Math.max(0, x0 - radius);
|
||||||
|
yLo = Math.max(0, y0 - radius);
|
||||||
|
xHi = Math.min(x0 + radius, xMax);
|
||||||
|
yHi = Math.min(y0 + radius, yMax);
|
||||||
|
|
||||||
|
for (x = xLo; x <= xHi; ++x)
|
||||||
|
for (y = yLo; y <= yHi; ++y)
|
||||||
|
if (x !== x0 || y !== y0)
|
||||||
|
coords.push({ x: x, y: y });
|
||||||
|
|
||||||
|
return coords;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_.pickRandomWeighted = function (weightedArrays) {
|
_.pickRandomWeighted = function (weightedArrays) {
|
||||||
|
2
dist/terra.min.js
vendored
2
dist/terra.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user