关于c#:使用Random.range生成没有重复的级别no

Using Random.range to generate level no without repetition

我尝试对以下问题使用递归,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int newlevelgen()
{
    int exampleno = Random.Range (1,4);
    if (exampleno != lastlevelno)
    {
        lastlevelno = exampleno;
        return exampleno;
    }
    else
    {
        newlevelgen();
    }
    return exampleno;
}

这是我上面的代码,我想做的是生成新数字而不重复上一个数字,但这根本行不通。救命!


我创建了一个实用程序,可以轻松地处理无重复的随机数,平面分布的随机数和加权列表(包括通用属性抽屉!)。您可以在GtiHub上找到它并免费使用:
https://github.com/khadzhynov/RandomUtils


这个想法是您得到一个介于a和b之间的值。如果该值大于或等于先前的值,则将其增加并返回。其他情况,您照原样返回。

考虑到这一点,它确实起作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public int GetUniqueLevelInclusiveOrdinal(int a , int b, int previous){

    // given the ordinal numbers from a to b INCLUSIVE,
    // so including a and b,
    // (*** NOTE, no random int calls in Unity or any system
    // work inclusively so take care ***)
    // choose one of the numbers from a to b inclusive
    // but do not choose"previous"

    // which top index to use with Random.Range which is exclusive?
    int top = b+1;

    // everyday algorithm for excluding one item from a random run
    int topExcludeOne = top-1;

    int value = Random.Range(a, topExcludeOne);
    if (value >= previous) return value+1;
    else return value;
}

这是编程中非常著名的基本模式...

1
2
3
4
5
int result = UnityEngine.Random.Range(0,highest-1);
if (result>=exclude)
   return result+1;
else
   return result;

在Unity中,您必须使用扩展名:

1
2
3
4
5
6
7
8
9
10
public static int RandomIndexButNotThis(this int highest, int exclude)
    {
    if (highest<2) Debug.Break();

    int result = UnityEngine.Random.Range(0,highest-1);
    if (result>=exclude)
       return result+1;
    else
       return result;
    }

获得0到99的随机索引

1
Random.Range(0,100)

获取0到99的随机索引,但不包括61

1
100.RandomIndexButNotThis(61)

获得0到9的随机索引

1
Random.Range(0,10)

要获取0到9的随机索引,但要排除8

1
10.RandomIndexButNotThis(8)

如果是Unity的新手,请介绍扩展


让我以此开头作为开头,说这是对发布的原始方法的问题的解答。获得理想结果的最佳方法远非如此,但这不是此答案的重点。是的,递归可能会继续进行几次调用。 33%的机会需要另一个递归调用,但这并不意味着无限循环有33%的机会,因为需要X个递归调用的可能性为0.33 ^ X,因此达到3个递归调用的可能性仅为0.33 ^ 3?= 0.036。
不过,建议使用其他方法。例如,请参阅Joe Blow的答案。

您的递归有问题。如果examplenolastlevelno相同,则不会使用递归调用newlevelgen()会给您的新值,而不会始终返回(可能重复的)exampleno值。更改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
int newlevelgen()
{
    int exampleno = Random.Range (1,4);
    if (exampleno != lastlevelno)
    {
        lastlevelno = exampleno;
        return exampleno;
    }
    else
    {
        return newlevelgen();
    }
}