MMM-GameOfLife.js
"use strict"; Module.register("MMM-GameOfLife", { // Default module config. defaults: { name: "MMM-GameOfLife", desiredFrameRate: 1, resolution: 10, canvasWidth: 300, canvasHeight: 300, notAliveColorCode: "#000", aliveColorCode: "#aaa" }, start: function() { Log.info("Starting module: " + this.name); this.sanitizeConfig(); }, getDom: function() { let wrapper = document.createElement("div"); wrapper.id = "gameOfLifeWrapper"; return wrapper; }, getScripts: function() { return [ "https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js" ]; }, notificationReceived: function(notification, payload, sender) { if (notification === "DOM_OBJECTS_CREATED") { Log.info("DOM objects are created. Starting P5 …"); let sketch = this.makeSketch(this.config); new p5(sketch, "gameOfLifeWrapper"); } }, sanitizeConfig: function() { if (this.config.desiredFrameRate < 1) { this.config.desiredFrameRate = 1; } if (this.config.resolution < 2) { this.config.resolution = 2; } if (this.config.canvasWidth < 50) { this.config.canvasWidth = 50; } if (this.config.canvasHeight < 50) { this.config.canvasHeight = 50; } }, Function `makeSketch` has a Cognitive Complexity of 63 (exceeds 5 allowed). Consider refactoring.
Function `makeSketch` has 112 lines of code (exceeds 25 allowed). Consider refactoring. makeSketch: function(conf) { return function(pFive) { let currentGenGrid; let lastGenGrid; /* user definable parameters */ let desiredFrameRate = conf.desiredFrameRate; let resolution = conf.resolution; let canvasWidth = conf.canvasWidth; let canvasHeight = conf.canvasHeight; let notAliveColorCode = conf.notAliveColorCode; let aliveColorCode = conf.aliveColorCode; let notAliveColor = getNotAliveColor(notAliveColorCode); /* computed parameters */ let rows = canvasWidth / resolution; let cols = canvasHeight / resolution; pFive.setup = function() { pFive.frameRate(desiredFrameRate); pFive.createCanvas(canvasWidth, canvasHeight); lastGenGrid = makeGrid(rows, cols); currentGenGrid = makeGrid(rows, cols); fillGridRandomly(currentGenGrid); }; pFive.draw = function() { pFive.clear(); pFive.background(notAliveColor); drawGrid(currentGenGrid); let nextGenGrid = computeNextGeneration(currentGenGrid); if (representingSameState(nextGenGrid, currentGenGrid) || representingSameState(nextGenGrid, lastGenGrid)) { fillGridRandomly(currentGenGrid); } else { lastGenGrid = currentGenGrid; currentGenGrid = nextGenGrid; } }; /* "Private functions" */ function getNotAliveColor() { if (notAliveColorCode === "transparent") { return pFive.color("rgba(0, 0, 0, 0)"); } else { return pFive.color(notAliveColorCode); } } function makeGrid(rows, cols) { let array = new Array(rows); for (let i = 0; i < rows; i++) { array[i] = new Array(cols); } return array; } function fillGridRandomly(grid) { for (let i = 0; i < grid.length; i++) { for (let j = 0; j < grid[i].length; j++) { grid[i][j] = pFive.floor(pFive.random(2)); } } } function drawGrid(grid) { for (let i = 0; i < grid.length; i++) { for (let j = 0; j < grid[i].length; j++) { drawCell(grid, i, j); } } } function drawCell(grid, i, j) { let aliveColor = pFive.color(aliveColorCode); if (grid[i][j] === 1) { pFive.fill(aliveColor); pFive.stroke(aliveColor); let x = i * resolution; let y = j * resolution; pFive.rect(x, y, resolution - 1, resolution - 1); } } function computeNextGeneration(currentGen) { let nextGen = makeGrid(rows, cols); for (let i = 0; i < rows; i++) { for (let j = 0; j < cols; j++) { computeNextGenCell(i, j, currentGen, nextGen); } } return nextGen; } function computeNextGenCell(i, j, currentGen, nextGen) { let currentState = currentGen[i][j]; let aliveNeighbors = countAliveNeighbors(currentGen, i, j); if (currentState === 0 && aliveNeighbors === 3) { nextGen[i][j] = 1; } else if (currentState === 1 && (aliveNeighbors < 2 || aliveNeighbors > 3)) { nextGen[i][j] = 0; } else { nextGen[i][j] = currentState; } } function countAliveNeighbors(grid, x, y) { let count = 0; for (let i = -1; i < 2; i++) { for (let j = -1; j < 2; j++) { let row = (x + i + rows) % rows; let col = (y + j + cols) % cols; count += grid[row][col]; } } count -= grid[x][y]; return count; } function representingSameState(leftGrid, rightGrid) { for (let i = 0; i < leftGrid.length; i++) { for (let j = 0; j < leftGrid.length; j++) { if (leftGrid[i][j] !== rightGrid[i][j]) { return false; } } } return true; } }; }});