Issue with Game of life code method? (User interface is complete but actual GOL methods aren't generating what they should)

六眼飞鱼酱① 提交于 2019-12-12 05:29:23

问题


I've been working on a Game of Life assignment and am nearing the stage of completion, but am struggling to figure out what I've messed up on such that the GOL rules (and Fredkin rules that the assignment requires us to implement as well) are not generating the proper result.

As I have little experience working with graphics I decided to output everything in the interactions window (using Dr.Java). (It's used to set up menu options like the scale, coordinates (you manually enter), generations, and output the final generation of whichever rule you choose to run (GOL or Fredkin).

The program nextGeneration takes a Boolean array map from the main method (where people input coordinates), and should change it to correspond to the next generation of the Game of Life. This happens by creating an entirely new 2D array, map2, which gets values loaded into it based on the number of neighbors which are turned on for each point. At the end of the program, map gets loaded into map2.(Note: this isn't original, this is required by the assignment)

The program living merely checks if a point in the map array is on or off. countNeighbors takes the 8 neighbors of a particular square, passes them each through the living method, and returns the number of neighbors which are currently on. Since countNeighbors sometimes demands either a negative number, or a number greater than the scale of the map, we implemented conditions in living to create that wraparound universe.

I think the problem(s) most likely arise in nextGeneration. I am somewhat tense about using the operand "or" (written as || ), and I think this may be where I screwed up. If you could just look through the code, and see if what I have said is true is written as true, that would be absolutely wonderful.

Below is the code for the program. It also utilizes a Keyboard.class file which I'm happy to post (however one would do that) if that helps (it's required to compile).

   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:


There might be other problems, here are a few that I could spot by eye:

  1. In the nextGeneration method, you handle cases where a cell should stay alive or die, but you do not have anything for when cells should be born. You should have something like this:

    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. This is a minor issue, still in nextGeneration, in if(count==3)live; else if(count <=2 || count > 3) die; is redundant, you only need if(count == 3) live; else die;

let us know, if you still have problems



来源:https://stackoverflow.com/questions/35952931/issue-with-game-of-life-code-method-user-interface-is-complete-but-actual-gol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!