I always hear how it is hard to implement shuffle algorithms for music players, but never really the explanation for it. What makes it hard?
Take for example how I would implement one:
- First the user adds 5 songs to a playlist
let songs = [0, 1, 2, 3, 4];
- Then the user enables shuffle
- The program would then copy the
songs
array into a new array, sayshuffle
- Then the
shuffle
array would be randomly sorted with any algorithm - The
shuffle
array is stored in eg. a text file for persistence, which is loaded at session start - Let's say, the
shuffle
array is now[2, 4, 0, 1, 3]
- Then the player plays this array in reverse order
-
When a song is played, it is removed from
shuffle
array. Eg.// shuffle starts as [2, 4, 0, 1, 3] while (shuffle.length > 0) { player.play(shuffle[shuffle.length - 1]); shuffle.pop(); } // First iteration plays song 3, and the array is then: [2, 4, 0, 1] // The second plays song 1, and the array is then: [2, 4, 0] // Third plays song 0, and the array is then: [2, 4] etc.
-
Then when all songs have been played, a new array would be again randomly generated from
songs
, which could have had new songs added to it. Maybe even say a couple of songs before the last one, so that the new array is ready by the time the previous one finishes. - You could even stop play and resume later, and you would still only hear songs that have not yet been played, since they are not yet removed from
shuffle
Even if someone has 20000 songs, the array would only be (given it references by integer index) a 125 KB file.
Best Answer
Shuffle is hard for music players because what people understand as random and what random actually means are two different things. The difficulty comes in matching user expectations. Users will say their expectation is songs randomly selected, but there are many things they don't want from a random selection. There is nothing really wrong with your outline for randomly shuffling a playlist, other than it doesn't really meet users expectations of shuffle.
Users really want something like a curated playlist that cycles through their collection and plays songs semi-randomly along an equal distribution. This is a much harder task than simply picking a random song or ordering a collection randomly. Many of these can be handled because we have establish enough meta data about songs that it can be used and taken into account, but balancing them is a difficult task.