Skip to content

Instantly share code, notes, and snippets.

@KrofDrakula
Created December 8, 2012 14:16
Show Gist options
  • Save KrofDrakula/4240421 to your computer and use it in GitHub Desktop.
Save KrofDrakula/4240421 to your computer and use it in GitHub Desktop.
/node_modules
Array.prototype.hasCell = function(cell) {
if (arguments.length == 2) cell = new Cell(arguments[0], arguments[1]);
return this.filter(function(c) {
return c.x == cell.x && c.y == cell.y;
}).length > 0;
};
function World(cells) {
this.cells = cells || [];
}
World.prototype.advanceStep = function() {
var candidates = this.computeCandidates(),
newState = [];
candidates.forEach(function(cell) {
var neighbours = this.findNeighbours(cell);
if (neighbours.length == 2 && this.cells.hasCell(cell) || neighbours.length == 3)
newState.push(cell);
}, this);
this.cells = newState;
};
World.prototype.computeCandidates = function() {
var candidates = [];
this.cells.forEach(function(cell) {
for (var t = 0; t < 9; t++) {
var x = (t % 3) - 1, y = Math.floor(t / 3) - 1,
c = new Cell(cell.x + x, cell.y + y);
if (!candidates.hasCell(c))
candidates.push(c);
}
}, this);
return candidates;
};
World.prototype.findNeighbours = function(reference) {
var neighbours = [];
for (var y = reference.y - 1; y <= reference.y + 1; y++)
for (var x = reference.x - 1; x <= reference.x + 1; x++) {
if (x == reference.x && y == reference.y) continue;
var c = new Cell(x, y);
if (this.cells.hasCell(c)) neighbours.push(c);
}
return neighbours;
};
World.prototype.render = function() {
var bounds = this.getBoundingBox(),
screen = '';
for (var y = bounds.top; y <= bounds.bottom; y++) {
for (var x = bounds.left; x <= bounds.right; x++) {
screen += (this.cells.hasCell(x, y)) ? 'X' : ' ';
}
screen += '\n';
}
console.log(screen);
};
World.prototype.getBoundingBox = function() {
var bounds = {
left : Infinity,
top : Infinity,
right : -Infinity,
bottom : -Infinity
};
this.cells.reduce(function(u, v) {
u.left = Math.min(u.left, v.x);
u.top = Math.min(u.top, v.y);
u.right = Math.max(u.right, v.x);
u.bottom = Math.max(u.bottom, v.y);
return u;
}, bounds);
return bounds;
};
World.parse = function(source) {
var cells = [];
source.split('\n').forEach(function(line, y) {
for (var x = 0; x < line.length; x++) {
if (line[x] != ' ') cells.push(new Cell(x, y));
}
}, this);
return new World(cells);
};
function Cell(x, y) {
this.x = x;
this.y = y;
}
module.exports = {
World : World,
Cell : Cell
};
var fs = require('fs');
var gol = require('./gol'),
World = gol.World,
Cell = gol.Cell;
var w = World.parse(fs.readFileSync('pattern.txt', 'utf8'));
while(true) {
w.render();
w.advanceStep();
}
xxxxxxxx xxxxx xxx xxxxxxx xxxxx
require('chai').should();
var gol = require('./gol'),
World = gol.World,
Cell = gol.Cell;
describe('known patterns', function() {
describe('square', function() {
it('should be static', function() {
var w = new World([
new Cell(0,0),
new Cell(1,0),
new Cell(0,1),
new Cell(1,1)
]);
w.advanceStep();
w.cells.length.should.equal(4);
w.cells.hasCell(0,0).should.be.true;
w.cells.hasCell(1,0).should.be.true;
w.cells.hasCell(0,1).should.be.true;
w.cells.hasCell(1,1).should.be.true;
});
it('should have alternating lines', function() {
var w = new World([
new Cell(1, 0),
new Cell(1, 1),
new Cell(1, 2)
]);
w.advanceStep();
w.cells.length.should.equal(3);
w.cells.hasCell(0,1).should.be.true;
w.cells.hasCell(1,1).should.be.true;
w.cells.hasCell(2,1).should.be.true;
w.advanceStep();
w.cells.length.should.equal(3);
w.cells.hasCell(1,0).should.be.true;
w.cells.hasCell(1,1).should.be.true;
w.cells.hasCell(1,2).should.be.true;
});
it('should return a valid bounding box', function() {
var w = new World([
new Cell(0,0),
new Cell(3,4)
]);
var box = w.getBoundingBox();
box.left.should.equal(0);
box.top.should.equal(0);
box.right.should.equal(3);
box.bottom.should.equal(4);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment