首页 > 解决方案 > 根据可能性计算要执行的随机动作

问题描述

我有一个包含一些可能操作的枚举

internal enum Action
{
    Stay,
    MoveLeft,
    MoveRight
}

和一个对象,该对象保存有关此操作的当前机会的信息

internal class ActionWithPossibility
{
    public Action Action { get; }
    public int ActionChancePercent { get; }

    public ActionWithPossibility(Action action, int actionChancePercent)
    {
        Action = action;
        ActionChancePercent = actionChancePercent;
    }
}

机会从 0 到 100。带有机会的动作集合可能是

        List<ActionWithPossibility> actionsWithPossibilities = new List<ActionWithPossibility>() {
            new ActionWithPossibility(Action.Stay, 40),
            new ActionWithPossibility(Action.MoveLeft, 30),
            new ActionWithPossibility(Action.MoveRight, 30)
        };

或者

        List<ActionWithPossibility> actionsWithPossibilities = new List<ActionWithPossibility>() {
            new ActionWithPossibility(Action.Stay, 30),
            new ActionWithPossibility(Action.MoveLeft, 10),
            new ActionWithPossibility(Action.MoveRight, 60)
        };

或者

        List<ActionWithPossibility> actionsWithPossibilities = new List<ActionWithPossibility>() {
            new ActionWithPossibility(Action.Stay, 30),
            new ActionWithPossibility(Action.MoveLeft, 60),
            new ActionWithPossibility(Action.MoveRight, 10)
        };

有两个重要的事情:

通过此方法调用随机操作时

    public void NextAction(List<ActionWithPossibility> actionsWithPossibilities)
    {
        int randomNumber = random.Next(0, 100);

        // ...

        Action targetAction = null; // ?
    }

有没有办法计算动作(不使用ifs)?我想到了这个设置:

我可以总结一下当前动作的前辈,会得到这个结果

但我不知道如何通过代码计算动作。一些帮助会很棒。

这可能是

基于百分比的概率

但正如我之前提到的,可能的操作数量是未知的,所以我不能选择三个 if 语句。也许有一个技巧可以使用一些数学来完全避免 if 语句。

标签: c#

解决方案


int threshold = 0;
int randomNumber = random.Next(0, 100);
for (var i = 0; i < actionsWithPossibilities.Count; i++)
{
    var item = actionsWithPossibilities[i];
    threshold += item.ActionChancePercent;

    if (randomNumber <= threshold)
    {
        //first action that's under the defined threshold is placed in result
        result = item.Action;
        break;
    }
}

推荐阅读