Проблема с кодом игры Game of life? (Пользовательский интерфейс завершен, но реальные методы GOL не генерируют то, что они должны)

Я работал над заданием Game of Life и близок к завершению, но изо всех сил пытаюсь выяснить, что я испортил, так что GOL правит (и Фредкин правит, что это задание также требует от нас выполнения)) не дают должного результата.

Поскольку у меня мало опыта работы с графикой, я решил вывести все в окне взаимодействий (используя Dr.Java). (Он используется для настройки параметров меню, таких как масштаб, координаты (вы вводите вручную), поколения и вывод окончательного поколения любого правила, которое вы выберете (GOL или Fredkin).

Программа nextGeneration берет карту логического массива из основного метода (где люди вводят координаты) и должна изменить ее, чтобы она соответствовала следующему поколению игры жизни. Это происходит путем создания совершенно нового двумерного массива map2, в который загружаются значения, основанные на количестве соседей, которые включены для каждой точки. В конце программы карта загружается в map2 (примечание: это не оригинал, это требуется для задания)

Проживающая программа просто проверяет, включена ли точка в массиве карты. countNeighbors берет 8 соседей определенного квадрата, передает их каждому через живой метод и возвращает количество соседей, которые в данный момент включены. Поскольку countNeighbors иногда требует либо отрицательного числа, либо числа, превышающего масштаб карты, мы создали условия жизни, чтобы создать эту круговую вселенную.

Я думаю, что проблема (и), скорее всего, возникнет в следующем поколении. Я несколько напряжен в отношении использования операнда "или" (написанного как ||), и я думаю, что это может быть там, где я облажался. Если бы вы могли просто просмотреть код и посмотреть, написано ли то, что я сказал "правда", как правда, это было бы просто замечательно.

Ниже приведен код для программы. Он также использует файл Keyboard.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 ответ

Могут быть и другие проблемы, вот некоторые, которые я мог бы заметить на глаз:

  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. Это небольшая проблема, все еще в nextGeneration, в if(count==3)live; else if(count <=2 || count > 3) die; избыточно, вам нужно только if(count == 3) live; else die;

дайте нам знать, если у вас все еще есть проблемы

Другие вопросы по тегам