2011-12-27 39 views
1

標題解釋了大部分問題。
我有一個由二維數組表示的平鋪網格。某些圖塊被標記爲空(但它們存在於數組中,對於某些繼續使用),而其他圖塊則處於正常狀態。使用瓷磚貼圖陣列隨機重新排列剩餘瓷磚位置的邏輯

我需要做的是對網格中的剩餘(非空)瓦片進行重新排序,以便所有(或大部分)不同的非空位置。如果我只是遍歷所有非空的位置,並用另一個隨機的交換瓦片,我可能已經自動重新排序它們中的很多(交換的)。

所以我想知道是否有一些技術我可以遵循,以最小的循環令人滿意地重新排序電網。任何提示?

+1

瓷磚需要如何隨機交換?如果隨機性不重要,你可以通過用2代替1,用3代替N,用N代替N。如果隨機性很重要,那麼你試圖找到一個**錯亂* *的原始瓷磚,並希望隨機生成一個。 – templatetypedef 2011-12-27 18:47:28

+0

是的,** **是我想要的!我想知道是否可以在原地進行,而不是保存非空的瓷磚並隨機分配。然後再次,我只能使用非空位置,所以從地圖中選取一個隨機點並檢查它是否爲空可能會造成很多無效的檢查。 – eternalthinker 2011-12-27 19:02:52

回答

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

它會滿足您的需求(「滿意」有點模糊),以確保每個非空磁磚與另一個非空磁磚交換一次?

假設你有一個清單:

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

我們可以寫下列表

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

的indicies和指標進行N次隨機掉期洗牌它 - 也許一些數字移動,有些不。

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

然後將這些配對作爲交換序列在我們的原始列表上執行。

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

如果您有奇數個元素,剩餘元素將與列表中的任何其他元素進行交換。

+0

我正在處理二維數組。關於如何隨機化2D索引(非空)的任何想法? – eternalthinker 2011-12-27 19:06:29

+0

事實上,他們是在一個2D陣列旁邊的觀點。他們只是有地方的東西。 – Mikeb 2011-12-27 20:08:57