-3

Hi everyone I am trying to simulate a simple Conway's game of life, these are the rules of the game:

Any live cell with fewer than two live neighbours dies, as if caused by under-population. Any live cell with two or three live neighbours lives on to the next generation. Any live cell with more than three live neighbours dies, as if by overcrowding. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

Now the problem is that I need to modify my actual grid in order to print it and then re-change it as its previously value before any rules is applied, however I cannot find any system to accomplish this task, I hope someone can help me. Here my code:

import java.util.Scanner;
import java.io.*;

class LifeGrid
{
private int[][] grid, newGrid;
private int generation = 0;

public LifeGrid(int x, int y, String filename) throws FileNotFoundException 
{ 
    grid = new int[x][y];
    newGrid = new int[x][y];

    int j = 0;

    Scanner scanner = new Scanner(new File(filename));

    while(scanner.hasNextLine() && j < x)
    {
        String line = scanner.nextLine();

        for(int i=0; i<line.length() && i<y; i++)
        {
            if(line.charAt(i) == '*')
                grid[j][i] = 1;
            else
                grid[j][i] = 0;
        }
        j++;
    }
    scanner.close();
}

public void show()
{

    for(int i=0; i<grid.length; i++)
    {
        for(int j=0; j<grid[i].length; j++)
        {
            if(grid[i][j] == 1)
                System.out.print("*");
            else
                System.out.print(" "); 
        }
        System.out.println();
    }
    System.out.println("Generation:" + generation);
}

//Getter methods

public int getWidth()             { return grid[0].length;  }
public int getHeight()            { return grid.length;     }
public int getGeneration()        { return this.generation; }
public int getCell(int x, int y)  { return grid[x][y];      }


public static void main(String[] args)throws FileNotFoundException 
{
    LifeGrid life = new LifeGrid(6, 10, args[0]);
    life.run(); 
    }

//Check neighbours

    public int neighbours(int x, int y)
    {
        int neighbours = 0;

        if(x == 0 && y == 0)
        {
        if(grid[x][y+1] == 1)       {neighbours++;} 
        if(grid[x+1][y] == 1)       {neighbours++;}
        if(grid[x+1][y+1] == 1)     {neighbours++;}
        }
        else if(x == 0 && y >= 1 && y < getWidth() -1)
        {
        if(grid[x][y+1] == 1)       {neighbours++;} 
        if(grid[x][y-1] == 1)       {neighbours++;}
        if(grid[x+1][y] == 1)       {neighbours++;}
        if(grid[x+1][y+1] == 1)     {neighbours++;} 
        if(grid[x+1][y-1] == 1)     {neighbours++;}
        }
        else if(x >= 1 && x < getHeight() -1 && y == 0)
        {
        if(grid[x][y+1] == 1)       {neighbours++;} 
        if(grid[x+1][y] == 1)       {neighbours++;}
        if(grid[x+1][y+1] == 1)     {neighbours++;} 
        if(grid[x-1][y+1] == 1)     {neighbours++;}
        }
        else if(x == getHeight()-1 && y >= 1 && y < getWidth() - 1)
        {
        if(grid[x][y+1] == 1)       {neighbours++;} 
        if(grid[x][y-1] == 1)       {neighbours++;}
        if(grid[x-1][y-1] == 1)     {neighbours++;}
        if(grid[x-1][y+1] == 1)     {neighbours++;}
        }
        else if(x >=1 && x < getHeight() - 1 && y == getWidth()-1 )
        {
        if(grid[x][y-1] == 1)       {neighbours++;}
        if(grid[x+1][y] == 1)       {neighbours++;}
        if(grid[x+1][y-1] == 1)     {neighbours++;}
        if(grid[x-1][y-1] == 1)     {neighbours++;}
        }
        else if(x == 0 && y == getWidth()-1 )
        {   
        if(grid[x][y-1] == 1)       {neighbours++;}
        if(grid[x+1][y] == 1)       {neighbours++;}
        if(grid[x+1][y-1] == 1)     {neighbours++;}
        }
        else if(x == getHeight()-1  && y == 0)
        {
        if(grid[x-1][y] == 1)       {neighbours++;}
        if(grid[x][y+1] == 1)       {neighbours++;}
        if(grid[x-1][y+1] == 1)     {neighbours++;}
        }   
        else if(x == getHeight()-1  && y == getWidth()-1)
        {
        if(grid[x][y-1] == 1)       {neighbours++;}
        if(grid[x-1][y] == 1)       {neighbours++;}
        if(grid[x-1][y-1] == 1)     {neighbours++;}
        }
        else
        {
                    if(grid[x][y+1] == 1)           {neighbours++;}
                    if(grid[x][y-1] == 1)           {neighbours++;}
                    if(grid[x+1][y] == 1)           {neighbours++;}
                    if(grid[x+1][y+1] == 1)         {neighbours++;}
                    if(grid[x+1][y-1] == 1)         {neighbours++;}
                    if(grid[x-1][y-1] == 1)         {neighbours++;}
                    if(grid[x-1][y+1] == 1)         {neighbours++;}
                }
        return neighbours;
    }
    public void run()
    {
        int n;
        int[][] old;

        for(int i=0; i<grid.length; i++)
        {
            for(int j=0; j<grid[i].length; j++)
            {
                n = neighbours(i,j);

                if(grid[i][j] == 1)
                {
                    if(n < 2 || n > 3)      {generation = 0;}
                    if(n == 2 || n == 3)    {generation = 1;}
                }
                else 
                {
                    if(n == 3)          {generation = 1;}
                    else            {generation = 0;}
                }

                if(generation == 1)
                {
                    old = grid;
                    newGrid[i][j] = 1;
                    grid = newGrid;
                    show();
                    grid = old;
                }
                else 
                {   
                    old = grid;
                    newGrid[i][j] = 0;
                    grid = newGrid;
                    show();
                    grid = old;
                                }

            }
        }
        }
}       

