-1

So i have a cellular automaton, where i can place pixels on an image and they just move down one pixel each "tick". Now the problem is since the for loop is like this:

for(int x = 0; x < 100; x++){
   for(int y = 0; y < 100; y++){
     //Check if nothing below (x,y) pixel and move it down if so
   }
}

Then the pixels get teleported to the bottom because they get moved down every iteration of the y loop. I solved it by making the y loop go from 100 down to 0 instead of 0 to 100, so its iterating upwards but it wont work if i want to make my pixels move upwards in certain situations.

Maybe a double loop where it makes a list of which pixels to move and where in the first one and actually do it in the second but that seems quite performance heavy and im sure there is a better solution

PS: if you have a better title for the question, let me know

Luka Kostic
  • 314
  • 3
  • 12
  • Where are you using a "tick"? Is that inside or outside of these for loops? – gunr2171 Jul 31 '18 at 19:36
  • 3
    Sorry, I'm unable to understand your question, but for the record your title is definitely not optimal. I mean a loop can't possibly evaluate all iterations at once since it is actually its purpose to **_iterate_**. – scharette Jul 31 '18 at 19:36
  • So essentially your problem boils down to: you want to have an increasing for loop for y in some cases and a decreasing for loop for y in others? – Sach Jul 31 '18 at 19:37
  • Can you explain more about what you are trying to do? It's not clear and your code is definitely not doing what you want, so it's hard to backward engineer. – JNevill Jul 31 '18 at 19:37

2 Answers2

0

Would something like this work, assuming you've got what you want to do inside the inner for loop correct?

static void MovePixels(bool moveUp)
{
    for (int x = 0; x < 100; x++)
    {
        if (moveUp)
        {
            for (int y = 0; y < 100; y++)
            {
            }
        }
        else
        {
            for (int y = 100; y > 0; y--)
            {
            }
        }
    }
}
Sach
  • 10,091
  • 8
  • 47
  • 84
0

You need two copies of the cells. In pseudo code:

int[] currentCells = new int[...];
int[] nextCells = new int[...];

Initialize(currentCells);
while (true) {
    Draw(currentCells);
    Calculate next state by using currentCells as source and store result into nextCells;

    // exchange (this copies only references and is fast).
    var temp = currentCells;
    currentCells = nextCells;
    nextCells = temp;
}

Note that we loop through each cell of the destination (nextCells) to get a new value for it. Throughout this process we never look at the cells in nextCells, because these could be moved ones already. Our source is strictly currentCells which now represents the previous (frozen) state.

// Calculate next state.
for(int x = 0; x < 100; x++){
    for(int y = 0; y < 100; y++){
        if(currentCells[x, y] == 0 && y > 0) { // Nothing here
            // Take value from above
            nextCells[x, y] = currentCells[x, y - 1];
        } else {
            // Just copy
            nextCells[x, y] = currentCells[x, y];
        }
    }
}

In Conway's Game of Life, for instance, you calculate the state of a cell by analyzing the values of the surrounding cells. This means that neither working upwards nor downwards will work. By having 2 buffers, you always have a source buffer that is not changed during the calculation of the next state.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • accepted as answer, but shouldnt there be another if in "currentCells[x, y] == 0 && y > 0" so it doesnt overwrite if any cell is already in nextCells (if one is moving up and another down) – Luka Kostic Jul 31 '18 at 21:56
  • No, because we ignore the previous values already in `nextCells` and calculate the new ones from looking at `currentCells` only. `currentCells` now acts as previous cells. So the actual cell (at `[x, y]`) is taken from `currentCells`. If `currentCells[x, y]` is empty, this means that indeed we have an empty position. – Olivier Jacot-Descombes Aug 01 '18 at 12:40