-1

I want to code my own version of "game of life", in processing 3, but I've come across an error I don't seem to understand. Whenever the code run, the screen keeps going black and white with a few pixels changing but it does not look like game of life.

Any help?

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;
}
Raymond Edde
  • 41
  • 1
  • 7
  • "it does not look like game of life" is hardly a description of a problem. Have you tried debugging? Or let it run slower? – f1sh Feb 21 '17 at 16:33
  • That `zeroOrOne` and `cells0` / `cells1` stuff is where I would look. Do you have two different games running at the same time, or something? That would certainly explain the screen seeming to alternate between two different things... Get one running before you try doing two at once. – D M Feb 21 '17 at 16:37
  • I have tried to run it slow, the best description I can give is that the screen goes black in one iteration and then goes back to white with another version of what looks like a game of life. It does this every time – Raymond Edde Feb 21 '17 at 17:01
  • The two arrays are meant two store what the next iteration of the animation should loo like and the zeroOrOne makes that change in the If statement – Raymond Edde Feb 21 '17 at 17:02

2 Answers2

2

Please post your code as an MCVE. When I try to run your code, I get an error because I don't have the font file your'e trying to load on line 59. That font has nothing to do with your problem, so you should really get rid of it before posting a question.

You've got a lot going on in this code. I understand why you have two arrays, but having them both at the sketch level is only over-complicating your code. You shouldn't need to constantly switch between arrays like that. Instead, I would organize your code like this:

  • You should only have one array at the sketch level. You can also get rid of the zeroOrOne variable.
  • Initialize that array however you want.
  • Create a nextGeneration() that returns a new array based on the current array. This will probably call other functions for counting neighbors and whatnot. But the point is that you can just create a new array every time instead of switching between two global arrays.
  • This removes all of your duplicated logic.

General notes:

  • Having 8 if statements to check the neighbors is a bit of overkill. Why not just use a nested for loop?
  • You should get into the habit of following proper naming conventions. Functions should start with a lower-case letter, and variables should be descriptive- naming something check doesn't really tell the reader anything.

If you still can't get it working, then you're going to have to do some debugging. Add print() statements, or use the Processing editor's debugger to step through the code. Which line behaves differently from what you expect? Then you can post an MCVE of just that line (and whatever hard-coded variables it needs to show the behavior) and we'll go from there. Good luck.

Community
  • 1
  • 1
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
0

The issues you are having are twofold:

  1. The two cells arrays that you have interfere and make two separate games, when you only want one.

  2. You are updating the cells in your arrays before you get to the end of checking which ones need to be modified.

The way to solve both problems at once is to repurpose the cells1 array. Instead of checking it every other time, make it an array set entirely to false. Then, whenever you want to modify a square in cells0, set that location in cells1 to true, and after you make a marker of each cell you want to change, change them all at once with a separate for loop at the end of the drawLoop() method. This solves both problems in one fell swoop.

Once you have done this, you can remove the check and zeroAndOne variables, as you won't need them anymore. This is what I got for the drawLoop() method after I made the modifications I recommend:

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();
}

I'm sure you can figure out the rest. Good luck!

Lavaman65
  • 863
  • 1
  • 12
  • 22