This site requires JavaScript, please enable it in your browser!
Greenfoot back
Wavesludge
Wavesludge wrote ...

2012/12/11

Conway's Game Of life

1
2
Wavesludge Wavesludge

2012/12/11

#
How would you go around doing Conway's Game of Life, but you could add and remove squares before the game has started and when the game is running? This is one scenario that I have been looking at and want to have mouse ineraction. G.O.L Scenario Something like this: http://www.greenfoot.org/scenarios/6908
danpost danpost

2012/12/11

#
Just add the code in the 'act' method of the Cell class (or a method it calls) to change the state of the cell when clicked on.
Wavesludge Wavesludge

2012/12/11

#
OK, there is a method:
    public void flipState() {
        setState(!myState);
    }
But if I use that in the act like this:
       if (Greenfoot.mouseClicked(null))
        {
            MouseInfo mouse=Greenfoot.getMouseInfo();
            flipState();
        }
All of the cells gets flipped, but I want only the cell I click to get flipped
vonmeth vonmeth

2012/12/11

#
if (Greenfoot.mouseClicked(this))  
 {  
     flipState();  
 }  
danpost danpost

2012/12/11

#
Please post the entire Cell class as you have it right now.
Wavesludge Wavesludge

2012/12/11

#
vonmeth's solution worked great thanks! Cell class:
import greenfoot.*;  
import java.awt.Color;
import java.util.List;

public class Cell  extends Actor
{
    Boolean         myFirstTime = true;
    Boolean         myState, myLastState;
    GreenfootImage  myBody;
    int             myNumNeighbors;
    int             myBodySize;
    Cell []         myNeighbors;
    
    public Cell(int cellSize) 
    {
        super();
        myState = myLastState = false;
        myBody = new GreenfootImage(cellSize, cellSize);
        setImage(myBody);
        myBodySize = cellSize - 2;
        showState();
    }
    
    public void act() 
    {
        if (myFirstTime) 
        {
            List neighbors = getNeighbours(1, true, Cell.class);
            myNumNeighbors = neighbors.size();
            myNeighbors = new Cell[myNumNeighbors];
            for(int i = 0; i < myNumNeighbors; i++)
                myNeighbors[i] = (Cell)neighbors.get(i);
                myFirstTime = false;
         }
        
        if (Greenfoot.mouseClicked(this))    
        {    
            flipState();    
        }  
        applyRule();
        showState();
    }
    
    public void saveLastState() 
    {
        myLastState = myState;
    }

    public void setState(boolean state) 
    {
        myState = state;
        showState();
    }
    

    public boolean getState() 
    {
       return(myState);
    }

    public void flipState() 
    {
        setState(!myState);
    }
    
    public int countNeighbors() 
    {
        int sum = 0;
        for(int i = 0; i < myNumNeighbors; i++) 
            if (myNeighbors[i].myLastState)
                sum++;
        return(sum);
    }
    
    public void applyRule() 
    {}
    
    private void showState() 
    {
        if (myState) 
            myBody.setColor(Color.black);
        else 
            myBody.setColor(Color.white);
        myBody.fillRect(1, 1, myBodySize, myBodySize);
    }
}
Is there an alternative to the getNeighbour method, but gives the same result?
vonmeth vonmeth

2012/12/11

#
The click isn't going to work correctly, as applyRule is going to change its state after it is clicked. Edit: You can't see this why this is with the code provided, but Cell has a subclass with a different applyRule that will.
Wavesludge Wavesludge

2012/12/11

#
Yeah, there is one subclass:
import greenfoot.*;  

public class LifeCell  extends Cell
{
    public LifeCell(int cellSize) {
        super(cellSize);
    }

    public void applyRule() {
        int numNeighborsOn = countNeighbors();
        boolean state = myState;
        
        if (numNeighborsOn < 2)
            state = false;
        else if (numNeighborsOn > 3)
            state = false;
        else if (numNeighborsOn == 3)
            state = true;
            
        myState = state;
    }   
}
Wavesludge Wavesludge

2012/12/11

#
One important thing I want is that when I run the scenario it doesn't "run" it's paused until I hit space, then I can pause the scenario while it's running with pause, and I can edit the block with the mouse. Havn't quite figured out how to do that yet.
vonmeth wrote...
The click isn't going to work correctly, as applyRule is going to change its state after it is clicked. Edit: You can't see this why this is with the code provided, but Cell has a subclass with a different applyRule that will.
Why not?
vonmeth vonmeth

2012/12/11

#
Ah, I'm tired, just place the click after applyRule.
vonmeth vonmeth

2012/12/11

#
Wavesludge wrote...
One important thing I want is that when I run the scenario it doesn't "run" it's paused until I hit space, then I can pause the scenario while it's running with pause, and I can edit the block with the mouse. Havn't quite figured out how to do that yet.
I edited it do the same. pause is public boolean of CellularAutomata.
    public void act() 
    {
        if (myFirstTime) {
            List neighbors = getNeighbours(1, true, Cell.class);
            myNumNeighbors = neighbors.size();
            myNeighbors = new Cell[myNumNeighbors];
            for(int i = 0; i < myNumNeighbors; i++)
                myNeighbors[i] = (Cell)neighbors.get(i);
            myFirstTime = false;
         }
        CellularAutomata world = (CellularAutomata) getWorld();
         if(!world.pause)
         {
         applyRule();
         }
         if (Greenfoot.mouseClicked(this))  
         {  
             flipState();
             saveLastState();
         }  
         showState();
    }
Should work correctly though I can't work out in my head right now, if when the game is unpaused, if calling saveLastState in that if block will cause behaviour we don't want.
Wavesludge Wavesludge

2012/12/11

#
Can't find symbol - variable pause tried adding the variable as I know, but I still get the same error
vonmeth vonmeth

2012/12/11

#
    public boolean          pause = true; // so we start off paused

    public CellularAutomata()
    {    
        super(20, 20, 20);
        myHeight = getHeight();
        myWidth = getWidth();
        myCellSize = getCellSize();
        drawGrid();
        createCells();
        saveState(); // so we save the state of cells from the start, even when starting off paused
    }

    public void act() 
    {
        if ("space".equals(Greenfoot.getKey())) pause = !pause;
        if(!pause) saveState();
    }

    private void saveState(){
        for(int i = 0; i < myHeight; i++)
            for(int j = 0; j < myWidth; j++)
                myCells[i][j].saveLastState();
    }
vonmeth vonmeth

2012/12/11

#
public void act()   
{  
    if (myFirstTime) {  
        List neighbors = getNeighbours(1, true, Cell.class);  
        myNumNeighbors = neighbors.size();  
        myNeighbors = new Cell[myNumNeighbors];  
        for(int i = 0; i < myNumNeighbors; i++)  
            myNeighbors[i] = (Cell)neighbors.get(i);  
        myFirstTime = false;  
     }  
    CellularAutomata world = (CellularAutomata) getWorld();  
     if(!world.pause) applyRule();  
     if (Greenfoot.mouseClicked(this)) flipState();   
     showState();  
}  
Need to remove the saveLastState(); I put in there. It was causing some problems. It will work when pausing, and unpausing, but I think my earlier fear of it not acting correctly when changing the state of the cell while the game is running seems to be proving true. I tested it on patterns that always act one way. That is, change into another pattern when changing the state of a cell near it. When pausing, adding the cell, then unpausing, it would change into the pattern. When the adding the cell while unpaused, it doesn't change into the correct pattern.
Wavesludge Wavesludge

2012/12/11

#
After I added that, it takes ages for the world to show up after compiling, and it's just a green background with no squares.
There are more replies on the next page.
1
2