I have an array of colors that will populate a pie chart to act as a game spinner. I don\'t want the same colors to appear next to each other, making one huge chunk in the c
The GKShuffledDistribution class in GameplayKit has two features that should make fulfilling this requirement pretty easy:
It draws "random" numbers from the range it's initialized with in such a way that it must use all the numbers in that range before repeating any one of them.
Alone, this behavior creates "chunks" (for lack of a better word) in the random sequence. For example, if you have 4 possible values, the first four nextInt()
calls would exhaust all four of them. But on the fifth call you're on a new "chunk", you'd be able to randomly get any of the 4 values again, including the final value from the last "chunk".
So, GKShuffledDistribution
also makes sure that there aren't any repeats across "chunk" boundaries.
You can see this pretty easy by trying the following in a playground, and showing a value graph for the nextInt()
line:
import GameplayKit
let colors = ["red", "green", "blue"
// the effect is easier to see with more than three items, so uncomment for more:
// , "mauve", "puce", "burnt sienna", "mahogany",
// "periwinkle", "fuschia", "wisteria", "chartreuse"
]
let randomizer = GKShuffledDistribution(lowestValue: 0, highestValue: colors.count - 1)
for _ in 1...100 {
randomizer.nextInt()
}
Or with more colors:
You'll notice that some values get repeated with a skip in between (note the sequence of 11, 10, 11
early on in the second graph), but never is one value repeated consecutively.
To use this to shuffle an array of colors, just work from a shuffled index:
extension GKShuffledDistribution {
func shuffledInts(count: Int) -> [Int] {
// map on a range to get an array of `count` random draws from the shuffle
return (0..
(Also showing a couple of other things in this example: using color literals instead of color names, though you could just as well do either, and using the dieWithSideCount
initializer for GKShuffledDistribution
. Note that color literals look a lot nicer in Xcode than on the web in SO.)