我需要游戏编程方面的帮助。
你打开一个胸部,并且在给定概率的情况下你会找到一个项目。
项目/机会
A / 10%
B / 30%
C / 60%
Random random = new Random();
int x = random.Next(1, 101);
if (x < 11) // Numbers 1..10 ( A -> 10% )
{
do_something1(); d
}
else if (x < 41) // Numbers 11..40 ( B -> 30 % )
{
do_something2();
}
else if (x < 101) // Numbers 41..100 ( C -> 60 % )
{
do_something3();
}
这个例子在概率方面真的有意义吗? 你有其他解决方案吗?
提前谢谢!
答案 0 :(得分:4)
我同意@Timothy,我会寻求一个更易于维护的解决方案,您不会依赖magic numbers来分割您的概率。此外,它是个人偏好,但我也称它为比率而不是百分比,否则&#34; 100&#34;成为另一个神奇的数字,你限制自己的最低概率为1%。这样你可以1:10:200分开它,或者你可以分开:
public static readonly int RATIO_CHANCE_A = 10;
public static readonly int RATIO_CHANCE_B = 30;
// ...
public static readonly int RATIO_CHANCE_N = 60;
public static readonly int RATIO_TOTAL = RATIO_CHANCE_A
+ RATIO_CHANCE_B
// ...
+ RATIO_CHANCE_N;
Random random = new Random();
int x = random.Next(0, RATIO_TOTAL);
if ((x -= RATIO_CHANCE_A) < 0) // Test for A
{
do_something1();
}
else if ((x -= RATIO_CHANCE_B) < 0) // Test for B
{
do_something2();
}
// ... etc
else // No need for final if statement
{
do_somethingN();
}
编辑:更通用的解决方案
答案 1 :(得分:2)
我意识到这已经晚了一点,但是这里有一个例子,没有consts,费力的if / else和/或switch语句;
public class WeightedChanceParam
{
public Action Func { get; }
public double Ratio { get; }
public WeightedChanceParam(Action func, double ratio)
{
Func = func;
Ratio = ratio;
}
}
public class WeightedChanceExecutor
{
public WeightedChanceParam[] Parameters { get; }
private Random r;
public double RatioSum
{
get { return Parameters.Sum(p => p.Ratio); }
}
public WeightedChanceExecutor(params WeightedChanceParam[] parameters)
{
Parameters = parameters;
r = new Random();
}
public void Execute()
{
double numericValue = r.NextDouble() * RatioSum;
foreach (var parameter in Parameters)
{
numericValue -= parameter.Ratio;
if (!(numericValue <= 0))
continue;
parameter.Func();
return;
}
}
}
用法示例:
WeightedChanceExecutor weightedChanceExecutor = new WeightedChanceExecutor(
new WeightedChanceParam(() =>
{
Console.Out.WriteLine("A");
}, 25), //25% chance (since 25 + 25 + 50 = 100)
new WeightedChanceParam(() =>
{
Console.Out.WriteLine("B");
}, 50), //50% chance
new WeightedChanceParam(() =>
{
Console.Out.WriteLine("C");
}, 25) //25% chance
);
//25% chance of writing "A", 25% chance of writing "C", 50% chance of writing "B"
weightedChanceExecutor.Execute();
答案 2 :(得分:1)
所以总结这里的解决方案是一个解决方案,可以解决任意数量的机会,而不需要很多if-else语句,而是切换案例:
int[] chances = { 1, 23, 14, 49, 61 };
int totalRatio = 0;
foreach(int c in chances)
totalRatio += c;
Random random = new Random();
int x = random.Next(0, totalRatio);
int iteration = 0; // so you know what to do next
foreach(int c in chances)
{
iteration++;
if((x -= c) < 0)
break;
}
switch(iteration)
{
case 1:
case 2:
//...
default:
}
答案 3 :(得分:0)
当我结合你所有的答案时,这也应该在这里工作,对吗?
double number;
Random x = new Random();
number = x.NextDouble();
double RATIO_CHANCE_A = 0.10;
double RATIO_CHANCE_B = 0.30;
double RATIO_CHANCE_C = 0.60;
double RATIO_TOTAL = RATIO_CHANCE_A + RATIO_CHANCE_B + RATIO_CHANCE_C;
if ( number < RATIO_CHANCE_A ) // A -> 10%
{
do_something1();
}
else if ( number < RATIO_CHANCE_B + RATIO_CHANCE_A ) // B -> 30%
{
do_something2();
}
else if ( number < RATIO_TOTAL ) // C -> 60%
{
do_something3();
}