我一直在做一个生活游戏作业,并且接近完成阶段,但我正在努力弄清楚我搞砸了什么,以至于 GOL 规则(以及作业要求我们实现的 Fredkin 规则)没有产生正确的结果。
由于我几乎没有处理图形的经验,我决定在交互窗口中输出所有内容(使用 Dr.Java)。(它用于设置菜单选项,如比例、坐标(您手动输入)、世代,并输出您选择运行的任何规则(GOL 或 Fredkin)的最终生成。
程序 nextGeneration 从 main 方法(人们输入坐标的地方)获取布尔数组映射,并应将其更改为与下一代生命游戏相对应。这是通过创建一个全新的 2D 数组 map2 来实现的,该数组根据为每个点打开的邻居数量将值加载到其中。在程序结束时,map被加载到map2中。(注意:这不是原创的,这是作业所要求的)
程序 live 只是检查地图数组中的某个点是打开还是关闭。 countNeighbors 获取特定正方形的 8 个邻居,通过 living 方法将它们分别传递,并返回当前打开的邻居数。由于countNeighbors有时要求负数或大于地图比例的数字,因此我们在生活中实施了条件来创建环绕宇宙。
我认为问题最有可能出现在下一代中。我对使用操作数"or"(写为 || )有点紧张,我认为这可能是我搞砸的地方。如果你能浏览一下代码,看看我所说的是真的,是否写成真的,那绝对是美妙的。
下面是该程序的代码。它还利用了一个键盘.class文件,如果有帮助(编译需要),我很乐意发布该文件(但是有人会这样做)。
public class GameOfLife {
public static void main(String[] args) {
int r = 0; //rules set. Either 0 or 1, 0 for life game, 1 for Fredkin game
int i = 0; // looping variable
int j = 0; // looping variable
int b = 0; // used to read integer inputs from keyboard
int x = 0; // used during the stage where the player manually changes the board. Represents x coordinate.
int y = 0; // used during the stage where the player manually changes the board. Represents x coordinate.
int gen = 0; //number of generations to be skipped before printing out new map
int scale = 0;
boolean[][] map = new boolean[0][0];
System.out.println("Start game? y/n");
String a = Keyboard.readString();
if (a.equals("n")) {
return;
} else {
System.out.println("Do you wish to know the rules? y/n");
a = Keyboard.readString();
if (a.equals("y")) {
System.out.println("Each coordinate in the printed graph is represented by a 0 or a .");
System.out.println("0 represents a live cell, . represents a dead one.");
System.out.println("Each cell has 8 neighboring cells.");
System.out.println("There are two ways in which the game can be played.");
System.out.println("In the Life model, if a cell has 3 neighbors, if dead, it turns on.");
System.out.println("If it has 2 neighbors, it keeps its current condition.");
System.out.println("Else, it dies. Brutal.");
System.out.println("In the Fredkin Model, only non-diagnol neighbors count.");
System.out.println("If a cell has 1 or 3 neighbors, it is alive.");
System.out.println("If it has 0, 2 or 4, it dies. WAY more Brutal.");
}
System.out.println("Do you want to play by Fredkin or Life Rules? 0 for life, 1 for Fredkin");
while (i == 0) {
b = Keyboard.readInt();
if (b == 1) {
r = 1;
i = 1;
}
if (b == 0) {
r = 0;
i = 1;
}
}
while (j == 0) {
System.out.println("What scale would you like to use? Please enter an integer larger than 4");
b = Keyboard.readInt();
if (b >= 5) {
map = new boolean[b][b];
scale = b;
j = 1;
} else {
System.out.println("Come on, buddy, read the rules");
}
}
j = 0;
while (j == 0) {
System.out.println("Do you want to enter coordinates? y to continue entering coordinates, n to go to next option");
a = Keyboard.readString();
if (a.equals("y")) {
i = 0;
while (i == 0) {
System.out.println("Please enter a value for an X coordinate from 0 to " + (scale - 1));
b = Keyboard.readInt();
if (b >= 0) {
if (b < scale) {
i = 1;
x = b;
}
}
}
i = 0;
while (i == 0) {
System.out.println("Please enter a value for a Y coordinate from 0 to " + (scale - 1));
b = Keyboard.readInt();
if (b >= 0) {
if (b < scale) {
i = 1;
y = b;
}
}
}
map[y][x] = true;
printgame(map);
} else {
if (a.equals("n")) {
j = 1;
}
}
}
i = 0;
while (i == 0) {
System.out.println("How many generations would you like to skip ahead? Please enter a value greater than 0");
b = Keyboard.readInt();
if (b > 0) {
gen = b;
i = 1;
}
}
i = 0;
if (r == 0) {
for (i = 0; i <= gen; i++) {
nextGeneration(map);
}
printgame(map);
} else {
if (r == 1) {
for (i = 0; i <= gen; i++) {
FredGen(map);
}
printgame(map);
}
}
}
}
public static void printgame(boolean[][] map) {
int x = map[0].length;
int y = map[0].length;
int i = 0;
int j = 0;
char c;
String Printer = "";
for (j = 0; j < y; j++) {
for (i = 0; i < x; i++) {
if (map[j][i]) {
c = '0';
} else {
c = '.';
}
Printer = (Printer + " " + c);
}
System.out.println(Printer);
Printer = new String("");
}
}
private static void nextGeneration(boolean[][] map) {
int x = map[0].length;
int y = map[0].length;
int[][] neighborCount = new int[y][x];
boolean[][] map2 = new boolean[y][x];
for (int j = 0; j < y; j++)
for (int i = 0; i < x; i++)
neighborCount[j][i] = countNeighbors(j, i, map);
//this makes a new generation array
for (int j = 0; j < y; j++) {
for (int i = 0; i < x; i++) {
if (map[j][i] = true) { //assumes initial value of array is true (AKA "ALIVE")
if (neighborCount[j][i] == 3) { //check if alive AND meeting condition for life
map2[j][i] = true; //sets character array coordinate to ALIVE: "0"
} else if ((neighborCount[j][i] <= 2) || (neighborCount[j][i] > 3)) { //check if dead from isolation or overcrowding
map2[j][i] = false; //sets character array coordinate to DEAD: "."
}
}
}
}
map = map2;
}
private static int countNeighbors(int j, int i, boolean[][] map) { //counts all 8 elements living/dea of 3x3 space surrounding and including living/dead central coordinate)
return living(j - 1, j - 1, map) + living(j - 1, i, map) +
living(j - 1, i + 1, map) + living(j, i - 1, map) + living(j, i + 1, map) +
living(j + 1, i - 1, map) + living(j + 1, i, map) + living(j + 1, i + 1, map);
}
private static int living(int j, int i, boolean[][] map) {
int x = map[0].length - 1;
if (i < 0) {
i = i + x;
} else {
i = i % x;
}
if (j < 0) {
j = j + x;
} else {
j = j % x;
}
if (map[j][i] == true) {
return 1;
} else {
return 0;
}
}
private static void FredGen(boolean[][] map) {
int x = map[0].length;
int y = map[0].length;
int[][] neighborCount = new int[y][x];
for (int j = 0; j < y; j++)
for (int i = 0; i < x; i++)
neighborCount[j][i] = Freddysdeady(j, i, map);
//this makes a new generation array
for (int j = 0; j < y; j++)
for (int i = 0; i < x; i++)
if (map[j][i] = true) { //assumes initial value of array is true (AKA "ALIVE")
if ((neighborCount[j][i] < 1) || (neighborCount[j][i] == 2) || (neighborCount[j][i] > 3)) { //check if dead from isolation or overcrowding
map[j][i] = false; //sets chracter array coordinate to DEAD: "."
} else if ((neighborCount[j][i] == 1) || (neighborCount[j][i] == 3)) { //check if alive AND meeting condition for life
map[j][i] = true; //sets character array coordinate to ALIVE: "0"
}
}
}
private static int Freddysdeady(int j, int i, boolean[][] map) {
return living(j - 1, i, map) + living(j, i - 1, map) + living(j, i + 1, map) + living(j + 1, i, map);
}
}
可能还有其他问题,这里有一些我可以用肉眼发现的问题:
-
在
nextGeneration
方法中,您处理细胞应该保持存活或死亡的情况,但您没有关于细胞何时应该出生的任何信息。你应该有这样的东西:if(map[x][y]) { //should this cell stay alive? if yes = live, else die } else { //should a cell be born in this slot? if yes = born, else nothing }
-
这是一个小问题,仍然在
nextGeneration
,if(count==3)live; else if(count <=2 || count > 3) die;
是多余的,你只需要if(count == 3) live; else die;
如果您仍有问题,请告诉我们