Search code examples
javascripthtmllogicgame-physicsconways-game-of-life

issue with my game of life logic?


I have coded Conway's game of Life in JavaScript, it seems to be producing something to the screen, but it doens't seem to be following the same logic or running in the same way at all to Conways Game of Life. I don't know what is wrong and why it is running like this, my code seems to me like it should be following the correct rules. Can anyone spot why it is not running correctly? here is a link to JSFiddle https://jsfiddle.net/nw4Lw7z9/1/

 //object constructor
function cell(){
    this.alive = Math.random() >0.8;    
    this.neighbours = 0;  //number of live neighbours
    this.checkneighbours = [[-1,-1],[-1,0],[0,-1],[-1,1],[1,-1],[1,0],[0,1],[1,1]];
}


function GoL(size){
    this.size = size;
    this.grid = this.makeGrid(size);
};      

    GoL.prototype.makeGrid = function(size){
        var grid = [];
        for(var i=0; i<size; i++){
            var row=[];
            for(var j =0; j<size; j++){
                row.push(new cell());   
            }
            grid.push(row);
        }
            return grid;
    };  

    GoL.prototype.drawGrid = function(){
        grid.innerHTML = '';
        for(var i=0;i<this.size;i++){
            var row =this.grid[i];
            var rowCell="";
            for(var j=0;j<this.size;j++){
                var cell = row[j];
                if(cell.alive){
                    rowCell += "X|";
                }else{
                    rowCell += " |";
                }               
            }
            grid.innerHTML = grid.innerHTML + rowCell + "\n";
        }       
    };  

GoL.prototype.underpopulation = function(ro,col){
    var cell = this.grid[ro][col];
    if(cell.neighbours <2){
        return true;
    }else{
        return false;   
    }
};  
GoL.prototype.overpopulation = function(ro,col){
    var cell = this.grid[ro][col];
    if(cell.neighbours >3){
        return true;
    }else{
        return false;   
    }
};  

GoL.prototype.backtolife = function(ro,col){
    var cell = this.grid[ro][col];
    if(cell.neighbours ==3 && !cell.alive){
    return true;
    }else{
        return false;   
    }   
};


GoL.prototype.update = function(ro,col){    
    var cell = this.grid[ro][col];
   // cell.num_of_neighbours = 0;
    for(var i =0; i<cell.checkneighbours.length; i++){
        var checkneighbour = cell.checkneighbours[i];
        var neighbour1 = checkneighbour[0];
        var neighbour2 = checkneighbour[1];
        if(neighbour1>=0 && neighbour1 < this.size && neighbour2 >=0 && neighbour2 < this.size){
        var currentneighbour = this.grid[ro + neighbour1][col+neighbour2];
        if(currentneighbour.alive){
            cell.neighbours++;
        }
       }
    }
};

GoL.prototype.updateAll = function(){
    for(var i=0; i<this.size-1;i++){
        for(var j=0; j<this.size-1;j++){
            this.update(i,j);
        }
    }   
}

GoL.prototype.cellstatus = function(ro,col){
    var cell = this.grid[ro][col];
    if(this.underpopulation(ro,col) || this.overpopulation(ro,col)){
        cell.alive = false;
    }else if(this.backtolife(ro,col)){
        cell.alive = true;
    }
};

GoL.prototype.allcellstatus = function(ro,col){
    for(var i=0; i<this.size;i++){
        for(var j=0; j<this.size;j++){
            this.cellstatus(i,j);
        }
    }   
};


var gameoflife = new GoL(100);   

var interval = setInterval(function(){
    gameoflife.drawGrid();
    gameoflife.updateAll();
    gameoflife.allcellstatus();
},500);    

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Game of Life</title>
    <script src="cell.js" type="text/javascript"> </script>
  </head>
  <body>
    <pre id="grid">
    </pre>
  </body>
</html>

Solution

  • Your update function is hard to follow. I've cleaned it up. Give this a try:

    GoL.prototype.update = function(ro,col){    
        var cell = this.grid[ro][col];
        // Uncomment this. Need to re-set every iteration (and fix typo)
        cell.neighbours = 0;
        for(var i = 0; i < cell.checkneighbours.length; i++){
            // Get new indices
            var newRow = ro + cell.checkneighbours[i][0];
            var newCol = col + cell.checkneighbours[i][1];
    
            // Check that indices are in range
            if (newRow >= 0 && newRow < this.grid.length && newCol >= 0 && newCol < this.grid[newRow].length) {
                if(this.grid[newRow][newCol].alive){
                    cell.neighbours++;
                }
            }
        }
    };