使用图块地图阵列随机重新排序剩余图块位置的逻辑

时间:2011-12-27 18:42:59

标签: algorithm grid permutation tiles

标题解释了大部分问题 我有一个由2D数组表示的tile网格。某些图块标记为空(但它们存在于数组中,用于某些继续使用),而其他图块处于正常状态。

我需要做的是,重新排序网格中的剩余(非空)图块,以便所有(或大多数)处于不同的非空位置。如果我只是迭代所有非空位置并用另一个随机交换平铺,我可能已经自动重新排序了许多(交换的)。

所以我想知道是否有一些我可以遵循的技术,以便以最小的循环令人满意地重新排序网格。任何提示?

2 个答案:

答案 0 :(得分:2)

public void RandomizeGrid<T>(T[,] grid, Func<T,bool> isEmpty)
{
    // Create a list of the indices of all non-empty cells.  
    var indices = new List<Point>();
    int width = grid.GetLength(0);
    int height = grid.GetLength(1);
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            if (!isEmpty(grid[x,y])) // function to check emptiness
            {
                indices.Add(new Point(x,y));
            }
        }
    }

    // Randomize the cells using the index-array as displacement.
    int n = indices.Count;
    var rnd = new Random();
    for (int i = 0; i < n; i++)
    {
        int j = rnd.Next(i,n); // Random index i <= j < n
        if (i != j)
        {
            // Swap the two cells
            var p1 = indices[i];
            var p2 = indices[j];
            var tmp = grid[p1.X,p1.Y];
            grid[p1.X,p1.Y] = grid[p2.X,p2.Y];
            grid[p2.X,p2.Y] = tmp;
        }
    }
}

答案 1 :(得分:0)

它是否满足您的需求(“令人满意”有点模糊)以确保每次非空的瓷砖与另一个非空瓷砖交换一次?

说你有一个清单:

(1,4,7,3,8,10)

我们可以写下列表的标记

(0,1,2,3,4,5)

并对指数进行N次随机交换以对其进行混洗 - 可能有些数字会移动,有些则不会。

(5,1,3,2,4,0)

然后将这些成对顺序作为一系列交换在我们的原始列表中执行。

(8,10,3,7,1,4)

如果你有一个奇数个元素,那么剩下的就会与列表中的任何其他元素交换。