一次评估所有值的for循环?
For loop that evaluates all values at once?
所以我有一个元胞自动机,我可以在图像上放置像素,每个像素只向下移动一个像素 "tick"。现在的问题是因为 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:如果您有更好的问题标题,请告诉我
假设您已经在内部 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--)
{
}
}
}
}
您需要两个单元格副本。在伪代码中:
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 个缓冲区,您始终拥有一个在计算下一个状态期间不会更改的源缓冲区。
所以我有一个元胞自动机,我可以在图像上放置像素,每个像素只向下移动一个像素 "tick"。现在的问题是因为 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:如果您有更好的问题标题,请告诉我
假设您已经在内部 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--)
{
}
}
}
}
您需要两个单元格副本。在伪代码中:
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 个缓冲区,您始终拥有一个在计算下一个状态期间不会更改的源缓冲区。