有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

顺便说一句,很抱歉格式弄乱了。我用的是Supreme,这是自动格式化的最佳选择

对于那些不熟悉的人,这里有一些生活游戏的规则: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) 个答案

  1. # 1 楼答案

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

    你有不必要的、令人困惑的循环

    nextGen方法中有四个嵌套循环。你只需要两个,就可以在网格中的每个单元格中循环。你不需要最外面的两个,只需要里面的两个,所以去掉外面的两个。同时去掉变量repeatstartXstartY,因为你不需要它们

    您还需要遍历所有表达式,例如visualize[startX + 1][startY],并将startX替换为k,将startY替换为l

    您的平方检查逻辑错误

    startXstartY替换为kl后,以下行在代码中出现两次:

                        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]

    还可以打印出一个由*.字符组成的小网格,代表下一代的状态。这必须使用life而不是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计数器了

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

    需要在l循环开始时将alive重置为零


    我对你的nextGen方法做了所有这些更改,它似乎起了作用,因为它展示了我希望在滑翔机上看到的一代人。以下是我的结论(IntelliJ对其进行了一些格式化,因此它的格式与您的代码不同):

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

    而且,LeftRight{}和Down注释是错误的。k循环在行上运行(即它是y-坐标),而l循环在每行的单元格上运行(即x-坐标)。而且,k + 1是下降一个单元格,而不是上升一个单元格