生命游戏代码方法的问题?(用户界面是完整的,但实际的 GOL 方法没有生成它们应该生成的内容)



我一直在做一个生活游戏作业,并且接近完成阶段,但我正在努力弄清楚我搞砸了什么,以至于 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);
  }
}

可能还有其他问题,这里有一些我可以用肉眼发现的问题:

  1. 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 }

  2. 这是一个小问题,仍然在nextGenerationif(count==3)live; else if(count <=2 || count > 3) die;是多余的,你只需要if(count == 3) live; else die;

如果您仍有问题,请告诉我们

相关内容

最新更新