简体   繁体   English

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

[英]JAVA - Conway's Game of Life deletes all alive cells?

I am working on Conway's Game of Life for a school project. 我正在为康威的一个学校项目的生命游戏工作。 I am not looking for the code directly. 我不是直接寻找代码。 I am looking to find out what is wrong with my code. 我想找出我的代码有什么问题。

In Conway's Game of Life a cell goes from dead to alive if it has 3 alive neighbors. 在康威的“生命游戏”中,如果一个单元有3个活着的邻居,它就会从死到活。 It stays alive if it has two or three alive neighbors. 如果它有两个或三个活着的邻居,它会保持活着。 If none of those are true it is dead. 如果这些都不是真的那就死了。

My LifeView class has a method that displays the cell simulation and afterwards displays how many alive cells are around the given point. 我的LifeView类有一个显示单元格模拟的方法,然后显示给定点周围有多少活细胞。

This is the output I am getting: 这是我得到的输出:

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

This is wrong because the second generation is supposed to be a horizontal line of live cells crossing the center of the first generation alive cells. 这是错误的,因为第二代应该是穿过第一代活细胞中心的活细胞的水平线。 Instead of crossing that center, all cells are turned dead. 所有细胞都没有穿过那个中心。 I am stumped as to why it doesn't work. 我很难过为什么它不起作用。

Main class: 主要课程:

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 class: 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 class: package gameOfLife; LifeModel类:包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();
    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;
}


}

Any help is GREATLY appreciated! 任何帮助是极大的赞赏!

You just have a couple small issues with your LifeModel class. 你的LifeModel类只有几个小问题。

In your constructor you set the tempWorld to reference the same array as the actual game world. 在构造函数中,您将tempWorld设置为引用与实际游戏世界相同的数组。 This will cause any modifications to tempWorld to also affect the gameWorld. 这将导致对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.
}

Then in next generation you have the line "//tempWorld = new boolean[numRows+2][numCols+2];" 然后在下一代你有一行“// tempWorld = new boolean [numRows + 2] [numCols + 2];” commented out. 评论说。 You really do need to create a new temp array here so you aren't changing the game board as you read it. 你真的需要在这里创建一个新的临时数组,这样你就不会在阅读时更改游戏板。 However, I'm not sure what the +2 is supposed to be, so I removed it. 但是,我不确定+2应该是什么,所以我删除了它。 You should have: 你应该有:

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

After I made those changes it worked perfectly for me. 在我做出这些改变后,它对我来说非常有效。 I've included the full LifeModel class below that I used on my machine. 我已经在我的机器上使用了下面的完整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;
}


}

Check that numLivingNeighbors is returning the proper value for each cell in the world. 检查numLivingNeighbors是否为世界中的每个单元格返回正确的值。

Also check the step for staying alive 还要检查保持活力的步骤

Hey You have done a simple mistake in your code 嘿你在代码中犯了一个简单的错误

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

this is LifeModel constructor. 这是LifeModel构造函数。 In this constructor you need to initialize tempworld also. 在这个构造函数中,您还需要初始化tempworld。 You should not assign your world to tempworld. 你不应该将你的世界分配给tempworld。 After modification this block of code will become like this.... 修改后,这段代码将变成这样......

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

After this your output will be correct. 在此之后,您的输出将是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM