Skip to content

Instantly share code, notes, and snippets.

@pawelmhm
Created June 15, 2013 22:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pawelmhm/5789763 to your computer and use it in GitHub Desktop.
Save pawelmhm/5789763 to your computer and use it in GitHub Desktop.
A CodePen by pawelmhm.
<canvas id="canvas" width="600" height="600"></canvas>
function Cell(x, y, size) {
this.x = x;
this.y = y;
this.size = 10;
this.neighbors = [];
}
Cell.prototype = {
constructor: Cell,
sayName: function () {
return [this.x, this.y];
},
getX: function () {
return this.x;
},
getY: function () {
return this.y;
},
};
function Empty(x, y) {
Cell.call(this, x, y);
this.state = 0;
this.colour = '#000';
}
Empty.prototype = new Cell();
function Tree(x, y) {
Cell.call(this, x, y);
this.state = 1;
this.colour = '#00CC33';
}
Tree.prototype = new Cell();
function BurningTree(x, y) {
Cell.call(this, x, y);
this.state = 2;
this.colour = '#FF0000';
}
BurningTree.prototype = new Cell();
function Forest(sizeX, sizeY, canvas, probOfFire, probOfGrowth) {
this.sizeX = sizeX;
this.sizeY = sizeY;
this.cells = [];
this.canvas = canvas;
this.cx = canvas.getContext('2d');
this.probOfFire = probOfFire;
this.probOfGrowth = probOfGrowth;
}
Forest.prototype = {
constructor: Forest,
addCell: function (newCell) {
this.cells.push(newCell);
this.drawCell(newCell);
},
removeCell: function (cell) {
var cut = this.cells.indexOf(cell);
this.cells.splice(cut, 1);
},
growTree: function (emptyCell) {
var diceNature = Math.random();
if (diceNature < this.probOfGrowth) {
var x = emptyCell.getX();
var y = emptyCell.getY();
this.removeCell(emptyCell);
var newTree = new Tree(x, y);
this.addCell(newTree);
}
},
burnTree: function (tree) {
var dice = Math.random();
/* var neighbors = this.getNeighbors(tree);
for (i = 0; i < neighbors.length; i++) {
if (neighbors[i] instanceof BurningTree) {
var neighborBurning = true;
break;
}
} */
if ((dice < this.probOfFire)) {
var x = tree.x;
var y = tree.y;
this.removeCell(tree);
var newBurningTree = new BurningTree(x, y);
this.addCell(newBurningTree);
}
},
endBurning: function (burningTree) {
var x = burningTree.x;
var y = burningTree.y;
this.removeCell(burningTree);
var newEmpty = new Empty(x, y);
this.addCell(newEmpty);
},
getAllCells: function () {
return this.cells;
},
updateForest: function () {
for (i = 0; i < this.cells.length; i++) {
if (this.cells[i] instanceof Tree) {
var tree = this.cells[i];
this.burnTree(tree);
} else if (this.cells[i] instanceof BurningTree) {
var burningTree = this.cells[i];
this.endBurning(burningTree);
} else if (this.cells[i] instanceof Empty) {
var empty = this.cells[i];
this.growTree(empty);
}
}
},
drawSquare: function (cx, posX, posY, size, color) {
cx.fillStyle = color;
cx.fillRect(posX, posY, size, size);
},
drawCircle: function (cx, posX, posY, size, color) {
var centerX = posX;
var centerY = posY;
var radius = size / 2;
cx.beginPath();
cx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
cx.fillStyle = color;
cx.fill();
cx.lineWidth = 2;
cx.strokeStyle = '#000';
cx.stroke();
},
drawCell: function (cell) {
var posX = cell.x;
var posY = cell.y;
var colour = cell.colour;
var size = cell.size;
this.drawSquare(this.cx, posX, posY, size, colour);
/* this.drawCircle(this.cx, posX, posY, size, colour);*/
},
populate: function (cell) {
var width = this.canvas.width;
var height = this.canvas.height;
var numOfSquares = (width * height) / (cell.size * cell.size);
var i = 0;
var posX = 0;
var posY = 0;
while (i < numOfSquares) {
if (posX >= width - cell.size) {
posY += cell.size + 2;
posX = 0;
}
var e = new Tree(posX, posY);
this.addCell(e);
posX += cell.size + 1;
i += 1;
}
},
getNeighbors: function (cell) {
var width = this.sizeX;
var height = this.sizeY;
var neighbors = [];
var position = this.cells.indexOf(cell);
neighbors.push(this.cells[position - 1]);
neighbors.push(this.cells[position + 1]);
neighbors.push(this.cells[position + (width / cell.size)]);
neighbors.push(this.cells[position - (width / cell.size)]);
neighbors.push(this.cells[position + (width / cell.size + cell.size)]);
neighbors.push(this.cells[position + (width / cell.size - cell.size)]);
console.log(neighbors);
return neighbors;
}
};
cx = document.getElementById('canvas');
function deadForest() {
las = new Forest(cx.width, cx.height, cx, 0.1, 0.0);
cell = new Cell(0, 0);
las.populate(cell);
window.setInterval(refresh, 520);
function refresh() {
las.updateForest();
}
}
function forestWithNoFire() {
las = new Forest(cx.width, cx.height, cx, 0.03, 1);
cell = new Cell(0, 0);
las.populate(cell);
window.setInterval(refresh, 520);
function refresh() {
las.updateForest();
}
}
function forestWithFires() {
las = new Forest(cx.width, cx.height, cx, 0.2, 1);
cell = new Cell(0, 0, 20);
las.populate(cell);
window.setInterval(refresh, 520);
function refresh() {
las.updateForest();
}
}
deadForest();
//forestWithNoFire();
//forestWithFires();
/*
Forest Fire --> 2d cellular automaton
A small exercise in dealing with JS objects.
Green square = tree;
red = burning tree;
black = empty space;
More on this particular programming challenge:
http://rosettacode.org/wiki/Forest_fire
More on cellular automata:
http://en.wikipedia.org/wiki/Cellular_automaton
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment