ID:1598990
 
Shuffle (List)

This process will shuffle any list you give it, effectively and efficiently (for DM). Only shuffle once. If you shuffle the same list twice you're doing extra work that doesn't help.

proc
shuffle(list/givenList)
. = givenList
var/nextElement

for(var/i = 1; i <= givenList.len; i++)

nextElement = rand(1, givenList.len - i)
nextElement = givenList[nextElement]

. -= nextElement
. += nextElement

return .

An example of how it's used:

mob
Login()
var/list/L = list("a","b","c","d")
L = shuffle(L)

for(var/i = 1; i <= L.len; i++)
world << "\[[L[i]]]"

Output
[c]
[a]
[b]
[d]
I just wanted to point out that when shuffling a 52 card deck multiple times with this procedure it begins to eventually throw multiple out of bounds exceptions.
Can you show me the code you're using that's giving the error?

Also, with this process shuffling multiple times doesn't make it any more or less shuffled. Each shuffle gives every element in the list a random place.
I just shuffled a list of length 52 1000 times. Got no errors at all. I think you're doing something wrong.


No errors:
mob
Login()
var/list/L[52]
for(var/i = 1 to 52)
L[i] = i

for(var/i = 1 to 1000)
L = shuffle(L)
Okay so I'm going to have a look at that in a moment but first I need to say something else.

Using this function more than once on the same list is needless. You should never ever use this process more than once. Running this more than once, why? Running this 10 million times.... Why?

Gonna test this myself out of interest.
Since you're modifying the given list inside the proc, you don't need to do "L = shuffle(L)", which is equivalent to "shuffle(L); L = L". That shouldn't be the cause of any problems, though.
In response to Kaiochao
Thanks! That's what it was actually. I should have watched how I was passing the information. I effectively created a referencing loop. What happens then is the memory just continues to fill up until there's no longer any more space to store variables.

The list was being passed by reference and then returned by value. Anything passed by reference should never be returned. You end up with data that can't be garbage collected.
Error Free Now
You wouldn't need to use it more than once logically. However, Just like in real life you could use it multiple for good measure. I was only pointing out an error that occured as I benchmarked this against mine.

Another thing I noticed is that considering you select a spot at random you expect all elements to change. However if your random selection never selects say element 1, 2, 3, 4, 5 and 6 - They won't be moved and will stay in the same position. Thus you have a code-logic error as well.
In response to D-Cire
You don't understand how this code works. When my code randomly selects an element it moves that element to the end of the list. That element is now beyond the scope of the loop.

For that reason when any random element in my code is moved, they are all beyond reach. Hence all elements are covered only once and all elements have a random location because they were plucked randomly.

Please read my code closely and you will understand it.


Also: Once you understand my code you will understand that you should never do this more than once. "For good measure" makes no sense with my shuffle. It's maximally shuffled the first time you use it. You can't get the locations of any elements any more random than they already are. It's impossible.
In response to Zecronious
Zecronious wrote:
You don't understand how this code works. When my code randomly selects an element it moves that element to the end of the list. That element is now beyond the scope of the loop.

For that reason when any random element in my code is moved, they are all beyond reach. Hence all elements are covered only once and all elements have a random location because they were plucked randomly.

Please read my code closely and you will understand it.


Also: Once you understand my code you will understand that you should never do this more than once. "For good measure" makes no sense with my shuffle. It's maximally shuffled the first time you use it. You can't get the locations of any elements any more random than they already are. It's impossible.

Incorrect And I'll be referencing you to my post in my thread about how your wrong about how yours isn't inefficient, and how mine is.

Link: http://www.byond.com/forum/?post=1604987#comment10713238

Have a nice day feeling super awkward. c:
In response to D-Cire
D-Cire, I've already had other programmers approve of mine.... You're the only person saying mine is wrong.

I'm laughing my ass off. At first I thought you were trolling me. Now I realise you just haven't read through my code properly. It's funny as hell.

The only awkward thing is that you refuse to read through the code I wrote which has been approved.
Whoops, I left out a -i.

nextElement = rand(1, givenList.len - i)


Thanks.