File:

* * *

Expected output:

*
*
*

The new run() method is:

public void run()
{
    int n;

    for(int i=0; i<grid.length; i++)
    {
        for(int j=0; j<grid[i].length; j++)
        {
            n = neighbours(i,j);

            if(grid[i][j] == 1)
            {
                if(n < 2 || n > 3)  {generation = 0;}
                if(n == 2 || n == 3)    {generation = 1;}
            }
            else 
            {
                if(n == 3)      {generation = 1;}
                else            {generation = 0;}
            }

            newGrid[i][j] = generation;
        }
    }
    grid = newGrid.clone();
    show();
}

Now instead of getting as output:

*
*
*

I get:

*
*

Can someone help me to figure out why?

user1078406
  • 9
  • 1
  • 3
  • is this some sort of homework? – xmoex Dec 06 '11 at 16:41
  • You need to be a little clearer. Given an example of expected output for one iteration vs the actual output. – AHungerArtist Dec 06 '11 at 16:41
  • Figure out how to print the grid. Just use keyboard input to generate the next life cycle. – Security Hound Dec 06 '11 at 16:44
  • you are updating `grid = newGrid`, but then later you are calling `grid = old`. I think the latter line should not be there. – Kane Dec 06 '11 at 16:52
  • Besides the advice already offered. For better help sooner, post an [SSCCE](http://sscce.org/). To make an SSCCE of that code would require factoring out the file read and instead assigning random values to the initial grid. – Andrew Thompson Dec 06 '11 at 17:10
  • As best I can guess from your description, the basic problem might be changing the state of a cell before the entire grid is analyzed, as in [this thread](http://stackoverflow.com/questions/8199460/issue-with-game-of-life). – Andrew Thompson Dec 06 '11 at 17:13

1 Answers1

1

Welcome!

Maybe I get you wrong but is your problem that the grid gets updated to early (read: the new game state is used for calculating remaining old cells?)

I think you run into troubles with old = grid because that will merely produce a shallow copy of your array. Very likely you looking for a deep copy which could be achieved using the clone method which Array has inherited.

Furthermore as I read the code I got the feeling you already update the grid while still calculating the new game state. Only assign the new game state to a working grid like "gridTemp" and when exiting the outer for loop you should do something like:

grid = gridTemp.clone()
gridTemp.clear() //purge, trash whatever, just make it empty

Keep in mind that's just pseudo code! I hope it's helpful anyway. :)

edit: Ok, I can't run your code here and therefore I'm not 100% sure if that's the solution to your problem but this code block seems to be wrong:

if(generation == 1)
                {
                    old = grid;
                    newGrid[i][j] = 1;
                    grid = newGrid;
                    show();
                    grid = old;
                }
                else 
                {   
                    old = grid;
                    newGrid[i][j] = 0;
                    grid = newGrid;
                    show();
                    grid = old;
                                }

instead I suggest a tiny restructure. Replace the code above with:

newGrid[i][j] = generation

and furthermore add the following just after your iteration.

grid = newGrid.clone();
show();

So instead of updating and displaying the grid all the time while calculating the new game give yourself a kiss, (Keep It Sweet and Simple!). First determine the new game state and save it in a temporary grid like newGrid. In the end you can copy the game state into the old grid and update the display. Probably it's not even necessary to call the clone() method there but let's be a little bit crazy :)

Community
  • 1
  • 1
nuala
  • 2,681
  • 4
  • 30
  • 50
  • I am not sure to have very well understand what you mean. I have changed the program like: if(generation == 1) { newGrid[i][j] = 1; gridTemp = newGrid; grid = gridTemp.clone(); show(); gridTemp.clear(); However I do not know how to initialise gridTemp.. – user1078406 Dec 06 '11 at 17:12
  • sorry don't mind the "gridTemp" probably it's just confusing. I updated my answer and tried to be more clear. – nuala Dec 06 '11 at 17:24
  • Thank you very much for your answer but still, it does not work. Because now I get as out put just two 'asterisk' in a column but missing the third one. – user1078406 Dec 06 '11 at 17:37