在c#中选择随机数

Picking Random Numbers in c#

大家好,我有一个问题,选择随机数洗牌。为了随机洗牌,我们尝试在每个循环中随机选择一张牌,但似乎我们用完了一种牌,我们不能随机选择另一种。它进入无限循环。有什么建议吗?

(翻译:maca=spade,sinek=club,kupa=heart,karo=diamond,vale=jack,kiz=queen,papaz=king)

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    public class KartKarma : MonoBehaviour {
    public GameObject[] Deste;
    public static GameObject KupaAs, Kupa2, Kupa3, Kupa4, Kupa5, Kupa6, Kupa7, Kupa8, Kupa9, Kupa10, KupaVale, KupaKiz, KupaPapaz;
    public static GameObject KaroAs, Karo2, Karo3, Karo4, Karo5, Karo6, Karo7, Karo8, Karo9, Karo10, Karo11, Karo12, Karo13;
    public static GameObject SinekAs, Sinek2, Sinek3, Sinek4, Sinek5, Sinek6, Sinek7, Sinek8, Sinek9, Sinek10, Sinek11, Sinek12, Sinek13;
    public static GameObject MacaAs, Maca2, Maca3, Maca4, Maca5, Maca6, Maca7, Maca8, Maca9, Maca10, Maca11, Maca12, Maca13;
    public GameObject[] Kupa = {KupaAs, Kupa2, Kupa3, Kupa4, Kupa5, Kupa6, Kupa7, Kupa8, Kupa9, Kupa10, KupaVale, KupaKiz, KupaPapaz};
    public GameObject[] Karo = {KaroAs, Karo2, Karo3, Karo4, Karo5, Karo6, Karo7, Karo8, Karo9, Karo10, Karo11, Karo12, Karo13};
    public GameObject[] Sinek = {SinekAs, Sinek2, Sinek3, Sinek4, Sinek5, Sinek6, Sinek7, Sinek8, Sinek9, Sinek10, Sinek11, Sinek12, Sinek13};
    public GameObject[] Maca = {MacaAs, Maca2, Maca3, Maca4, Maca5, Maca6, Maca7, Maca8, Maca9, Maca10, Maca11, Maca12, Maca13};
    List<GameObject> deste = new List<GameObject>();

// Use this for initialization
void Start () {
    int i = 0;
    while(i < 26){
        int a = Random.Range(1,5);
        if (a == 1) {
            int b = Random.Range(0,13);
            if(Maca != null){
                while(Maca[b] == null){
                    b = Random.Range(0,13);
                }
                deste.Add(Maca[b]);
                Maca[b] = null;
            }
            else {
                while(a == 1)
                    a = Random.Range(2,5);
            }
        }

        if (a == 2) {
            int b = Random.Range(0,13);
            if(Sinek != null){
                while(Sinek[b] == null)
                    b = Random.Range(0,13);
                deste.Add (Sinek[b]);
                Sinek[b] = null;
            }
            else {
                while(a == 2)
                    a = Random.Range(1,5);
            }
        }

         if (a == 3) {
            int b = Random.Range(0,13);
            if(Karo != null){
                while(Karo[b] == null)
                    b = Random.Range(0,13);
                deste.Add (Karo[b]);
                Karo[b] = null;
            }
            else {
                while(a == 3)
                    a = Random.Range(1,5);
            }
        }

        if (a == 4) {
            int b = Random.Range(0,13);
            if(Kupa != null){
                while(Kupa[b] == null){
                    b = Random.Range(0,13);
                }
                deste.Add(Kupa[b]);
                Kupa[b] = null;
            }
            else {
                                    while(a == 4)
                    a = Random.Range(1,5);
            }
        }
        i++;
    }
}

void Update () {

}

}


使用适当的随机播放算法,如Knuth(又名Fisher Yates):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/// <summary>Used to shuffle collections.</summary>

public class Shuffler
{
    /// <summary>Shuffles the specified array.</summary>
    /// <typeparam name="T">The type of the array elements.</typeparam>
    /// <param name="array">The array to shuffle.</param>

    public void Shuffle<T>(IList<T> array)
    {
        for (int n = array.Count; n > 1; )
        {
            int k = _rng.Next(n);
            --n;
            T temp = array[n];
            array[n] = array[k];
            array[k] = temp;
        }
    }

    private readonly Random _rng = new Random();
}

然后:

1
2
3
var shuffler = new Shuffler();
...
shuffler.Shuffle(deste);

正如@paul发布的链接所表明的那样-请注意,Random并不是一个特别伟大的随机数生成器。如果您愿意,可以替换一个更好的,但是底层的shuffle算法保持不变。


1
2
while(a == 1)
    a = Random.Range(2,5);

这是你无限循环的原因。另外,这部分:

1
2
while(Sinek[b] == null)
    b = Random.Range(0,13);

也是令人讨厌的,因为它不能保证条件会永远满足。


我认为线条

1
2
3
4
while(a == 1)
while(a == 2)
while(a == 3)
while(a == 4)

导致此问题。请重新检查你的逻辑。