Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calculate a random action to execute by possibilities

Tags:

c#

I have an enum with some possible actions

internal enum Action
{
    Stay,
    MoveLeft,
    MoveRight
}

and an object holding information about the current chance for this action

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

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

the chance goes from 0 to 100. A collection of actions with their chance could be

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

or

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

or

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

There are 2 important things:

  • The sum of the possibilities will be 100.
  • More or less actions are possible. So the amount of actions is unknown.

When calling a random action via this method

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

        // ...

        Action targetAction = null; // ?
    }

Is there a way to calculate the action (without using ifs)? I thought about this setup:

  • Action A 30
  • Action B 10
  • Action C 60

I could sum up the predecessors of the current action and would get this result

  • Action A 0 - 30
  • Action B 30 - 40
  • Action C rest

but I don't know how to calculate the action by code. Some help would be awesome.

This might be a possible duplicate of

Percentage Based Probability

but as I mentioned before the amount of possible actions is unknown so I can't go for three if statements. And maybe there is a trick using some math to avoid if statements completely.


1 Answers

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;
    }
}
like image 59
404 Avatar answered Dec 23 '25 11:12

404