// 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 = \"", /**/"&lt;script src='quine.html'&gt;&lt;/script&gt;"/**/); // Add github link to the page quine("github = \"", /**/"&lt;b&gt;&lt;a href='http://github.com/snowl'&gt;"/**/); quine2("\"; //", /**/"&lt;/a&gt;&lt/b&gt;"/**/); // 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); } }