Ways to improve the cleanliness of the code

I've created a simple life simulation game and I'm looking for ways to optimize the code.

Any suggestions on how to make the code cleaner?

jsfiddle: https://jsfiddle.net/04vazdrb/

 /*
     JavaScript Implementation of Conway's Game Of Life
    */

window.onload = function() {

    var gridHeight = 400;
    var gridWidth = 400;
    var theGrid = createCellArray(gridWidth);
    var mirrorGrid = createCellArray(gridWidth);
    var genCounter = 0;

    seed();
    tick();
    //main loop
    function tick() {
      drawGrid();
      updateGrid();
      counter();
      requestAnimationFrame(tick);
    }
    /* Returns an array with n elements and initializes an empty 
       nested array in each element using a FOR loop.
    */
    function createCellArray(rows) {
      var arr = [];
      for (var i = 0; i < rows; i++) {
        arr[i] = [];
      }
      return arr;
    }

    // Populating and initializing the grid randomly.
    function seed() {
      // Iterate through rows
      for (var j = 0; j < gridHeight; j++) {
        // Iterate through columns
        for (var k = 0; k < gridWidth; k++) {
          // Generate a random binary number between 0 and 1
          var randomBinary = Math.floor(Math.random() * 2);
          // Set the state of the cell
          theGrid[j][k] = randomBinary;
        }
      }
    }

    // Draw each cell in the grid as a pixel on a Canvas
    function drawGrid() {
      var c = document.getElementById("gridCanvas");
      var ctx = c.getContext("2d"); // Get the canvas context
      ctx.clearRect(0,  0, 400, 400); // Clear the canvas before each redraw

      // Iterate through rows
      for (var j = 1; j < gridHeight; j++) {
        // Iterate through columns
        for (var k = 1; k < gridWidth; k++) {
          if (theGrid[j][k] === 1) { // Alive cell
            ctx.fillStyle = "#71bc4a"; // Green color
            ctx.fillRect(j, k, 1, 1); // Fill a cell
          }
        }
      }

    }

    // Update the grid based on the game rules
    function updateGrid() {
      // Iterate through rows
      for (var j = 1; j < gridHeight - 1; j++) {
        // Iterate through columns
        for (var k = 1; k < gridWidth - 1; k++) {
          var totalCells = 0;
          // Add up the total values for the surrounding cells
          totalCells += theGrid[j - 1][k - 1]; // Top left
          totalCells += theGrid[j - 1][k]; // Top center
          totalCells += theGrid[j - 1][k + 1]; // Top right
          totalCells += theGrid[j][k - 1]; // Middle left
          totalCells += theGrid[j][k + 1]; // Middle right
          totalCells += theGrid[j + 1][k - 1]; // Bottom left
          totalCells += theGrid[j + 1][k]; // Bottom center
          totalCells += theGrid[j + 1][k + 1]; // Bottom right

          // Apply the rules to each cell
          if (theGrid[j][k] === 0) {
            switch (totalCells) {
              case 3:
                // If cell is dead and has 3 neighbors, switch it on
                mirrorGrid[j][k] = 1;
                break;
              default:
                mirrorGrid[j][k] = 0; // Otherwise leave it dead

            }
            // Apply rules to living cell
          } else if (theGrid[j][k] === 1) {
            switch (totalCells) {
              case 0:
              case 1:
                mirrorGrid[j][k] = 0; // Die of loneliness
                break;
              case 2:
              case 3:
                mirrorGrid[j][k] = 1; // Carry on living
                break;
              case 4:
              case 5:
              case 6:
              case 7:
              case 8:
                mirrorGrid[j][k] = 0; // Die of overcrowding
                break;
              default:
                mirrorGrid[j][k] = 0; //   
            }
          }
        }
      }
      // Iterate through rows
      for (var j = 0; j < gridHeight; j++) {
        // Iterate through columns
        for (var k = 0; k < gridWidth; k++) {
          // Copy mirrorGrid to theGrid
          theGrid[j][k] = mirrorGrid[j][k];
        }
      }
    }
    // Generation counter
    function counter() {
      genCounter++;
      document.getElementById("generationCount").innerHTML = "Generation: " + genCounter;
    }

  } 

Answer №1

To simplify the logic, consider replacing the switch statement with a straightforward if statement.

if ((totalCells == 2) || (totalCells == 3)) {
    mirrorGrid[j][k] = 1;     //Cell survives
}else {
    mirrorGrid[j][k] = 0;     //Cell perishes
}

It may also be beneficial to use "x" and "y" instead of "j" and "k" for clarity since these are coordinates.

Answer №2

To simplify the process of looping through each cell, you can create a function dedicated to this task. Here's an example:

function loopThroughCells(action) {
    // Iterate through rows
    for (var y = 0; y < gridHeight; y++) {
        // Iterate through columns
        for (var x = 0; x < gridWidth; x++) {
            action(x, y);
        }
    }
}

Check out this demonstration: https://jsfiddle.net/uzrabeq0/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

It is not possible to upload files larger than 4mb in ASP.NET MVC3

