2017-04-13 49 views
1

有20個紅球坐在4個貨架上的20個位置上。我想通過生成一個包含所有20個球的新位置的新陣列,將每個球移動到自己貨架上的新位置。我正在使用一個函數(如下),允許我這樣做。但是,我發現這個功能不斷崩潰;當我輸出正在生成的值時,它似乎掛在可用位置的最後一個座標處,但不會退出「while」循環。通過創建陣列交換節點位置來實現無限循環

func generateNewLocationArray(previous: [String: CGPoint]) -> [String : CGPoint] { 
    var refreshedLocations = [String : CGPoint]() 
    for (location, _) in previous { 
     let node = fgNode.childNode(withName: location) as? LocationNode 
     var newLocation = generateRandomLocation(check: refreshedLocations) 
     let previousLocation = previous[(node?.name!)!] 
     while (newLocation == previousLocation) || (newLocation.y != previousLocation?.y) { 
      newLocation = generateRandomLocation(check: refreshedLocations) 
     } 
     node?.position = newLocation 
     refreshedLocations[location] = newLocation 
    } 
    return refreshedLocations 
} 

我想要實現:

  1. 該函數將在CGPoints的數組,這是「以前的」 陣列的位置,所有的球都是的。
  2. 然後創建一個全新的數組,名爲「刷新位置」。
  3. 它加載一個現有節點,該節點位於前一個數組中包含的位置。
  4. 然後它爲該節點生成一個新位置。該位置是從20個位置的預設陣列中獲得的。這個新位置不能與節點當前位置相同;也不能有不同的y座標(所以球停留在架子上)。
  5. 在滿足這個標準之前,它不斷產生一個新的位置。
  6. 然後,它將這個位置加載到refreshedLocations數組中,並且還檢查下一個節點,以確保沒有重複的位置。

問題再次出現:此代碼適用於10個或15個球。但是當數字被推到20時,它似乎更有可能掛起。它將確定如何將所有的球移動到新的位置,但它經常卡在「while」循環中。這裏有什麼問題?

編輯:這是返回一個隨機位置的函數,但首先檢查正在生成的數組是否已經包含正在添加的點。

func generateRandomLocation(check: [String : CGPoint]) -> CGPoint { 
    let randomIndex = GKRandomDistribution(lowestValue: 0, highestValue: allPositions.count - 1) 
    var position = allPositions[randomIndex.nextInt()] 
    while check.values.contains(position) { 
     position = allPositions[randomIndex.nextInt()] 
    } 
    return position 
} 
+0

需要查看'generateRandomLocation'函數。 – ebby94

+1

顯示generateRandomLocation(檢查:)的代碼。我懷疑你的算法有缺陷。如果一個架子上的四個球互換了位置,那麼第五個球就沒有地方了。剩下的唯一地方就是現在坐的地方,這是不允許的。 – vacawama

+0

已在上面添加 - 謝謝!另外,如果你確定了這個缺陷,那麼知道如何解決這個問題將會很有幫助。 – illuminatedtype

回答

2

據我所看到的,

while (newLocation == previousLocation) || (newLocation.y != previousLocation?.y) 

總是會,如果你到某行的唯一位置左邊的最後一球是真的是一個它已經英寸你可以通過檢測貨架上有多少個位置已經被填充,並且如果它是n-1,並且剩下的唯一位置是球所在的位置,只需將它與隨機選擇的另一個球交換架。

但是,必須有更好的方法來做到這一點。我會嘗試修改Fisher Yates shuffle

首先,通過架子和位置組織球。然後,對於n球的每個架子(編號0到n - 1)

  • 從第一n選擇隨機球 - 2個球,並用球Ñ交換它 - 1
  • 從選擇隨機球第一n - 3個球和交換它與球N - 2
  • 從第一n選擇隨機球 - 4個球,並用球交換ñ它 - 3

等。當隨機選擇從0球時停止。在這個過程結束時,所有的球都會改變位置。

重複每個貨架。

+0

非常好,謝謝你向我推薦「Fisher Yates shuffle」。 – illuminatedtype