JAVA - 康威的生命游戏删除所有活细胞?



我正在为一个学校项目制作康威的《生命游戏》。我不是直接查找代码。我想找出我的代码出了什么问题。

在康威的《生命的游戏》中,如果一个细胞有三个活着的邻居,它就会从死变成活。如果它有两三个活着的邻居,它就能活下来。如果这些都不是真的,那就是死了。

我的LifeView类有一个方法,它显示单元模拟,然后显示给定点周围有多少活动单元。

这是我得到的输出:

How many rows is your simulation?
5
How many columns is your simulation?
5
How many generations is your simulation?
3
xxxxx
xxxxx
xx0xx
xx0xx
xx0xx
00000
01110
02120
03230
02120

xxxxx
xxxxx
xxxxx
xxxxx
xxxxx
00000
00000
00000
00000
00000

xxxxx
xxxxx
xxxxx
xxxxx
xxxxx
00000
00000
00000
00000
00000

这是错误的,因为第二代被认为是穿过第一代活细胞中心的活细胞的水平线。所有细胞都死了,而不是穿过那个中心。我不明白为什么它不起作用。

主要类别:

package gameOfLife;
import java.util.Scanner;
public class Main {
/**
 * @param args the command line arguments
 */
public static void main(String[] args)
{
    Scanner numReader = new Scanner(System.in);
    System.out.println("How many rows is your simulation?");
    int rows = numReader.nextInt();
    System.out.println("How many columns is your simulation?");
    int columns = numReader.nextInt();
    System.out.println("How many generations is your simulation?");
    int generations = numReader.nextInt();

    LifeModel model = new LifeModel(rows,columns);
    LifeView life = new LifeView(model);
    for(int i=0; i<generations; i++)
    {
         life.displayLife();
         model.nextGeneration();
    }
}

LifeView类:

package gameOfLife;
import java.util.Scanner;
public class LifeView {
private LifeModel model;
public LifeView(LifeModel model)
{
    this.model = model;
}

public void displayLife()
{
    for(int i=0; i < model.getWorld().length; i++)
    {
        for(int j=0; j < model.getWorld()[0].length; j++)
        {
            if(model.getWorld()[i][j])
            {
                System.out.print("0");
            }
            else
            {
                System.out.print("x");
            }
        }
        System.out.println("");
    }
    System.out.println("");
    for(int i=0; i < model.getWorld().length; i++)
    {
        for(int j=0; j < model.getWorld()[0].length; j++)
        {
            System.out.print(model.numLivingNeighbors(i,j));
        }
        System.out.println("");
    }
    System.out.println("");
    System.out.println("");
}
}

LifeModel类:包游戏OfLife;

public class LifeModel
{
private boolean[][] world;
private int numRows;
private int numCols;
private boolean[][] tempWorld;

public LifeModel(int rows, int cols)
{
    this.numRows=rows;
    this.numCols=cols;
    world = new boolean[rows][cols];
    initWorld();
    tempWorld = world;
}
private void initWorld()
{
    boolean done = false;
    while(!done)
    {
        int i = (int) (Math.random()*numRows);
        int j = (int) (Math.random()*numCols);
        if(j>0 && i>0 && i<numRows-1 && j<numCols-1)
        {
            /*
             world[i-1][j-1] = true;
             world[i-1][j] = true;
             world[i-1][j+1] = true;
             world[i][j+1] = true;
             world[i+1][j] = true;
             */
             world[i][j]=true;
             world[i+1][j]=true;
             world[i-1][j]=true;
             done = true;
        }
    }

}
public void nextGeneration()
{
    //tempWorld = new boolean[numRows+2][numCols+2];
    int rows = world.length;
    int columns = world[0].length;
    for(int i=0; i < rows; i++)
    {
        for(int j = 0; j < columns; j++)
        {
            toggleCell(i,j);
        }
    }
    world = tempWorld;
}
public void toggleCell(int r, int c)
{
    int count = numLivingNeighbors(r,c);
    if(!world[r][c] && count==3)
    {
        tempWorld[r][c] = true;
    }
    else if(world[r][c] && (count>=2 && count<=3))
    {
        tempWorld[r][c] = true;
    }
    else
    {
        tempWorld[r][c] = false;
    }
}
public int numLivingNeighbors(int r, int c)
{
    int count = 0;
    boolean newCells[][] = world;
    for(int i = -1; i<=1; i++)
    {
        for(int j = -1; j<=1; j++)
        {
            if(i!=0 || j!=0)
            {
                int row = r + i;
                int column = c + j;
                if(row>=0 && row < newCells.length && column>=0 && column<newCells[0].length && newCells[row][column])
                {
                    count++;
                }
            }
        }
    }
    return count;
}
public void userChange()
{
}
public boolean[][] getWorld()
{
    return world;
}

}

非常感谢您的帮助!

您的LifeModel类只有几个小问题。

在构造函数中,您将tempWorld设置为引用与实际游戏世界相同的数组。这将导致对tempWorld的任何修改也会影响gameWorld。

public LifeModel(int rows, int cols)
{
    this.numRows=rows;
    this.numCols=cols;
    world = new boolean[rows][cols];
    initWorld();
    //tempWorld = world;  // You can remove this line.
}

然后在下一代中,您可以注释掉行"//tempWorld=new boolean[numRows+2][numCols+2];"。你确实需要在这里创建一个新的临时数组,这样你就不会在阅读游戏板时更改它。然而,我不确定+2应该是什么,所以我删除了它。你应该有:

public void nextGeneration()
{
    tempWorld = new boolean[numRows][numCols]; // Keep it the same size
    int rows = world.length;
    int columns = world[0].length;
    for(int i=0; i < rows; i++)
    {
        for(int j = 0; j < columns; j++)
        {
            toggleCell(i,j);
        }
    }
    world = tempWorld;
}

在我做了这些更改之后,它对我来说非常有效。我在下面包含了我在机器上使用的完整的LifeModel类。

package gameOfLife;
public class LifeModel
{
private boolean[][] world;
private int numRows;
private int numCols;
private boolean[][] tempWorld;

public LifeModel(int rows, int cols)
{
    this.numRows=rows;
    this.numCols=cols;
    world = new boolean[rows][cols];
    initWorld();
}
private void initWorld()
{
    boolean done = false;
    while(!done)
    {
        int i = (int) (Math.random()*numRows);
        int j = (int) (Math.random()*numCols);
        if(j>0 && i>0 && i<numRows-1 && j<numCols-1)
        {
            /*
             world[i-1][j-1] = true;
             world[i-1][j] = true;
             world[i-1][j+1] = true;
             world[i][j+1] = true;
             world[i+1][j] = true;
             */
             world[i][j]=true;
             world[i+1][j]=true;
             world[i-1][j]=true;
             done = true;
        }
    }

}
public void nextGeneration()
{
    tempWorld = new boolean[numRows][numCols];
    int rows = world.length;
    int columns = world[0].length;
    for(int i=0; i < rows; i++)
    {
        for(int j = 0; j < columns; j++)
        {
            toggleCell(i,j);
        }
    }
    world = tempWorld;
}
public void toggleCell(int r, int c)
{
    int count = numLivingNeighbors(r,c);
    if(!world[r][c] && count==3)
    {
        tempWorld[r][c] = true;
    }
    else if(world[r][c] && (count>=2 && count<=3))
    {
        tempWorld[r][c] = true;
    }
    else
    {
        tempWorld[r][c] = false;
    }
}
public int numLivingNeighbors(int r, int c)
{
    int count = 0;
    boolean newCells[][] = world;
    for(int i = -1; i<=1; i++)
    {
        for(int j = -1; j<=1; j++)
        {
            if(i!=0 || j!=0)
            {
                int row = r + i;
                int column = c + j;
                if(row>=0 && row < newCells.length && column>=0 && column<newCells[0].length && newCells[row][column])
                {
                    count++;
                }
            }
        }
    }
    return count;
}
public void userChange()
{
}
public boolean[][] getWorld()
{
    return world;
}

}

检查numLivingNeighbors是否为世界上的每个单元格返回了正确的值。

还要检查保持活力的步骤

嘿,你在代码中犯了一个简单的错误

public LifeModel(int rows, int cols)
{
    this.numRows=rows;
    this.numCols=cols;
    world = new boolean[rows][cols];
    initWorld();
    tempWorld = world;
}

这是LifeModel构造函数。在这个构造函数中,您还需要初始化tempworld。你不应该把你的世界分配给临时世界。修改后,这个代码块将变成这样。。。。

public LifeModel(int rows, int cols)
{
this.numRows=rows;
this.numCols=cols;
world = new boolean[rows][cols];
tempWorld = new boolean[rows][cols];
initWorld();
}

在此之后,您的输出将是正确的。

最新更新