At a loss and sure what to do

Im trying to build a very basic cellular automata program for a school assignment. I need to draw a grid, randomly “infect” a cell and then it needs to spread out from there. In my current code i can draw the grid, infect the cell and then it does nothing. i managed to get this working as a 2d array, but the prof wants it done without it being a 2d array.

Im not sure why that after it the program starts it won’t spread the “infection”.

final int SIZE = 500;//size of canvas
final int SIDE_LENGTH = 10;//number of cells
final int CELL = SIZE/SIDE_LENGTH;//setting cell size
final int infected = 1;//indicates infected cells
int healthy = 0;
color[] infectionColor = {color(0, 0, 0), color(255, 0, 0)};//color array
int[] gridX = new int [SIDE_LENGTH];//random x variable
int[] gridY = new int [SIDE_LENGTH];//random y variable
int[] tempGridX;//temporary x array
int[] tempGridY;//temporary y array
int x = int(random(SIDE_LENGTH));//randomly chooses an X coordinate
int y = int(random (SIDE_LENGTH));//randomly chooses a Y coordinate


void setup()
{
  size (500, 500);
  stroke(255);
  frameRate(2);
}

void draw()
{ 
  drawBoard();//draws board
  infectRandom();//randomly infects a cell
  spreadInfection();//spreads the infection
  deepSave();//deep saves the status at end of loop
}

void drawBoard()
{
  for (int i = 0; i<SIDE_LENGTH; i++) {
    for (int j = 0; j<SIDE_LENGTH; j++) {
      gridX[x] = healthy;//sets unifected cells to 0
      gridY[y] = healthy;//sets unifected cells to 0
      if (gridX[x]==healthy && gridY[y]==healthy) {
        fill (infectionColor[0]);
      } else if (gridX[x]==infected && gridY[y]==infected) {
        fill (infectionColor[1]);
      }
      rect (i*CELL, j*CELL, CELL, CELL);
    }
  }
}


void infectRandom()
{
  //Randomly infects a cell at the beginning of the program
  if (gridX[x]==healthy && gridY[y]==healthy) {
    for (int i = 0; i<SIDE_LENGTH; i++) {
      for (int j = 0; j<SIDE_LENGTH; j++) {
        infect(x, y);
        println ("found infected thing at"+i+ +j);
      }
    }
  }
}


void infect(int i, int j)
{
  //infects a cell
  gridX[i]= infected;//changes x coordinate to infected
  gridY[j]= infected;//changes y coordinate to infected
  fill (infectionColor[1]);//cells now drawn in infected color
  rect (i*CELL, j*CELL, CELL, CELL);
}

void spreadInfection()
{
  //Spreads infection throughout program
  for (int i = 1; i<SIDE_LENGTH-1; i++) {
    for (int j = 1; j<SIDE_LENGTH-1; j++) {
      if (gridX[i]==infected && gridY[j] == infected)//if cell i&j are infected
      {
        if (gridX[i-1]==healthy && gridY[j]==healthy)
          //if cell i-1&j are healthy
        {
          infect(i-1, j);//then infect
        }
        if (gridX[i+1]==healthy && gridY[j]==healthy)
          //if cell i+1&j are healthy
        {
          infect(i+1, j);//then infect
        }
        if (gridX[i]==healthy && gridY[j-1]==healthy)
          //if cell i&j-1 are healthy
        {
          infect(i, j-1);//then infect
        }
        if (gridX[i]==healthy && gridY[j+1]==healthy)
          //if cell i&j+1 are healthy
        {
          infect(i, j+1);//then infect
        }
      }
    }
  }
  tempGridX=gridX;//shallow save into temporary array x variable
  tempGridY=gridY;//shallow save into temporary array y variable
}

void deepSave()
{
  //Deep save of game information back into original array
  tempGridX = new int[gridX.length];
  tempGridY = new int[gridY.length];
  for (int i =0; i<gridX.length; i++) {
    for (int j = 0; j<gridY.length; j++) {
      tempGridX[i] = gridX[i];//deep save of temporary x variable into original array
      tempGridY[j] = gridY[j];//deep save of temporary y variable into original array
    }
  }
}
1 Like

Consider this sample 2D array.

There are 5 highlighted squares. If the central (red) one is cell (i, j), then the four surrounding it have the relative positions in color.

You can represent this 2D array in a 1D array. Just have each row in order. How long is the 1D array in terms of the 2D array’s width and length? Can you see how the two values that are the position of a Cell in the 2D array can be used to determine the Cell’s position in the 1D array?

1 Like

sorry, i think you’ve confused me. When it was a 2d array it was setup as grid[][], which was then rewritten as grid[x] grid[y], but for some reason it now doesn’t want to change around the “infected” cell. The cell size is still the same and the new array should be the same length and width as it was in a 2d array.

