Search code examples
javascriptconways-game-of-lifecellular-automata

Stuck programming Conway's "Game of Life" in JS


We have to program a JavaScript version of Conway's Game of Life for a school project, but we're stuck on looping the edges. The whole thing works fine, but the function that calculates the number of neighbors doesn't work on the cells that are on the edges (because it has to evaluate values outside of the array, which are undefined). We've tried several options, but they all alter the functionality of the rest of the program.

What should we add for it to work on the edges of the grid?

    var totalNeighbors = function(x, y) {
    var total = 0;

    if (x > 0 && cells[(x - 1)][y] == 1) {
        total++;
    }

    if (x < (width - 1) && cells[x + 1][y] == 1) {
        total++;
    }

    if (y > 0 && cells[x][y - 1] == 1) {
        total++;
    }

    if (y < (height - 1) && cells[x][y + 1] == 1) {
        total++;
    }

    if (y > 0 && x > 0 && cells[x - 1][y - 1] == 1) {
        total++;
    }

    if (y > 0 && x < (width - 1) && cells[x + 1][y - 1] == 1) {
        total++;
    }

    if (y < (height - 1) && x > 0 && cells[x - 1][y + 1] == 1) {
        total++;
    }

    if (y < (height - 1) && x < (width - 1) && cells[x + 1][y + 1] == 1) {
        total++;
    }

    return total;
};

Thanks!


Solution

  • I'd go with something more like this:
    As you can see, I refactored a little bit.

    var isvalid = function(x, y) {
            /*
             * This returns 1 if cells[x][y] == 1.
             * Otherwise, we return 0.
             * NOTE: If cells[x, y] is out of bounds, we return 0.
             * GLOBALS USED: cells, width, and height.
             */
    
            //This returns true if (index < size && index >= 0)
            //Used to check that index is not an invalid index.
            var inbounds = function (size, index) {
                    return (index >= 0 && index < size);
            };
    
            //given point is out of bounds
            if (!inbounds(width, x) || !inbounds(height, y)) {
                    return 0;
            }
    
            //everything is good
            return (cells[x][y] === 1) ? 1 : 0;
        };
    
    var totalNeighbors = function(x, y) {
        var total = 0;
    
        //cells[x-1][y]
        total += isvalid(x-1, y);
    
        //cells[x + 1][y]
        total += isvalid(x+1, y);
    
        //cells[x][y - 1]
        total += isvalid(x, y-1);
    
        //cells[x][y + 1]
        total += isvalid(x, y+1);
    
        //cells[x - 1][y - 1]
        total += isvalid(x-1, y-1);
    
        //cells[x + 1][y - 1]
        total += isvalid(x+1, y-1);
    
        //cells[x - 1][y + 1]
        total += isvalid(x-1, y+1);
    
        //cells[x + 1][y + 1]
        total += isvalid(x+1, y+1);
    
        return total;
    };
    

    PS: Your original code sample is 37 lines without comments. My code sample is 52 lines with comments and 33 lines without comments.

    As near as I can figure, this way is cleaner and shorter. ;)