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 楼答案
老实说,这里有几件事不对:
你有不必要的、令人困惑的循环
在
nextGen
方法中有四个嵌套循环。你只需要两个,就可以在网格中的每个单元格中循环。你不需要最外面的两个,只需要里面的两个,所以去掉外面的两个。同时去掉变量repeat
、startX
和startY
,因为你不需要它们您还需要遍历所有表达式,例如
visualize[startX + 1][startY]
,并将startX
替换为k
,将startY
替换为l
您的平方检查逻辑错误
将
startX
和startY
替换为k
和l
后,以下行在代码中出现两次:因此,你要两次计算相邻八个细胞中的一个,其中一个根本不算
要解决此问题,请将出现的此代码之一替换为以下代码:
您正在修改当前一代,同时计算下一代
在生活中,你不能在试图弄清楚下一代是什么的同时改变世界上的这一代。否则,你可能会将一个细胞标记为死亡,而这是维持另一个细胞存活所必需的。相反,您必须创建第二个数组,并在其中记录下一代的状态
您已经创建了第二个数组,
life
,但您似乎根本没有使用它。所以,让我们用这个。一旦你弄清楚一个细胞应该是活的还是死的,就把这个值赋给life[k][l]
,而不是visualize[k][l]
还可以打印出一个由
*
和.
字符组成的小网格,代表下一代的状态。这必须使用life
而不是visualize
你把生活规则搞错了
您的代码当前的目标是,如果任何一个正方形正好有三个邻居,则将其标记为活动,否则将其标记为死亡。生活不是这样的
如果一个活细胞有两个或三个邻居,它就可以存活,否则它就会死亡。一个只有三个邻居的空牢房就活了
以下代码实现了此逻辑:
您忘记重置
alive
计数器了在
nextGen
的开头将变量alive
设置为0
,但在计算每个单元格的活动邻居数时,不会将其重置为零。这意味着alive
因此正在计算到目前为止遇到的每个细胞的活邻居的数量。过不了多久,这个数字就会超过3,一切都会结束需要在
l
循环开始时将alive
重置为零我对你的
nextGen
方法做了所有这些更改,它似乎起了作用,因为它展示了我希望在滑翔机上看到的一代人。以下是我的结论(IntelliJ对其进行了一些格式化,因此它的格式与您的代码不同):请花点时间了解这些变化,以及这段代码的工作原理
最后,您可以编写这样的代码八次:
不用写
if (!(something == 0)) ...
,你可以写if (something != 0)
。但是,您可以进一步简化此代码:如果一个单元格等于2
,它也会自动不等于0
,因此您可以只编写以下代码:而且,}和
Left
、Right
{Down
注释是错误的。k
循环在行上运行(即它是y-坐标),而l
循环在每行的单元格上运行(即x-坐标)。而且,k + 1
是下降一个单元格,而不是上升一个单元格