For循环可一次评估所有值?

时间:2018-07-31 19:31:59

标签: c# cellular-automata

因此,我有一个蜂窝自动机,可以在其中将像素放置在图像上,并且每个“刻度”仅向下移动一个像素。现在的问题是因为for循环是这样的:

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
   }
}

然后,像素被传送到底部,因为它们在y循环的每次迭代中都向下移动。我通过使y循环从100降低到0而不是0到100来解决它,因此它向上迭代,但是如果我想在某些情况下使像素向上移动,它将无法正常工作。

也许是一个双循环,它在其中列出了要移动的像素以及在第一个像素中要移动的位置,并在第二个像素中实际执行的操作的列表,但这看起来性能相当沉重,并且肯定有更好的解决方案

PS:如果您对这个问题有更好的标题,请告诉我

2 个答案:

答案 0 :(得分:0)

假设您已在内部for循环内完成了您想做的事情,这样的工作会成功吗?

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--)
            {
            }
        }
    }
}

答案 1 :(得分:0)

您需要两个单元格副本。用伪代码:

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

请注意,我们遍历目标(nextCells)的每个单元格以获得新值。在整个过程中,我们永远不会查看nextCells中的单元格,因为它们可能已经被移动了。严格来说,我们的来源是currentCells,它表示先前的(冻结)状态。

// 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];
        }
    }
}

例如,在Conway's Game of Life中,您可以通过分析周围单元格的值来计算单元格的状态。这意味着向上或向下工作均无效。通过拥有2个缓冲区,您将始终拥有一个在计算下一个状态时不会更改的源缓冲区。