mirror of
https://github.com/rileyjshaw/terra.git
synced 2024-11-21 04:54:23 +00:00
Fix #13: add a method to populate a terrarium non-randomly
This commit is contained in:
parent
02e2609ed5
commit
1988080a86
@ -22,35 +22,40 @@ function Terrarium(width, height, id, cellSize, insertAfter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates a terrarium with a set distribution of creatures
|
* Create a grid and fill it by using a function, 2-d array, or uniform type
|
||||||
* @param {array} creatures an array of arrays of the form [string 'creatureName', int fillPercent]
|
* @param {*} content if function, fill grid according to fn(x, y)
|
||||||
* @param {[type]} grid the grid to fill
|
* if array, fill grid cells with the corresponding creatureType
|
||||||
|
* if string, fill grid with that creatureType
|
||||||
|
* otherwise, create empty grid
|
||||||
|
* @return {grid} a grid adhering to the above rules
|
||||||
*/
|
*/
|
||||||
Terrarium.prototype.populate = function (creatures, grid) {
|
Terrarium.prototype.makeGrid = function (content) {
|
||||||
function pickCreature(accum, creature) {
|
var grid = [], type = typeof content, creature;
|
||||||
var percentage = accum + creature[1];
|
for (var x = 0, _w = this.width; x < _w; x++) {
|
||||||
if (!current && percentage > rand) {
|
grid.push([]);
|
||||||
current = creatureFactory.make(creature[0]);
|
for (var y = 0, _h = this.height; y < _h; y++) {
|
||||||
|
grid[x].push(creatureFactory.make(
|
||||||
|
type === 'function' ? content(x, y) :
|
||||||
|
type === 'object' && content.length ? (content[y] || [])[x] :
|
||||||
|
type === 'string' ? content :
|
||||||
|
undefined
|
||||||
|
));
|
||||||
}
|
}
|
||||||
return percentage;
|
} return grid;
|
||||||
}
|
};
|
||||||
|
|
||||||
var current, rand = 0;
|
/**
|
||||||
if (!grid) grid = this.grid;
|
* Create a grid and fill it randomly with a set creature distribution
|
||||||
|
* @param {array} distribution an array of arrays of the form [string 'creatureName', float fillPercent]
|
||||||
for (var x = this.width; x--;) {
|
*/
|
||||||
grid[x] = [];
|
Terrarium.prototype.makeGridWithDistribution = function (distribution) {
|
||||||
// populate the array with creatures if provided,
|
var current, rand = 0, grid = [];
|
||||||
// otherwise leave it sparse
|
for (var x = 0, _w = this.width; x < _w; x++) {
|
||||||
if (creatures) {
|
grid.push([]);
|
||||||
for (var y = this.height; y--;) {
|
for (var y = 0, _h = this.height; y < _h; y++) {
|
||||||
current = false;
|
grid[x].push(creatureFactory.make(_.pickRandomWeighted(distribution)));
|
||||||
rand = _.random(100, true);
|
|
||||||
_.reduce(creatures, pickCreature, 0);
|
|
||||||
grid[x].push(current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} return grid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +67,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
function copyAndRemoveInner (origCreature) {
|
function copyAndRemoveInner (origCreature) {
|
||||||
if (origCreature) {
|
if (origCreature) {
|
||||||
var copy = _.assign(new (origCreature.constructor)(), origCreature);
|
var copy = _.assign(new (origCreature.constructor)(), origCreature);
|
||||||
return copy.isDead() ? false : copy;
|
return copy && !copy.isDead() ? copy : false;
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +125,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
var winnerCreature = winner.creature;
|
var winnerCreature = winner.creature;
|
||||||
|
|
||||||
// clear the original creature's square if successFn returns false
|
// clear the original creature's square if successFn returns false
|
||||||
if (winnerCreature.successFn() === false) {
|
if (!winnerCreature.successFn()) {
|
||||||
newGrid[winner.x][winner.y] = false;
|
newGrid[winner.x][winner.y] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,8 +158,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
newGrid = _.map(oldGrid, copyAndRemove);
|
newGrid = _.map(oldGrid, copyAndRemove);
|
||||||
|
|
||||||
// create an empty grid to hold creatures competing for the same square
|
// create an empty grid to hold creatures competing for the same square
|
||||||
eigenGrid = [];
|
eigenGrid = this.makeGrid();
|
||||||
this.populate(false, eigenGrid);
|
|
||||||
|
|
||||||
// Add each creature's intended destination to the eigenGrid
|
// Add each creature's intended destination to the eigenGrid
|
||||||
_.each(newGrid, processCreatures);
|
_.each(newGrid, processCreatures);
|
||||||
|
10
app/util.js
10
app/util.js
@ -31,6 +31,16 @@ _.getNeighborCoords = function (x0, y0, xMax, yMax, radius) {
|
|||||||
return coords;
|
return coords;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_.pickRandomWeighted = function (weightedArrays) {
|
||||||
|
var sum = 0, rand = _.random(100, true);
|
||||||
|
var cur, i;
|
||||||
|
for (i = 0, _len = weightedArrays.length; i < _len; i++) {
|
||||||
|
cur = weightedArrays[i];
|
||||||
|
sum += cur[1];
|
||||||
|
if (sum > rand) return cur[0];
|
||||||
|
} return false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CommonJS exports
|
* CommonJS exports
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
|
72
dist/terra.js
vendored
72
dist/terra.js
vendored
@ -280,35 +280,40 @@ function Terrarium(width, height, id, cellSize, insertAfter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates a terrarium with a set distribution of creatures
|
* Create a grid and fill it by using a function, 2-d array, or uniform type
|
||||||
* @param {array} creatures an array of arrays of the form [string 'creatureName', int fillPercent]
|
* @param {*} content if function, fill grid according to fn(x, y)
|
||||||
* @param {[type]} grid the grid to fill
|
* if array, fill grid cells with the corresponding creatureType
|
||||||
|
* if string, fill grid with that creatureType
|
||||||
|
* otherwise, create empty grid
|
||||||
|
* @return {grid} a grid adhering to the above rules
|
||||||
*/
|
*/
|
||||||
Terrarium.prototype.populate = function (creatures, grid) {
|
Terrarium.prototype.makeGrid = function (content) {
|
||||||
function pickCreature(accum, creature) {
|
var grid = [], type = typeof content, creature;
|
||||||
var percentage = accum + creature[1];
|
for (var x = 0, _w = this.width; x < _w; x++) {
|
||||||
if (!current && percentage > rand) {
|
grid.push([]);
|
||||||
current = creatureFactory.make(creature[0]);
|
for (var y = 0, _h = this.height; y < _h; y++) {
|
||||||
|
grid[x].push(creatureFactory.make(
|
||||||
|
type === 'function' ? content(x, y) :
|
||||||
|
type === 'object' && content.length ? (content[y] || [])[x] :
|
||||||
|
type === 'string' ? content :
|
||||||
|
undefined
|
||||||
|
));
|
||||||
}
|
}
|
||||||
return percentage;
|
} return grid;
|
||||||
}
|
};
|
||||||
|
|
||||||
var current, rand = 0;
|
/**
|
||||||
if (!grid) grid = this.grid;
|
* Create a grid and fill it randomly with a set creature distribution
|
||||||
|
* @param {array} distribution an array of arrays of the form [string 'creatureName', float fillPercent]
|
||||||
for (var x = this.width; x--;) {
|
*/
|
||||||
grid[x] = [];
|
Terrarium.prototype.makeGridWithDistribution = function (distribution) {
|
||||||
// populate the array with creatures if provided,
|
var current, rand = 0, grid = [];
|
||||||
// otherwise leave it sparse
|
for (var x = 0, _w = this.width; x < _w; x++) {
|
||||||
if (creatures) {
|
grid.push([]);
|
||||||
for (var y = this.height; y--;) {
|
for (var y = 0, _h = this.height; y < _h; y++) {
|
||||||
current = false;
|
grid[x].push(creatureFactory.make(_.pickRandomWeighted(distribution)));
|
||||||
rand = _.random(100, true);
|
|
||||||
_.reduce(creatures, pickCreature, 0);
|
|
||||||
grid[x].push(current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} return grid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -320,7 +325,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
function copyAndRemoveInner (origCreature) {
|
function copyAndRemoveInner (origCreature) {
|
||||||
if (origCreature) {
|
if (origCreature) {
|
||||||
var copy = _.assign(new (origCreature.constructor)(), origCreature);
|
var copy = _.assign(new (origCreature.constructor)(), origCreature);
|
||||||
return copy.isDead() ? false : copy;
|
return copy && !copy.isDead() ? copy : false;
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +383,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
var winnerCreature = winner.creature;
|
var winnerCreature = winner.creature;
|
||||||
|
|
||||||
// clear the original creature's square if successFn returns false
|
// clear the original creature's square if successFn returns false
|
||||||
if (winnerCreature.successFn() === false) {
|
if (!winnerCreature.successFn()) {
|
||||||
newGrid[winner.x][winner.y] = false;
|
newGrid[winner.x][winner.y] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,8 +416,7 @@ Terrarium.prototype.step = function (steps) {
|
|||||||
newGrid = _.map(oldGrid, copyAndRemove);
|
newGrid = _.map(oldGrid, copyAndRemove);
|
||||||
|
|
||||||
// create an empty grid to hold creatures competing for the same square
|
// create an empty grid to hold creatures competing for the same square
|
||||||
eigenGrid = [];
|
eigenGrid = this.makeGrid();
|
||||||
this.populate(false, eigenGrid);
|
|
||||||
|
|
||||||
// Add each creature's intended destination to the eigenGrid
|
// Add each creature's intended destination to the eigenGrid
|
||||||
_.each(newGrid, processCreatures);
|
_.each(newGrid, processCreatures);
|
||||||
@ -498,6 +502,16 @@ _.getNeighborCoords = function (x0, y0, xMax, yMax, radius) {
|
|||||||
return coords;
|
return coords;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_.pickRandomWeighted = function (weightedArrays) {
|
||||||
|
var sum = 0, rand = _.random(100, true);
|
||||||
|
var cur, i;
|
||||||
|
for (i = 0, _len = weightedArrays.length; i < _len; i++) {
|
||||||
|
cur = weightedArrays[i];
|
||||||
|
sum += cur[1];
|
||||||
|
if (sum > rand) return cur[0];
|
||||||
|
} return false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CommonJS exports
|
* CommonJS exports
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
|
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