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的答案。
您的递归有问题。如果
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(); } } |