Игра жизни в обработке

Я хочу написать свою собственную версию "игры жизни" в процессе обработки 3, но я столкнулся с ошибкой, которую, похоже, не понимаю. Всякий раз, когда код запускается, экран становится черно-белым с изменением нескольких пикселей, но это не похоже на игру в жизнь.

Любая помощь?

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 ответа

Пожалуйста, отправьте ваш код как MCVE. Когда я пытаюсь запустить ваш код, я получаю сообщение об ошибке, потому что у меня нет файла шрифта, который вы пытаетесь загрузить в строке 59. Этот шрифт не имеет ничего общего с вашей проблемой, поэтому вы должны действительно избавиться от него раньше отправив вопрос.

В этом коде много чего происходит. Я понимаю, почему у вас есть два массива, но их наличие на уровне эскиза только усложняет ваш код. Вам не нужно постоянно переключаться между такими массивами. Вместо этого я бы организовал ваш код следующим образом:

  • У вас должен быть только один массив на уровне эскиза. Вы также можете избавиться от zeroOrOne переменная.
  • Инициализируйте этот массив так, как вы хотите.
  • Создать nextGeneration() который возвращает новый массив на основе текущего массива. Это, вероятно, вызовет другие функции для подсчета соседей и еще много чего. Но дело в том, что вы можете просто создавать новый массив каждый раз вместо переключения между двумя глобальными массивами.
  • Это удалит всю вашу дублированную логику.

Главные примечания:

  • Имея 8 if Заявления для проверки соседей немного излишни. Почему бы просто не использовать вложенные for цикл?
  • Вы должны привыкнуть следовать правилам именования. Функции должны начинаться со строчной буквы, а переменные должны быть описательными check на самом деле ничего не говорит читателю.

Если вы все еще не можете заставить его работать, тогда вам придется выполнить некоторую отладку. добавлять print() операторы, или используйте отладчик редактора обработки для пошагового выполнения кода. Какая линия ведет себя не так, как вы ожидаете? Затем вы можете опубликовать MCVE только этой строки (и любые жестко запрограммированные переменные, необходимые для отображения поведения), и мы пойдем оттуда. Удачи.

Проблемы, с которыми вы сталкиваетесь, имеют два аспекта:

  1. Две ячейки, которые вам мешают, создают две отдельные игры, когда вам нужна только одна.

  2. Вы обновляете ячейки в своих массивах, прежде чем закончите проверять, какие из них необходимо изменить.

Способ решения обеих проблем - переназначить массив cell1. Вместо того, чтобы проверять его каждый раз, сделайте массив полностью установленным в false. Затем, всякий раз, когда вы хотите изменить квадрат в ячейках 0, установите для этого местоположения в ячейках 1 значение true, и после того, как вы сделаете маркер каждой ячейки, которую хотите изменить, измените их все сразу с отдельным циклом for в конце drawLoop() метод. Это решает обе проблемы одним махом.

Как только вы это сделали, вы можете удалить check а также zeroAndOne переменные, так как они вам больше не понадобятся. Это то, что я получил за drawLoop() Метод после внесения изменений я рекомендую:

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

Я уверен, что вы можете выяснить остальное. Удачи!

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