I am facing an issue with uploading files in ASP.NET MVC3 where I am unable to upload files larger than 4mb. I am currently using jquery.form.js for the file upload process and utilizing ajax to post the form to the server side. It works perfectly fine whe ...

What could be the reason behind my Heroku app suddenly crashing without any visible errors?

After successfully starting the Nest application, about 50 seconds later it transitions from 'starting' to 'crashed'. The last log entry before the crash is a console log indicating the port number. View Heroku logs after successful bui ...

Attempting to adjust the width of a text animation loaded with jQuery using Textillate, but encountering difficulties

I found a captivating animation on this website: http://codepen.io/jschr/pen/GaJCi Currently, I am integrating it into my project. #content { position: relative; margin-left: auto; margin-right: auto; width: 1000px; height: 700px; } ...

What are the different ways to interact with the object retrieved from the onloadedmetadata event

Having trouble accessing a specific value in an object that is the result of the onloadedmetadata event. When I log the entire object using audioDuration, I am able to see and retrieve the respective value without any issues. However, when I try to access ...

Determine the available time slots for reserving a resource

I am developing an application that displays the weekly availability (Monday-Sunday) of a bookable resource. Next to this calendar view, users can select: A) Length of desired booking slot (15 min/30 min/60 min) B) Time zone The time slots are based ...

JavaScript: incorporating PHP into JavaScript

What is the proper way to incorporate PHP inside Javascript? var timeDiff = 60-20; if ( timeDiff <= 60 ) { var stamp = timeDiff <?php echo $this->__('second ago') . '.'; ?>; } A console error has been detected: Unca ...

The system is unable to interpret the symbol property 'Symbol(Symbol.iterator)' because it is not defined

I have created a custom .any() method for Array objects to loop through an array and check if any item passes a specified function: Array.prototype.any = (comparator) => { for(let item of this){ if(comparator(item)){ return true ...

Interdependent function calls between two functions

When faced with the task of recursively checking two objects with sorted keys, I came up with a solution involving two functions. buildObj - this function retrieves all unique keys from the objects, sorts them, and then calls buildObjKey for each key bui ...

The useEffect function is failing to execute when deploying on Vercel with Vite and React Router

After successfully deploying a React site using Vite on Vercel, with React Router for routing and a separate backend service, everything seemed to be working fine on my local machine. However, when testing the deployment on Vercel, I encountered an issue w ...

How can I update a CSS class value by utilizing AngularJS variables?

I am currently facing an issue with making my CSS values dynamic. The code I have tried is not functioning as expected. <style> .panel-primary { background-color:{{myColorPanel}} } </style> I came across a similar query on Ho ...

Updating JSON in JavaScript

I am striving to structure a JSON object in the following manner: {"tokenId":1,"uri":"ipfs://bafy...","minPrice":{"type":"BigNumber","hex":"0x1a"},"signature":"0 ...

Use $parse to extract the field names that include the dot character

Suppose I have an object with a field that contains a dot character, and I want to parse it using $parse. For instance, the following code currently logs undefined - var getter = $parse('IhaveDot.here'); var context = {"IhaveDot.here": 'Th ...

Is there a way to streamline this query code that seems overly complex?

Could someone please assist me in simplifying this code? I am trying to shorten or simplify the query code by using a stored procedure, but I still need to include the details inside the "()" parentheses. I am new to Node.js and would appreciate any help. ...

Error: AngularJS form validation is not working properly

I've been following the AngularJS documentation, but I'm having trouble with my validations. The error messages are not showing up and the minimum length restrictions for the form fields are not working: <form name="callbackForm" ng-submit="r ...

Can you provide me with information on how to retrieve data from a Yahoo Finance JSON file using Node.js?

I have created a simple request function to fetch JSON data from the Yahoo Finance API, but I am encountering difficulties in extracting information from the JSON response. Here is my code: var request = require("request"); var stock_url = "http://finan ...

Managing the re-triggering of a function within useEffect upon the user clicking the "Back Button" in a React application

Is there a way to prevent the loadUserPosts() function from being called again when the user clicks the 'back button' on their browser? It seems like the isLogged useState is being changed when the back button is clicked. The loadUserPosts funct ...

Update the image source every 1 second with Jquery and Javascript

I've been experimenting with creating a script that dynamically changes the source of an image every two seconds based on a list. Essentially, my current approach involves using a for loop to iterate over the provided list: $(document).ready(functio ...

Utilizing cylon.js with Nest Thermostat

Experiencing errors while trying to retrieve thermostat ambient Temperature with cylon.js I have already replaced ACCESS_TOKEN with my unique access token and device id Sample Code: var Cylon = require('cylon'); Cylon.robot({ connections: { ...

Clicking an ASP.NET Button without any code will cause the page to reload in a new window

I am working on a straightforward ASP.NET project consisting of only two pages. The first page, named FirstPage.htm, contains the following HTML markup: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xh ...

a single function spread across two controllers[JavaScript]

My query pertains to a JavaScript program with 2 controllers. The issue I am facing is the need for one function in both controllers (data.duration). This function serves two purposes, once for features themselves and once for the summary. Currently, this ...