#!/usr/bin/perl -w
use strict;
use Time::HiRes qw(time gettimeofday);
sub genDeck {
my ($sec, $usec) = gettimeofday();
my $seed = shift || int(rand($sec + $usec ^ $$)); # Or whatever number you like…
my @cards = split //, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
my $deck = undef;
srand($seed) if defined $seed;
for(my $i = 51; $i >= 0; $i–) {
my $choice = int(rand($i+1));
$deck .= $cards[$choice];
splice(@cards, $choice, 1);
}
my $output = sprintf "% 16d %s\n", $seed, $deck;
return $output;
}
print genDeck();
print genDeck(42);
print genDeck();
print genDeck(42);
$ perl card_decks.pl
1221670608 CfYXvUjqABboizcmekGtKuhPlsHMWQNROwLxVIyJardpnESFTDgZ
42 mRFWDtaZkrXecBpgwVbUSNxCuzqKIGOlEPQhsLonJAfdvyHYiMTj
245798749 NWevosPSaktybMzJCFYQRcIgnlrTjOGUhXiVAmDfKwLEHuqxBZpd
42 mRFWDtaZkrXecBpgwVbUSNxCuzqKIGOlEPQhsLonJAfdvyHYiMTj
class Array
def shuffle
length.times do |i|
rng = rand(length-i) +i
self[i] ^= self[rng]
self[rng] ^= self[i]
self[i] ^= self[rng]
end
end
end
deck = (1..52).to_a
puts deck
deck.shuffle
puts deck
def shuffle(set)
(size=set.length).times do |i|
y = rand(size)
set[i], set[y] = set[y], set[i]
end
end
# Can't figure out a good way to make this a one liner =(
def shuffle2(set)
size=set.length.times {|i| set[i], set[y=rand(size)] = set[y], set[i]}
end
$ cat deck_shuffle.cpp
#include <vector>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
vector<int> deck;
for (int i = 1; i < 53; i++)
deck.push_back(i);
for (vector<int>::iterator i = deck.begin(); i != deck.end(); i++)
cout << *i << " ";
cout << endl;
random_shuffle(deck.begin(), deck.end());
for (vector<int>::iterator i = deck.begin(); i != deck.end(); i++)
cout << *i << " ";
cout << endl;
random_shuffle(deck.begin(), deck.end());
for (vector<int>::iterator i = deck.begin(); i != deck.end(); i++)
cout << *i << " ";
cout << endl;
return 0;
}
$ g++ deck_shuffle.cpp & ./a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
46 16 29 41 26 21 20 37 22 32 3 14 30 23 13 52 7 6 18 28 19 34 31 24 9 8 42 27 51 17 40 4 39 11 49 35 12 2 38 25 15 44 36 47 43 45 10 50 33 1 5 48
49 2 19 32 42 5 17 8 22 47 43 26 15 1 16 24 6 38 33 48 39 46 31 12 9 37 20 18 4 30 28 7 25 34 36 41 10 11 27 3 29 44 52 23 45 40 51 35 14 21 13 50
long i = RARRAY_LEN(ary);
ptr = RARRAY_PTR(ary);
while (i) {
long j = (long)(rb_genrand_real()*i);
VALUE tmp = ptr[–i];
ptr[i] = ptr[j];
ptr[j] = tmp;
}
I was successful but later I decided to go a different route. Currently I have a constant matrix representing all possible shuffled decks. Then to get a shuffled deck I simply select a random number between the range of 0..n-1 where n is the number of permutations.
The benifit of this is there is no shuffling process and logging many hand histories of entire decks becomes dramatically easier since an entire deck can be represented by a single number. Also this approach guarentees a perfect distribution in shuffling. The only determining factor would be how well the rng actually works. (which some testing and analyzing would quickly uncover.)
The worst part of this approach is the memory requirement overhead. I feel for a server the additional 140k or so of memory is trivial. Additionally if the server was popularly used it would save memory on individual representation of decks. Particularly because you only need to know how many cards are drawn from the deck. Not the full representation.
Any ideas or thoughts on what I'm doing here is appreciated.