1

I am building a game of life CA in C++ (openFrameworks). As I am new to C++ I was wondering if someone could let me know if I am setting up the vectors correctly in the following code. the CA does not draw to the screen and I am not sure if this is as a result of how I set up the vectors. I have to use 1D vectors as I intend to send data to Pure Data which only handles 1D structures.

GOL::GOL() {
    init();
}


void GOL::init() {
  for (int i =1;i < cols-1;i++) {
    for (int j =1;j < rows-1;j++) {
        board.push_back(rows * cols);
        board[i * cols + j] = ofRandom(2);
    }
  } 
}


void GOL::generate() {
  vector<int> next(rows * cols);

  // Loop through every spot in our 2D array and check spots neighbors
  for (int x = 0; x < cols; x++) {
    for (int y = 0; y < rows; y++) {

      // Add up all the states in a 3x3 surrounding grid
      int neighbors = 0;
      for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
          neighbors += board[((x+i+cols)%cols) * cols + ((y+j+rows)%rows)];
        }
      }

      // A little trick to subtract the current cell's state since
      // we added it in the above loop
      neighbors -= board[x * cols + y];

      // Rules of Life
      if ((board[x * cols + y] == 1) && (neighbors <  2)) next[x * cols + y] = 0;        // Loneliness
      else if ((board[x * cols + y] == 1) && (neighbors >  3)) next[x * cols + y] = 0;        // Overpopulation
      else if ((board[x * cols + y] == 0) && (neighbors == 3)) next[x * cols + y] = 1;        // Reproduction
      else next[x * cols + y] = board[x * cols + y];  // Stasis
    }
  }

  // Next is now our board
  board = next;
}
mr. knott
  • 61
  • 2
  • 6
  • 2
    You have a problem in your `init` function: If `board` is a `std::vector` you will write to an out-of-bounds index, always. Remember that the index goes from zero to size-minus-one. So after the first `push_back` you can access index zero, after the second indexes zero and one, etc. In your code the first iteration will access index `cols + j`, which is clearly not valid. – Some programmer dude Mar 15 '13 at 18:23
  • How are you handling edge of board cases in your neighbor check? Ah the modulus - your wrapping your board okay. – Michael Dorgan Mar 15 '13 at 18:26
  • Thanks. I'm translating this from a Processing (java) sketch that uses 2D arrays. I'm away from my machine now, I'll have another look at both programs later, taking your advice into account. – mr. knott Mar 15 '13 at 18:46

1 Answers1

0

this looks weird in your code:

void GOL::init() {
  for (int i =1;i < cols-1;i++) {
    for (int j =1;j < rows-1;j++) {
        board.push_back(rows * cols);
        board[i * cols + j] = ofRandom(2);
    }
  } 
}

"vector.push_back( value )" means "append value to the end of this vector" see std::vector::push_back reference After doing this, you access the value of board[i * cols + j] and change it into a random value. What I think you are trying to do is:

void GOL::init() {
  // create the vector with cols * rows spaces:
  for(int i = 0; i < cols * rows; i++){
      board.push_back( ofRandom(2));
  }

}

This is how you would access every element at position x,y in your vector:

  for (int x = 0; x < cols; x++) { 
    for (int y =  0; y < rows; y++) {
        board[x * cols + y] = blabla;
    }
  } 

This means that in void GOL::generate() you are not accessing the right position when you do this:

      neighbors += board[((x+i+cols)%cols) * cols + ((y+j+rows)%rows)];

I think you want to do this:

      neighbors += board[((x+i+cols)%cols) * rows + ((y+j+rows)%rows)];

so x * rows + y instead of x * cols + y

tim k
  • 162
  • 1
  • 9