代码之家  ›  专栏  ›  技术社区  ›  ddalcanto

我在重现约翰·康威的人生游戏。然而,我对游戏规则的检查并没有正确地检测周围的生命。为什么会这样?

  •  -1
  • ddalcanto  · 技术社区  · 6 年前

    我已经做了很长一段时间的实验,但我就是看不出我的错误是在检查周围的生命!你们能看看我的代码,看看我的错误在哪里吗?代码中的所有内容在检查周围生命之外都是完全有效的。

    对于那些不熟悉生活的人,这里有一些生活游戏的规则: https://bitstorm.org/gameoflife/

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class Life
    {
        public static void main(String[] args)
        {
            Scanner in = new Scanner(System.in);
            String userin = in.nextLine();
            int x = 8;
            int y = 8;      
            int [][] visualize;
            if(userin.equals("glider"))
            {
                visualize = new int [][]{
                    //0 is used as a boundary, 1 represents a dead cell, 2 represents an alive cell
                    {0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 1, 1, 1, 1, 1, 1, 0},
                    {0, 1, 1, 1, 1, 1, 1, 0},
                    {0, 1, 1, 1, 2, 1, 1, 0},
                    {0, 1, 1, 1, 1, 2, 1, 0},
                    {0, 1, 1, 2, 2, 2, 1, 0},
                    {0, 1, 1, 1, 1, 1, 1, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0}
                };
                for (int i = 0; i <= 7; i++)
                {
                    for (int j = 0; j <= 7; j++)
                    {
                        if (visualize[i][j] == 2) {
                            System.out.print("*");
                        } else if (visualize[i][j] == 1)
                        {
                            System.out.print(".");
                        } else if (visualize[i][j] == 0)
                        {
                            System.out.print("_");
                        }
                    }
                    System.out.println();
                }
                nextGen(visualize, x, y);
            } else if(userin.equals("own"))
            {
                visualize = new int [8][8];
                for(int o = 1; o <= 6; o++) //Starting it a pos 1 means pos 0 is automaically filled with a "0", which is used as the boundary
                {
                    visualize[o] = new int[x];
                    for(int p = 1; p <= 6; p++) //Starting it a pos 1 means pos 0 is automaically filled with a "0", which is used as the boundary
                    {
                        visualize[o][p] = in.nextInt();
                    }
                    System.out.println(0);
                    System.out.println();
                }
                for (int i = 0; i <= 7; i++)
                {
                    for (int j = 0; j <= 7; j++)
                    {
                        if(visualize[i][j] == 2) {
                            System.out.print("*");
                        } else if (visualize[i][j] == 1)
                        {
                            System.out.print(".");
                        } else if (visualize[i][j] == 0)
                        {
                            System.out.print("_");
                        }
                    }
                    System.out.println();
                }
                nextGen(visualize, x, y);
            }
            else if(userin.equals("test"))
            {
                visualize = new int [][]{
                    {0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 1, 1, 1, 1, 1, 1, 0},
                    {0, 1, 2, 2, 1, 1, 1, 0},
                    {0, 1, 2, 1, 1, 1, 1, 0},
                    {0, 1, 1, 1, 1, 1, 1, 0},
                    {0, 1, 1, 1, 1, 1, 1, 0},
                    {0, 1, 1, 1, 1, 1, 1, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0}
                };
                for (int i = 0; i <= 7; i++)
                {
                    for (int j = 0; j <= 7; j++)
                    {
                        if (visualize[i][j] == 2) {
                            System.out.print("*");
                        } else if (visualize[i][j] == 1)
                        {
                            System.out.print(".");
                        } else if (visualize[i][j] == 0)
                        {
                            System.out.print("_");
                        }
                    }
                    System.out.println("_");
                }
                nextGen(visualize, x, y);
            }
        }
        static void nextGen(int visualize[][], int x, int y)
        {
            int[][] life = new int[x][y];
            int alive = 0;
            //Starts at array-point 1,1
            int startX = 1;
            int startY = 1;
            System.out.println();
            System.out.println();
            System.out.println("________");
            System.out.print("_");
            for(int repeat = startX; repeat <= 6; repeat++)
            {
    
                while(startY <= 6)
                {
                    for(int k = startX; k <=6; k++)
                    {
                        for(int l = startY; l <=6; l++)
                        {
                            //BEGIN CHECK FOR SURROUNDING LIVES
                            if(!(visualize[startX + 1][startY] == 0))
                            {
            if(visualize[startX + 1][startY] == 2) //Right 1
            {
                alive++;
            }
        }
        if(!(visualize[startX][startY + 1] == 0))
        {
            if(visualize[startX][startY + 1] == 2) //Up 1
            {
                alive++;
            }
        }
        if(!(visualize[startX + 1][startY + 1] == 0))
        {
            if(visualize[startX + 1][startY + 1] == 2) // Right 1, Up 1
            {
                alive++;
            }
        }
        if(!(visualize[startX - 1][startY] == 0))
        {
                if(visualize[startX - 1][startY] == 2) //Left 1
                {
                    alive++;
                }       
            }
            if(!(visualize[startX][startY - 1] == 0))
            {
                if(visualize[startX][startY - 1] == 2) // Down 1
                {
                    alive++;
                }
            }
            if(!(visualize[startX - 1][startY - 1] == 0))
            {
                if(visualize[startX - 1][startY - 1] == 2) //Left 1, Down 1
                {
                    alive++;
                }
            }
            if(!(visualize[startX + 1][startY - 1] == 0))
            {
            if(visualize[startX + 1][startY - 1] == 2) //Right 1, Down 1
            {
                alive++;
            }
        }
        if(!(visualize[startX - 1][startY - 1] == 0))
        {
                if(visualize[startX - 1][startY - 1] == 2) //Left 1, Down 1
                {
                    alive++;
                }
            }
            //CHECKS IF THERE ARE EXACTLY 3 LIVES AROUND AN AREA. IF NOT, IT KILLS THAT AREA
            if(alive == 3)
            {
                visualize[k][l] = 2;
    
            } else {
                visualize[k][l] = 1;
            }
        }
    }
    
    if (visualize[startX][startY] == 2) {
        System.out.print("*");
    } else if (visualize[startX][startY] == 1)
    {
        System.out.print(".");
    }   
    //Performs the check going down the Y-axis
    startY++;
    }
    System.out.println("_");
    System.out.print("_");
    //After
    startX++;
    startY = 1;
    
    }
    System.out.println("_______");
    }
    }
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Luke Woodward    6 年前

    老实说,这里有几件事不对:

    你有不必要的和混乱的循环

    您的数据库中有四个嵌套循环 nextGen 方法。您只需要两个,就可以在网格中的每个单元格中循环。你不需要最外面的两个,只需要里面的两个,所以去掉外面的两个。也要去掉这些变量 repeat , startX startY ,因为你不需要它们。

    您还需要遍历所有表达式,例如 visualize[startX + 1][startY] 替换 斯塔克斯 k 斯塔蒂 具有 l

    更换后 斯塔克斯 具有 K L

                        if (!(visualize[k - 1][l - 1] == 0)) {
                            if (visualize[k - 1][l - 1] == 2) //Left 1, Down 1
                            {
                                alive++;
                            }
                        }
    

    因此,您将两次计算相邻八个单元格中的一个,而其中一个根本不计算。

    若要修复此问题,请将出现的此代码之一替换为以下代码:

                        if (!(visualize[k - 1][l + 1] == 0)) {
                            if (visualize[k - 1][l + 1] == 2) //Left 1, Up 1
                            {
                                alive++;
                            }
                        }
    

    在生活中,你不能在试图弄清楚下一代是什么的同时改变世界上的这一代人。否则,您可能会将一个细胞标记为死亡,而这是保持另一个细胞存活所必需的。相反,您必须创建第二个数组,并在其中记录下一代的状态。

    life ,但你好像根本没用。所以,让我们使用它。一旦计算出一个单元格应该是活的还是死的,将该值赋给 life[k][l] 而不是 visualize[k][l] .

    * . 表示下一代状态的字符。这将不得不使用 而不是 visualize

    你把生活规则搞错了

    如果一个活细胞有两个或三个邻居,它就可以存活,否则它就会死亡。一个只有三个邻居的空牢房就活了。

                if (visualize[k][l] == 2 && (alive == 2 || alive == 3)) {
                    // Live cell stays alive if 2 or 3 neighbours
                    life[k][l] = 2;
                }
                else if (visualize[k][l] == 1 && alive == 3) {
                    // Dead cell becomes live if 3 neighbours
                    life[k][l] = 2;
                }
                else {
                    // Anything else: cell either dies or stays dead.
                    life[k][l] = 1;
                }
    

    你忘了重置开关 alive 柜台

    设置变量 活着的 0 ,但不将每个单元格的数量重置为零。这意味着 活着的 因此正在计算到目前为止遇到的每一个细胞的活邻居的数量。过不了多久,这个数字就会超过3,一切都会结束。

    活着的


    下一个

        static void nextGen(int visualize[][], int x, int y) {
            int[][] life = new int[x][y];
            int alive = 0;
    
            System.out.println();
            System.out.println();
            System.out.println("________");
            System.out.print("_");
    
            for (int k = 1; k <= 6; k++) {
                for (int l = 1; l <= 6; l++) {
                    alive = 0;
                    //BEGIN CHECK FOR SURROUNDING LIVES
                    if (!(visualize[k + 1][l] == 0)) {
                        if (visualize[k + 1][l] == 2) //Right 1
                        {
                            alive++;
                        }
                    }
                    if (!(visualize[k][l + 1] == 0)) {
                        if (visualize[k][l + 1] == 2) //Up 1
                        {
                            alive++;
                        }
                    }
                    if (!(visualize[k + 1][l + 1] == 0)) {
                        if (visualize[k + 1][l + 1] == 2) // Right 1, Up 1
                        {
                            alive++;
                        }
                    }
                    if (!(visualize[k - 1][l] == 0)) {
                        if (visualize[k - 1][l] == 2) //Left 1
                        {
                            alive++;
                        }
                    }
                    if (!(visualize[k][l - 1] == 0)) {
                        if (visualize[k][l - 1] == 2) // Down 1
                        {
                            alive++;
                        }
                    }
                    if (!(visualize[k - 1][l - 1] == 0)) {
                        if (visualize[k - 1][l - 1] == 2) //Left 1, Down 1
                        {
                            alive++;
                        }
                    }
                    if (!(visualize[k + 1][l - 1] == 0)) {
                        if (visualize[k + 1][l - 1] == 2) //Right 1, Down 1
                        {
                            alive++;
                        }
                    }
                    if (!(visualize[k - 1][l + 1] == 0)) {
                        if (visualize[k - 1][l + 1] == 2) //Left 1, Up 1
                        {
                            alive++;
                        }
                    }
    
                    if (visualize[k][l] == 2 && (alive == 2 || alive == 3)) {
                        life[k][l] = 2;
                    }
                    else if (visualize[k][l] == 1 && alive == 3) {
                        life[k][l] = 2;
                    }
                    else {
                        life[k][l] = 1;
                    }
    
                    if (life[k][l] == 2) {
                        System.out.print("*");
                    }
                    else if (life[k][l] == 1) {
                        System.out.print(".");
                    }
                }
    
                System.out.println("_");
                System.out.print("_");
            }
            System.out.println("_______");
    
            // Copy the 'life' array back to 'visualize', so that the
            // next generation could be calculated from it.
            for (int i = 1; i < 6; ++i)
            {
                visualize[i] = life[i];
            }
        }
    

    花点时间来理解这些变化,以及为什么这段代码可以工作。

                    if (!(visualize[k + 1][l] == 0)) {
                        if (visualize[k + 1][l] == 2) //Right 1
                        {
                            alive++;
                        }
                    }
    

    而不是写作 if (!(something == 0)) ... if (something != 0) 2 0

                    if (visualize[k + 1][l] == 2) //Right 1
                    {
                        alive++;
                    }
    

    此外,还有 Left Right Up Down 评论是错误的。这个 K Y L 循环在每行的单元格上运行( -协调)。也, k + 1 是下一个单元格,不是上一个单元格。