Game Of Life

In this example below you will see how to do a Game Of Life with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by sc0ttr0berts0n, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright sc0ttr0berts0n ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Game Of Life</title>
  
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  
<!-- Still WIP-->
<canvas></canvas>
  
  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/sc0ttr0berts0n/game-of-life-boamER */
html {
  background-color: #282228;
  height: 100%;
}

body {
  display: flex;
  height: 100%;
  flex-direction: column;
  justify-content: center;
}

canvas {
  align-self: center;
  border-radius: 0.5rem;
}


/*Downloaded from https://www.codeseek.co/sc0ttr0berts0n/game-of-life-boamER */
// User Vars
var settings = {
	grid: {
		columns: 5,
		rows: 5,
		padding: 4
	},
	cell: {
		size: 40,
		spawnAliveOdds: 0.20,
		isAliveColor: 'white',
		isDeadColor: 'rgba(255, 255, 255, 0.25)'
	}
};

var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

// Define Canvas Size
canvas.width = (settings.cell.size + settings.grid.padding) * settings.grid.columns - settings.grid.padding;
canvas.height = (settings.cell.size + settings.grid.padding) * settings.grid.rows - settings.grid.padding;

var cells = [];

function Cell(x, y, id) {
	var _this = this;

	this.id = id;
	this.x = x;
	this.y = y;
	this.isAlive = Math.random() > 1 - settings.cell.spawnAliveOdds ? true : false;
	this.neighbors;

	this.update = function () {
		_this.generation();
		_this.draw();
	};

	this.generation = function () {
		var isOnTop = _this.id < settings.grid.columns ? true : false;
		var isOnBottom = _this.id >= (settings.grid.columns - 1) * settings.grid.rows ? true : false;
		var isOnLeft = _this.id % settings.grid.columns === 0 ? true : false;
		var isOnRight = (_this.id + 1) % settings.grid.columns === 0 ? true : false;
		var neighbors = 0;

		// top left
		// if (!isOnTop && !isOnLeft && cells[this.findNeighborXY('up','left')].isAlive) neighbors++;
		// top middle
		// if (!isOnTop && cells[this.findNeighborXY('up')].isAlive) neighbors++;
		// top right
		// if (!isOnTop && !isOnRight && cells[this.findNeighborXY('up','right')].isAlive) neighbors++;
		// left
		// if (!isOnLeft && cells[this.findNeighborXY('left')].isAlive) neighbors++;
		// right
		// if (!isOnRight && cells[this.findNeighborXY('right')].isAlive) neighbors++;
		// bottom left?
		// if (!isOnBottom && !isOnLeft && cells[this.findNeighborXY('bottom','left')].isAlive) neighbors++;
		// bottom middle?
		if (!isOnBottom && cells[_this.findNeighborXY('bottom')].isAlive) neighbors++;
		// bottom right
		// if (!isOnBottom && !isOnRight && cells[this.findNeighborXY('bottom','right')].isAlive) neighbors++;

		_this.neighbors = neighbors;
	};

	this.findNeighborXY = function (a, b) {
		// Pass in the current id and 'up' 'down' 'left' 'right' as strings
		a = a === undefined ? null : a;
		b = b === undefined ? null : b;
		var offset = _this.id;

		if (a === 'up' || b === 'up') offset += -settings.grid.columns;
		if (a === 'down' || b === 'down') offset += settings.grid.columns;
		if (a === 'left' || b === 'left') offset--;
		if (a === 'right' || b === 'right') offset++;

		return offset;
	};

	this.draw = function () {
		ctx.fillStyle = _this.isAlive ? settings.cell.isAliveColor : settings.cell.isDeadColor;
		ctx.fillRect(_this.x, _this.y, settings.cell.size, settings.cell.size);
		ctx.fillStyle = '#282228';
		ctx.font = '16px sans-serif';
		ctx.fillText(_this.id.toString(), _this.x + 5, _this.y + 16);
	};
}

function init() {
	var cellCounter = 0;

	// Build first pass for the cells
	for (var x = 0; x < settings.grid.columns; x++) {
		for (var y = 0; y < settings.grid.rows; y++) {
			var cellX = y * (settings.cell.size + settings.grid.padding);
			var cellY = x * (settings.cell.size + settings.grid.padding);
			var cellID = cellCounter++;
			cells.push(new Cell(cellX, cellY, cellID));
		}
	}

	// Get data for first generation
	var consoleGrid = [];
	for (var i = 0; i < cells.length; i++) {
		cells[i].generation();
		cells[i].draw();
		consoleGrid.push(cells[i].neighbors);
	}

	// Log Neighbors to console
	var consoleLine = '\n';
	for (var _i = 0; _i < consoleGrid.length; _i++) {
		consoleLine += consoleGrid[_i];
		if ((_i + 1) % settings.grid.columns === 0) consoleLine += '\n';
	}
	console.log(consoleLine);
}

var fps = 1;
var now;
var then = Date.now();
var interval = 1000 / fps;
var delta;

function animate() {

	window.requestAnimationFrame(animate);

	now = Date.now();
	delta = now - then;

	if (delta > interval) {
		then = now - delta % interval;

		ctx.fillStyle = '#282228';
		ctx.fillRect(0, 0, canvas.width, canvas.height);

		for (var i = 0; i < cells.length; i++) {
			cells[i].update();
		}
	}
}

init();
animate();
// lol

Comments