选择基于整数值的选项?

时间:2014-02-14 20:56:35

标签: c# math if-statement

这是C#

我正在使用一个每隔几秒随机计算的变量来生成实体,它是一个在0到100之间随机生成的数字。目前我的系统使用了一堆if / else语句,从最难得的机会开始,最常见的。

如果骰子在32处滚动,并且实体有35%的机会产生,它将产生而不是产生更常见的实体,可以说70%的时间。但是,在大量的if / else语句中执行此操作看起来非常难看,我确信还有另一种方法。

有什么建议吗?

Psuedo我正在做什么

int dice = RandomNumber(0-100);
if(dice < 35) SpawnEntity(Gem);
else
if(dice < 60) SpawnEntity(Crate);

这非常......非常难看。它确实有效,但它很难看。我确信有更好的方法可以做到。

2 个答案:

答案 0 :(得分:3)

这将消除一些if冗余并保持初始化更清洁。

var actions = new Dictionary<int, Action>
    {{35, () => SpawnEntity(Gem)},
     {60, () => SpawnEntity(Crate)}};

foreach(var kvp in actions.OrderBy(kvp => kvp.Key))
  if (dice < kvp.Key) {
    kvp.Value();
    break;  
  }

正如Alex所提到的,您可能需要使用SortedDictionary或LINQ在迭代期间对其进行排序。还要记住,你并没有停留使用Dictionary,你可以通过继承IEnumerable并使用适当的add方法来声明自己的集合类型并具有相同的初始化序列。

答案 1 :(得分:0)

我认为没有。 switch语句不起作用,因为case标签必须是常量值,而不是范围。

如果要使代码具有通用性,可以定义包含范围和相应实体类型的数据结构。然后编写检查此类结构列表的代码,以找出随机数落入的范围,并创建相应的实体。这将消除所有if / else语句,并使添加新实体或更改其范围更容易一些。但是,如果您创建的一组内容定义明确且不变,则这不是必需的。

你甚至可以进一步抽象它并创建一个实用函数,它接受一组Action个对象,每个对象都有一个相应的“权重”,然后随机选择并执行Action个中的一个概率与其重量成正比。

// Randomly executes one of the given actions (KVP values). The probability
// of a given action being chosen is proportional to its weight (KVP key).

public static void RandomlyExecute(
    Random random,
    IEnumerable<KeyValuePair<double, Action>> choices)
{
    double totalWeight = Enumerable.Sum(choices, choice => choice.Key);
    double x = random.NextDouble() * totalWeight;
    double y = 0;

    foreach (var choice in choices)
    {
        y += choice.Key;
        if (x <= y)
        {
            choice.Value();
            break;
        }
    }
}