如何产生新的网格 - 生命的游戏

时间:2011-12-06 16:40:14

标签: java

大家好我想模拟一个简单的康威生活游戏,这些都是游戏规则:

任何活着的邻居少于两个的活细胞都会死亡,就像人口不足一样。 任何有两三个活邻居的活细胞都会留在下一代。 任何有三个以上活着的邻居的活细胞都会死亡,就像过度拥挤一样。 具有正好三个活邻居的任何死细胞变成活细胞,就好像通过繁殖一样。

现在问题是我需要修改我的实际网格才能打印它然后在应用任何规则之前将其重新更改为其先前的值,但是我找不到任何系统来完成此任务,我希望有人可以帮我。 这是我的代码:

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;
                                }

            }
        }
        }
}       

文件:

* * *

预期产出:

*
*
*

新的run()方法是:

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();
}

现在不是获得输出:

*
*
*

我明白了:

*
*

有人可以帮我弄清楚原因吗?

1 个答案:

答案 0 :(得分:1)

欢迎!

也许我误解了你的问题,但你的问题是网格早期更新(阅读:新游戏状态用于计算剩余的旧单元格?)

我认为你遇到了old = grid的麻烦,因为这只会产生你阵列的shallow copy。您很可能正在寻找可以使用Array继承的clone method实现的深层复制。

此外,当我阅读代码时,我感觉你已经在计算新游戏状态的同时更新了网格。只将新游戏状态分配给工作网格,如“gridTemp”,当退出外部for循环时,您应该执行以下操作:

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

请记住,这只是伪代码!无论如何,我希望它有用。 :)

修改 好的,我无法在这里运行您的代码,因此我不能100%确定这是否是您问题的解决方案,但此代码块似乎是错误的:

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;
                                }
相反,我建议进行一次微小的重组。将上面的代码替换为:

newGrid[i][j] = generation

并在迭代后添加以下内容。

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

因此,在计算新游戏时,不是一直更新和显示网格给自己一个吻,(保持甜蜜和简单!)。首先确定新游戏状态并将其保存在newGrid之类的临时网格中。 最后,您可以将游戏状态复制到旧网格中并更新显示。 可能甚至没有必要在那里调用clone()方法,但让我们有点疯狂:)