处理中的生命游戏

时间:2017-02-21 16:29:34

标签: java animation processing conways-game-of-life cellular-automata

我想在处理3中编写我自己的生活游戏版本#34;但是我遇到了一个我似乎无法理解的错误。每当代码运行时,屏幕会一直变为黑白,只有几个像素在变化,但它看起来不像生活游戏。

任何帮助?

int windowW, windowH, percentAlive, gen; 
//windowW is the width of the window, windowH is the height
//percentVlive is the initial percent of alive pixel  
//gen is the counter for the generation
color alive, dead;//alive is white and dead is black to represent their respective colors
boolean[][] cells0, cells1;//two arrays for the state of the cells, either alive or dead
boolean zeroOrOne = true;//this is to check which array should be iterated over

void setup() {
  size(700, 700);

  int width = 700;
  int height = 700;

  windowW = width;
  windowH = height;

  percentAlive = 15;

  alive = color(255, 255, 255);
  dead = color(0, 0, 0);

  cells0 = new boolean[width][height];
  cells1 = new boolean[width][height];

  frameRate(2);

  background(alive);

  for (int x=0; x<width; x++) {//set the percent of live pixels according to the precentAlive varriable
    for (int y=0; y<height; y++) {
      int state = (int)random (100);
      if (state > percentAlive) 
        cells0[x][y] = true;
      else 
      cells0[x][y] = false;
    }
  }
}



void draw() {
  gen += 1;//increases the generation every time it draws
  drawLoop(zeroOrOne);
  WriteGeneration(gen);

  if(zeroOrOne){//changes the zeroOrOne value  to change the array being iterated over
    zeroOrOne = false;
  }
  else {
   zeroOrOne = true; 
  }
}

void WriteGeneration(int number) {//changes the label on top
  fill(0);
  rect(0, 0, windowW, 100);
  fill(255);
  textFont(loadFont("BerlinSansFB-Reg-100.vlw"));
  text("Generation " + number, 10, 90);
}

void drawLoop(boolean check) {
  loadPixels();
  if (check) {//checks which array to iterate thrgough

    for (int x = 0; x < windowW; x++) {//iterates through the array
      for (int y = 0; y < windowH; y++) {
        if (cells0[x][y]) {//checks wether the pixel is alive or dead
          pixels[x * 700 + y] = alive;//gets the current pixel
          int lives = lives(x, y, check);//checks how many cells are alive around the current cell

          if (lives<2) {//these are supposed to put in place the game of life rules
            cells1[x][y] = false;
          } else if (lives>4) {
            cells1[x][y] = false;
          } else {
            cells1[x][y] = true;
          }
        } else {
          pixels[x * 700 + y] = dead;//gets the current pixel
          int lives = lives(x, y, check);//checks how many cells are alive around the current cell
          if (lives == 3) {//turns the pixel alive if the condition is met
            cells1[x][y] = true;
          }
        }
      }
    }
  } else {//the same as the top but instead the arrays being updated and read are switched

    for (int x = 0; x < windowW; x++) {
      for (int y = 0; y < windowH; y++) {
        if (cells1[x][y]) {
          pixels[x * 700 + y] = alive;
          int lives = lives(x, y, check);
          if (lives<2) {
            cells0[x][y] = false;
          } else if (lives>4) {
            cells0[x][y] = false;
          } else {
            cells0[x][y] = true;
          }
        } else {
          pixels[x * 700 + y] = dead;
          int lives = lives(x, y, check);
          if (lives == 3) {
            cells0[x][y] = true;
          }
        }
      }
    }
  }
  updatePixels();
}

int lives(int x, int y, boolean check) {//this just checks how many live pixels are around a given pixel
  int lives = 0;
  if (x > 1 && y >1 && x < 699 && y < 699) {
    if (check) {
      if (cells0[x-1][y-1])
        lives++;
      if (cells0[x][y-1])
        lives++;
      if (cells0[x+1][y-1])
        lives++;
      if (cells0[x-1][y])
        lives++;
      if (cells0[x+1][y])
        lives++;
      if (cells0[x-1][y+1])
        lives++;
      if (cells0[x][y+1])
        lives++;
      if (cells0[x+1][y+1])
        lives++;
    } else {
      if (cells1[x-1][y-1])
        lives++;
      if (cells1[x][y-1])
        lives++;
      if (cells1[x+1][y-1])
        lives++;
      if (cells1[x-1][y])
        lives++;
      if (cells1[x+1][y])
        lives++;
      if (cells1[x-1][y+1])
        lives++;
      if (cells1[x][y+1])
        lives++;
      if (cells1[x+1][y+1])
        lives++;
    }
  }
  return lives;
}

2 个答案:

答案 0 :(得分:2)

请将您的代码发布为MCVE。当我尝试运行您的代码时,我收到错误,因为我没有您尝试在第59行加载的字体文件。该字体与您的问题无关,所以您应该得到在发布问题之前将其删除。

您已经在此代码中进行了大量工作。我理解为什么你有两个数组,但在草图级别同时使用它们只会使你的代码过于复杂。您不应该像这样在阵列之间不断切换。相反,我会像这样组织你的代码:

  • 您应该只在素描级别有一个数组。您还可以删除zeroOrOne变量。
  • 根据需要初始化该数组。
  • 创建一个nextGeneration(),根据当前数组返回一个新数组。这可能会调用其他函数来计算邻居和诸如此类的东西。但关键是你每次都可以创建一个新数组,而不是在两个全局数组之间切换。
  • 这将删除所有重复的逻辑。

一般说明:

  • 有8个if语句来检查邻居有点矫枉过正。为什么不使用嵌套的for循环?
  • 你应养成遵循正确命名惯例的习惯。函数应该以小写字母开头,变量应该是描述性的 - 命名check并不能真正告诉读者任何东西。

如果仍然无法使其正常工作,那么您将不得不进行一些调试。添加print()语句,或使用Processing编辑器的调试器来逐步执行代码。哪条线的行为与您的预期不同?然后你可以发布一行MCVE(以及显示行为所需的任何硬编码变量),我们将从那里开始。祝你好运。

答案 1 :(得分:0)

您遇到的问题有两个:

  1. 当您只想要一个游戏时,你会干扰两个单元格并进行两个单独的游戏。

  2. 在检查需要修改哪些单元格之前,您正在更新数组中的单元格。

  3. 立即解决这两个问题的方法是重新利用cells1数组。而不是每隔一次检查它,使它成为一个完全为false的数组。然后,每当你想修改cells0中的一个方块时,将cells1中的那个位置设置为true,并在你想要改变的每个单元格的标记之后,在{的末尾用一个单独的for循环一次更改它们。 {1}}方法。这一举解决了这两个问题。

    完成此操作后,您可以删除drawLoop()check变量,因为您不再需要它们了。这是我在推荐修改后的zeroAndOne方法所得到的:

    drawLoop()

    我相信你可以弄明白其余的。祝好运!