Good day to all. Please rate the quality of the implementation and the general style of the code (except that everything is merged into one file) of Conway’s life game. I am writing not so long ago, so the opinion of knowledgeable people is important. Thank you in advance.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <style> body{ margin: 0; overflow: hidden; cursor: default; } input[type="button"]{ position: absolute; top: 10px; } #start{ right: 100px; } #stop{ right: 50px; } #unitsValue{ position: absolute; top: 40px; right: 50px; text-align: right; } #generation{ position: absolute; top: 70px; right: 50px; text-align: right; } </style> </head> <body> <canvas id="canvas" width="640" height="480"></canvas> <input type="button" id="start" value="Старт"> <input type="button" id="stop" value="Стоп" disabled> <input type="text" id="unitsValue"> <input type="text" id="generation"> <script type="text/javascript"> var canvas = document.getElementById('canvas'); canvas.width = document.documentElement.clientWidth; canvas.height = document.documentElement.clientHeight; ctx = canvas.getContext('2d'); canvas = document.getElementById('canvas'); ctx.strokeStyle = "#c7edfc"; var width = canvas.width; var height = canvas.height; var step = 10; //unit size var unitsValue = document.getElementById('unitsValue'); var generationPanel = document.getElementById('generation'); function drawBackGround() { for (var i = step; i < width; i += step * 2) { ctx.strokeRect(i, 0, step, height); ctx.strokeRect(0, i, width, step); }; }; var notEmpty = 1; var generation = 1; var grid = []; function generateGrid(width, height) { //generating first generation grid ctx.fillStyle = "#8dcbe4"; notEmpty = 0; for (i = 0; i < (height / step); i++){ grid[i] = []; for (j = 0; j < (width / step); j++){ grid[i][j] = Math.round(Math.random()); if (grid[i][j] == 1) { notEmpty++ }; }; }; unitsValue.value = notEmpty + " : units"; generationPanel.value = generation + " : generation"; }; function drawUnits(grid) { ctx.strokeStyle = "#c7edfc"; for (i = 0; i < grid.length; i++) { for (j = 0; j < grid[i].length; j++) { if (grid[i][j] == 1) { ctx.fillRect(((j + 1) * step) - step, ((i + 1) * step) - step, step, step); }; }; }; }; function refresh() { ctx.clearRect(0, 0, width, height); drawBackGround(); drawUnits(grid); }; canvas.onmousedown = function(c) { // manualy drawing ctx.strokeStyle = "#c7edfc"; if (stopButton.disabled == true) { var m = Math.floor(c.pageX / step); var n = Math.floor(c.pageY / step); console.log(m, n, grid[n][m]); var chooseDestiny = grid[n][m]; if (grid[n][m] == 1) { grid[n][m] = 0; ctx.clearRect(m * step, n * step, step, step); ctx.strokeRect(m * step, n * step, step, step); } else { grid[n][m] = 1; ctx.fillRect(m * step, n * step, step, step); }; console.log(m, n, grid[n][m]); this.onmousemove = function(e) { // swipe var x = Math.floor(e.pageX / step); var y = Math.floor(e.pageY / step); if (x != m || y != n) { m = x; n = y; if (chooseDestiny == 1) { grid[y][x] = 0; ctx.clearRect(m * step, n *step, step, step); ctx.strokeRect(m * step, n *step, step, step); } else { grid[y][x] = 1; ctx.fillRect(m * step, n *step, step, step); }; }; }; this.onmouseup = function(){ this.onmousemove = function(){}; } }; }; var newGrid = []; var oldGrid = []; function getNewGrid(grid) { notEmpty = 0; for (var i = 0; i < grid.length; i++){ newGrid[i] = []; for (var j = 0; j < grid[i].length; j++){ var neig = 0; var tempGrid = []; if (grid[i][j] == 1) { notEmpty++ }; if (i == 0) { // moore neighborhood for (var x = 0; x <= 1; x++) { tempGrid[x] = []; for (var y = -1; y <= 1; y++) { tempGrid[x][y+1] = grid[x][j+y]; }; }; } else if (i == grid.length-1) { for (var x = -1; x <= 0; x++) { tempGrid[x+1] = []; for (var y = -1; y <= 1; y++) { tempGrid[x+1][y+1] = grid[i+x][j+y]; }; }; } else { for (var x = -1; x <= 1; x++) { tempGrid[x+1] = []; for (var y = -1; y <= 1; y++) { tempGrid[x+1][y+1] = grid[i+x][j+y]; }; }; }; for (var n = 0; n < tempGrid.length; n++) { // neighbors value for (var m = 0; m < tempGrid[n].length; m++){ if (tempGrid[n][m] == 1) { neig++ }; }; }; if (grid[i][j] == 1) { neig -= 1 }; if (grid[i][j] == 1 && (neig == 3 || neig == 2)) { // create new unnits newGrid[i][j] = 1; } else if (grid[i][j] == 0 && neig == 3) { newGrid[i][j] = 1; } else { newGrid[i][j] = 0; }; }; }; unitsValue.value = notEmpty + " : units"; generation++; generationPanel.value = generation + " : generation"; }; startButton = document.getElementById('start'); stopButton = document.getElementById('stop'); var cycleTimer; startButton.onclick = function () { refresh(); cycleTimer = setTimeout(function cycle() { getNewGrid(grid); if (String(grid) == newGrid || String(newGrid) == oldGrid) { notEmpty = 0 }; oldGrid = grid; grid = newGrid; newGrid = []; refresh(); cycleTimer = setTimeout(cycle, 50); }, 50); setInterval(function () { if (notEmpty == 0) { ctx.strokeStyle = "#000000"; ctx.font = "50px Arial" ctx.strokeText("LIFE IS OVER", width / 2, height / 2); clearInterval(cycleTimer); startButton.disabled = false; stopButton.disabled = true; }; }, 100); startButton.disabled = true; stopButton.disabled = false; }; stopButton.onclick = function () { clearInterval(cycleTimer); startButton.disabled = false; stopButton.disabled = true; }; generateGrid(width, height); refresh(); </script> </body> </html>
DOM Events 1are outdated for a long time). - user207618 pmfor (var x = 0; x <= 1; x++) { tempGrid[x] = []; ...cyclesfor (var x = 0; x <= 1; x++) { tempGrid[x] = []; ...for (var x = 0; x <= 1; x++) { tempGrid[x] = []; ...The names of the variablesnandmnot informative, andxandyshould be used only for coordinates. I will not argue about indents and line breaks. - Regent