// Conway's Game of Life and Javascript + HTML Quine
// Page source is the same as shown code.
window.onload = function()
{
const theJs = "";
const github = "Github"; // My github :)
// Add the script tag to the webpage
quine("theJs = \"", /*
*/"<script src='quine.html'></script>"/**/);
// Add github link to the page
quine("github = \"", /**/"<b><a href='http://github.com/snowl'>"/**/);
quine2("\"; //", /**/"</a></b>"/**/);
// Add XMP tags each place an XMP tag exists
// This works because the XMP tag within an XMP tag won't be interpreted.
const xmp = document.getElementsByTagName('xmp');
for (let i = 0; i < xmp.length; i++)
{
xmp[i].style.display = "inline";
xmp[i].innerHTML = "<" + "xmp>" + xmp[i].innerHTML;
xmp[i].innerHTML += "<" + "/xmp>";
}
// Format nicely (quine completed)
// Make the website mono-spaced and show line-breaks
document.body.innerHTML = "<" + "pre style='margin: 8px;'>" + document.body.innerHTML + "<" + "/pre>";
// Set a margin of 0 so we can have a full-screen canvas
document.body.style.margin = 0;
// Below this we can start making Conway's Game of Life
// Lets create a canvas below our text to have some fun
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.style.position = "fixed";
canvas.style.left = "0px";
canvas.style.top = "0px";
canvas.style.zIndex = "-1";
// Add the canvas to the body of the page
document.body.appendChild(canvas);
// Set up a Conway's Game of Life
let lifeSize = 10, lifeRows, lifeColumns, lifeGame;
setup();
// Render conway's game every 30ms
setInterval(() =>
{
// Set up the style of drawn rectangles
ctx.fillStyle = "#EFEFEF";
// Clear the screen
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw the current state of the board
for (let x = 0; x < lifeRows; x++)
{
for (let y = 0; y < lifeColumns; y++)
{
if (lifeGame[x][y] == 1)
{
ctx.fillRect(x * lifeSize, y * lifeSize, lifeSize, lifeSize);
}
}
}
// Create a new temporary state
let tempGame = [];
for (let x = 0; x < lifeRows; x++)
{
tempGame[x] = [];
for (let y = 0; y < lifeColumns; y++)
{
// Get the neighbours of the current state
let neighbours = getNeighbours(x, y);
// Check how many neighbours the current cell has
let aliveNeighbours = 0;
for (let m = 0; m < 8; m++)
{
if (neighbours[m] !== undefined && neighbours[m] == 1)
{
aliveNeighbours += 1;
}
}
// If the current cell is dead, toggle on if 3 alive neighbours, otherwise toggle off
if (lifeGame[x][y] == 0)
{
if (aliveNeighbours == 3)
{
tempGame[x][y] = 1;
}
else
{
tempGame[x][y] = 0;
}
}
else
{
// Keep cell alive if it has 2 or 3 neigbours, otherwise set it off
if (aliveNeighbours == 2 || aliveNeighbours == 3)
{
tempGame[x][y] = 1;
}
else
{
tempGame[x][y] = 0;
}
}
}
}
// Apply the changes to the board
lifeGame = tempGame;
}, 30);
// Resize the canvas when the window is resized
window.onresize = setup;
// Press the N key to create a new game
window.onkeyup = (e) => e.keyCode == 78 && (lifeGame = genGame());
function setup()
{
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
lifeRows = Math.round(canvas.width / lifeSize);
lifeColumns = Math.round(canvas.height / lifeSize);
// Recreate a new Conway's Game
lifeGame = genGame();
}
// Set up conway's game of life
function genGame()
{
// Create a new array and populate it with random data
let lifeGame = [];
for (let x = 0; x < lifeRows; x++)
{
lifeGame[x] = new Array();
for (let y = 0; y < lifeColumns; y++)
{
lifeGame[x][y] = Math.round(Math.random());
}
}
return lifeGame;
}
// Get the individual neighbours of the current cell
function getNeighbours(x, y)
{
var neighbours = new Array();
// Only get the cells on left if possible
if (lifeGame[x - 1] != undefined)
{
neighbours.push(lifeGame[x - 1][y - 1]);
neighbours.push(lifeGame[x - 1][y]);
neighbours.push(lifeGame[x - 1][y + 1]);
}
neighbours.push(lifeGame[x][y - 1]);
neighbours.push(lifeGame[x][y + 1]);
// Only get the cells on right if possible
if (lifeGame[x + 1] != undefined)
{
neighbours.push(lifeGame[x + 1][y - 1]);
neighbours.push(lifeGame[x + 1][y]);
neighbours.push(lifeGame[x + 1][y + 1]);
}
return neighbours;
}
// Wow :)
function quine(tag, text)
{
document.body.innerHTML = document.body.innerHTML.replace(tag, tag + text);
}
// Wow :)
function quine2(tag, text)
{
document.body.innerHTML = document.body.innerHTML.replace(tag, text + tag);
}
}