标题解释了大部分问题 我有一个由2D数组表示的tile网格。某些图块标记为空(但它们存在于数组中,用于某些继续使用),而其他图块处于正常状态。
我需要做的是,重新排序网格中的剩余(非空)图块,以便所有(或大多数)处于不同的非空位置。如果我只是迭代所有非空位置并用另一个随机交换平铺,我可能已经自动重新排序了许多(交换的)。
所以我想知道是否有一些我可以遵循的技术,以便以最小的循环令人满意地重新排序网格。任何提示?
答案 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)
如果你有一个奇数个元素,那么剩下的就会与列表中的任何其他元素交换。