Fisher–Yates shuffle in C#

Is this a proper C# implementation of the Fisher–Yates shuffle?

//Fisher–Yates shuffle en.wikipedia.org/wiki/Fisher–Yates_shuffle //for i from 0 to n−2 do //j ← random integer such that i ≤ j < n //exchange a[i] and a[j] int count = 52; int[] deck = new int[count]; for (byte i = 0; i < count; i++)     deck[i] = i; Random rand = new Random(); // next(max) Returns a non-negative random integer that is less than the specified maximum. for (byte i = 0; i <= count - 2; i++) {     int j = rand.Next(count - i);     if (j > 0)     {         int curVal = deck[i];         deck[i] = deck[i+j];         deck[i+j] = curVal;     } } //suffle the other directinon to be sure  //for i from n−1 downto 1 do //j ← random integer such that 0 ≤ j ≤ i //exchange a[j] and a[i] for (int i = count - 1; i >= 1;  i--) {     int j = rand.Next(i + 1);     if (j != i)     {         int curVal = deck[i];         deck[i] = deck[j];         deck[i] = curVal;     } } 

Replay

Since I'm not sure what you are asking by if you are doing it correctly I decided the quickest and easiest answer is to put your code to use. I created a method called Yates and put your code in it. I then called it 19 times in a simple for loop noted the output. (I limited my output to the first 5 numbers so it is more clear here)

35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...
35 22 23 7 25...

You'll notice it is 19 of the same thing. The problem with Random is that it isn't truly random sometimes, and you just ran across this. simple fix for me was to move the creation of the Random rand outside of the method now when I run it.

13 48 16 39 44...
20 3 10 27 18...
20 38 6 10 9...
1 28 6 33 7...
40 20 7 23 37...
31 22 0 34 18...
51 50 49 1 48...
24 1 44 37 50...
23 1 30 41 3...
41 32 45 23 11...
31 47 32 25 34...
49 8 16 33 32...
21 12 17 32 37...
8 2 40 41 49...
0 15 29 42 39...
39 0 46 20 22...
13 24 3 34 26...
9 10 43 2 39...
36 4 40 45 48...

I know it's not much to go on and I normally give much longer reviews but there isn't much code to review.

Here is the code I used to test against

void Main()
{
    for (int i = 0; i < 19; i++)
    Console.WriteLine($"    {string.Join(" ", Yates().Take(5))}...");
}
Random rand = new Random();
private int[] Yates()
{
    int count = 52;
    int[] deck = new int[count];
    for (byte i = 0; i < count; i++)
    deck[i] = i;
    for (byte i = 0; i <= count - 2; i++)
    {
        int j = rand.Next(count - i);
        if (j > 0)
        {
            int curVal = deck[i];
            deck[i] = deck[i + j];
            deck[i + j] = curVal;
        }
    }
    for (int i = count - 1; i >= 1; i--)
    {
        int j = rand.Next(i + 1);
        if (j != i)
        {
            int curVal = deck[i];
            deck[i] = deck[j];
            deck[i] = curVal;
        }
    }
    return deck;
}

I agree with the comment from Sevy about you should pass the array to the method. But this happens to be how I need to use it.

The answer for Robert Snyder is correct but it contains a bug in my question

This was just setting deck[i] back to itself so it was doing nothing

int curVal = deck[i];
deck[i] = deck[j];
deck[i] = curVal;

Random rand = new Random();
public MainWindow()
{
    InitializeComponent();
    //for (byte b = 0; b < 200; b++)
    //    System.Diagnostics.Debug.WriteLine(rand.Next(52));
    byte[] deck;
    HashSet<byte> hsDeck = new HashSet<byte>();
    for (byte b = 0; b < 254; b++)
    {
        deck = Shuffle(52);
        hsDeck.Clear();
        for (byte i = 0; i < 52; i++)
        {
            if (hsDeck.Contains(deck[i]))
                Debug.WriteLine("Houston we have a problem");
            if (deck[i] < 0)
                Debug.WriteLine("Houston we have a problem");
            if (deck[i] > 51)
                Debug.WriteLine("Houston we have a problem");
            hsDeck.Add(deck[i]);
        }
        Debug.WriteLine(string.Join(", ", deck));
    }
}
private byte[] Shuffle(byte count)
{
    byte[] deck = new byte[count];
    for (byte i = 0; i < count; i++)
        deck[i] = i;
    byte curVal;
    //Fisher–Yates shuffle en.wikipedia.org/wiki/Fisher–Yates_shuffle
    //for i from 0 to n−2 do
    //j ← random integer such that i ≤ j < n
    //exchange a[i] and a[j]
    for (byte i = 0; i <= count - 2; i++)
    {
        byte k = (byte)rand.Next(count - i); //Returns a non-negative random integer that is less than the specified maximum
        if (k > 0)
        {
            curVal = deck[i];
            deck[i] = deck[i + k];
            deck[i + k] = curVal;
        }
    }
    //return deck;
    //suffle the other directinon to be sure
    //for i from n−1 downto 1 do
    //j ← random integer such that 0 ≤ j ≤ i
    //exchange a[j] and a[i]
    for (byte i = (byte)(count - 1); i >= 1;  i--)
    {
        byte k = (byte)rand.Next(i + 1);
        if (k != i)
        {
            curVal  = deck[i];
            deck[i] = deck[k];
            deck[k] = curVal;
        }
    }
    return deck;
}

Category: c# Time: 2016-07-29 Views: 0
Tags: random shuffle

Related post

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development

search

Front-end development

Database

development tools

Open Platform

Javascript development

.NET development

cloud computing

server

Copyright (C) avrocks.com, All Rights Reserved.

processed in 0.153 (s). 12 q(s)