From your example i understand the positioning of the infected cell being (i,j) and the cell to the right of that would be (i+1,j). When i run the println, it seems to show them all as infected.

Been working on this for over a week now and its becoming super frustrating, as its due next weekend and still need the second part of the assignment done, which i can’t do until i can get this one figured out…

The concept of not using array is challenging because it force to approach your problem using another model. Before you try to address the second part of the assignment, or even to spread a disease of a cell, you need to understand your model. If you are instructed not to use a 2D array, then what options do you have?

Working 2D in 1D is possible. You just need to get some experience and make an effort to understand it. Just using pen and paper, set a non-square grid and try to figure out how to access each cell individually. For instance, if you have a grid of 3x6 - aka. 3 rows and 6 columns, how would you represent this as a 1D array? What should its size be?

Right now what I see in your code, you have

int[] gridX = new int [SIDE_LENGTH];//random x variable
int[] gridY = new int [SIDE_LENGTH];//random y variable

Unfortunately, this is not enough to store your data. For once, you can only stored 20 elements in this array. Why 20? Each array has a size of 10 (final int SIDE_LENGTH = 10;) so two arrays together can store 10+10 cells. If we were to do in a 2D array, you will have a table of 10 x 10, meaning you can store 100 cells. You see, you need a 1D structure that can store 100 cells, not 20.

How to convert a 2D into 1D array. I cannot explain that here in detail, as I believe there are clear concise guides out there showing how to do that. You need a function that can access any cell at any time. This is very trivial with 1D arrays.

The next challenge is, to write a function that is able to get all the cells around a specific cell x,y. In other words, you need a function that takes a position in your 1D array, and it is able to return all the cells around this position. It will return the indices. In the example above, if I ask for what cells are around the RED cell, the function will return 8 indices corresponding to 4 white cells, blue, orange, green and yellow cell. Why do you need this?

I believe when you start spreading the disease, you will need to access this indices. From these, you would tell who is healthy around a specific cell. If any of them are healthy, then on one cycle, they have a chance to catch the disease. (This is how diseases spread by the way: by being close/next to an infected coupled to a chance to get infected)

What could you do next? First,you need to convince yourself that a 1D array could be way to proceed here. I suggest you start from scratch.

First challenge:

  1. Draw a 1D array as a 2D grid
  2. Draw each row with a unique color
  3. Can you draw each column with a unique color?
  4. Randomly sprinkle some disease cells on your grid by working directly with the 1D array. By using an user event (either a mouse clicked or pressing a specific button - r for reset or the space bar) generate a new random table with a mix of healthy and disease cells

Can you do that?

While you work on this first part, you can also tell us about how you will spread the infection. What approach will you use? I was guessing what you were doing. However, it is better if you describe it as you are the designer of this code.

I hope this helps,

Kf

2 Likes

Speaking about using a 1D array to represent a 2D 1, I’ve got this Java Mode sketch using 2D arrays: :grinning:

Which when I’ve converted it to p5.js, I’ve decided to flatten them as 1D arrays: :crazy_face:

Thankyou for the advice, its given me a lot to think about, ive already started rewriting as a 1d and changed the array size to reflect this.

I started rebuilding it all and im jsut providing the basics of what i have now. I have the grid being drawn, it finds a random cell to infect, it infects that random cell and the rest of the column that its in…

final int SIZE = 500;//size of canvas
final int SIDE_LENGTH = 10;//number of cells
final int CELL = SIZE/SIDE_LENGTH;//setting cell size
color[] infectionColor = {color(0, 0, 0), color(255, 0, 0)};//color array
int[] grid = new int [SIDE_LENGTH*SIDE_LENGTH];//grid array
int[] tempGrid;//temporary grid array
int randomCell = int(random(SIDE_LENGTH));//randomly chooses a cell
int infected = 1;//sets cell value to 1

void setup()
{
  size (500, 500);//sets size of canvas
  stroke(255);//white grid outline
  frameRate(2);//framerate to 2 to slow down program
}

void draw()
{ 
  drawBoard();//draws board
  infectRandom();//infects random cell
}

void drawBoard()
{
  for (int i = 0; i<SIDE_LENGTH; i++) {
    for (int j = 0; j<SIDE_LENGTH; j++) {
      if (grid[i] != infected && grid[j] != infected) {
        fill (infectionColor[0]);//sets healthy color to black
      } else if (grid[i] == infected && grid[j]==infected) {
        fill (infectionColor[1]);//sets infected color to red
      }
      rect (i*CELL, j*CELL, CELL, CELL);//draws grid
    }
  }
}


