3

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!

Dat8StringGuy
  • 301
  • 1
  • 2
  • 10
  • Check if you're doing a block on the edge. If so, don't try to access the ones you can't. I think all those `if`s can be refactored. Doing that will make applying point one easier. (If you have to loop edge accesses around to the zero-th one, remember that modulus, `%`, is your friend.) – J. Allan Oct 27 '16 at 00:02
  • What do you mean by a "block on the edge"? Any suggestion on how to refactor the `if`s? We tried it and it turned out to be even longer haha. – Dat8StringGuy Oct 27 '16 at 00:07
  • What I mean by "block on the edge" is a cell that has no cells on one or more sides (ie. it has no cells above it and/or beside it and/or below it.) After a quick run to the grocery store, I can come back and try my hand at refactoring it. (It might end up in a longer solution *line* wise, but it should be a *cleaner* solution.) – J. Allan Oct 27 '16 at 00:11
  • Posted my idea. Feel free to comment, ask questions, etc. – J. Allan Oct 27 '16 at 01:18

1 Answers1

3

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. ;)

J. Allan
  • 1,418
  • 1
  • 12
  • 23