void infectRandom()
{
  if (grid[randomCell]!=infected) {
    infect (randomCell);
  }
}

void infect (int i)
{
  grid[i] = infected;//sets cell value to 1
  fill (infectionColor[1]);//changes cell color to red
}`Preformatted text`
1 Like

Hi @NNY

You can’t just use i and j the way you used them.

Since you transformed your 2D grid into a 1D one, you need a formula that transform the (i, j) coordinates into the index where that square is stored in your 1D array. The figure that @TfGuy44 posted is showing you that transformation.

To sum up, if you want to access the square at the (i, j) position of your grid, you need to access the element in the index: idx = i + j * width.

That explain why you have that red line. You are actually infecting only 1 cell but when you are doing your check:
if (grid[i] == infected && grid[j]==infected)
You check the wrong cell since you are not using the formula above.

2 other things to note:

  • You are defining your random number in the global scope so it will always be the same.
  • You are infecting a “random” cell on every frame - I don’t think that is what you want. You should put your code in the setup() function to set up you grid and then in the draw() function spread the infection.
2 Likes

I know im definitely in over my head with this course, right now its just get it done.
The prof doesn’t want drawBoard() and infectRandom() in the setup() function. The infectRandom() only needs to be called once at the beginning of the program and then there will be another function to spread the infection. I had this working on a 2D array, but again the prof wants it on a 1D array, the frustrating part is getting it to work.

Im going to go back and play with the suggestion you made and that TFGuy44 made.

Thank you!!

I wrote this code to show you how the 1D array is related to the 2D one:

int[][] twoD = { {1, 2, 3}, 
                 {4, 5, 6}, 
                 {7, 8, 9} };
int[] oneD = {1, 2, 3, 4, 5, 6, 7, 8, 9};


void setup()
{
  println("The following list is obtained with the 2D array:");
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      println(twoD[i][j]);
    }
  }
  
  println("");
  println("The following list is obtained with the 1D array:");
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      println(oneD[i + j * 3]); //3 is the width of the 2D array
    }
  }
}

The structures are the same in both case. The only difference is on how you access the elements. With the 2D array you simply get the (i, j) element and for the 1D array you need to compute an index relative to the i and j value.

3 Likes

This is what i have now, it only infects the one cell, now i need to be able to reference that index to be able to spread the infection.

final int SIZE = 500;//size of canvas
final int SIDE_LENGTH = 10;//number of cells
final int CELL = SIZE/SIDE_LENGTH;//setting cell size
color[] infectionColor = {color(0, 0, 0), color(255, 0, 0)};//color array
int[] grid = new int [SIDE_LENGTH*SIDE_LENGTH];//grid array
int[] tempGrid;//temporary grid array
int randomCell = int(random(SIDE_LENGTH*SIDE_LENGTH));//randomly chooses a cell
int infected = 1;//sets cell value to 1

void setup()
{
  size (500, 500);//sets size of canvas
  stroke(255);//white grid outline
  frameRate(2);//framerate to 2 to slow down program
}

void draw()
{ 
  drawBoard();//draws board
  infectRandom();//infects random cell
}

void drawBoard()
{
  for (int i = 0; i<SIDE_LENGTH; i++) {
    for (int j = 0; j<SIDE_LENGTH; j++) {
      int index = grid[i+j*SIDE_LENGTH];//infected square
      
      if (index != infected) {
        fill (infectionColor[0]);//sets healthy color to black
      } else if (index == infected) {
        fill (infectionColor[1]);//sets infected color to red
      }
      println(grid[i+j*10]);
      rect (i*CELL, j*CELL, CELL, CELL);//draws grid
    }
  }
}

void infectRandom()
{
  if (grid[randomCell]!=infected) {
    infect (randomCell);
  }
}

void infect (int i)
{
  grid[i] = infected;//sets cell value to 1
}

If you know the i and j for a cell in the 2D grid, you can find the index for that cell in the 1D array.

But you can also reverse this process!

If you know an index in the 1D array, you can work out which cell that is in the 2D array!

int i = index % width;
int j = index / width;

Do NOT just blindly use this equations like they are magic! LOOK AT THEM! Think about how they work! If the grid is a 3 by 3, the center cell has index 4. How does index 4 give you i and j values of 1? 4 % 3 is 1. Is 4 / 3 also 1? How about the center space on the last row? Index 7. What is 7%3? What is 7/3?

2 Likes

Hey!! I think we are working on the same assignment, or at least it must be very similar. I’ve taken a different approach then you.

Like you, I am suffering through this though and cannot wait for it be done. I made my grid of cells using a 1d array and then called a random cell to infect.

I really have nothing helpful to add. I just wanted to say 'I feel your pain". This course is way harder then how it was described to me.

Best of luck to you.