2014-02-14 2 views
0

Это C#Выбор опции на основе значения Integer?

Я использую переменную, которая вычисляется случайным образом каждые несколько секунд, чтобы порождать сущности, это число, которое генерируется случайным образом в диапазоне от 0 до 100. В настоящее время моя система использует кучу если/другое заявления в порядок от самого редкого шанса, до самого распространенного.

Если кубик рулон на 32, а сущность имеет шанс на 35%, он будет появляться вместо более распространенной сущности, которая возникает, скажем, 70% времени. Однако делать это в тоннах if/else заявлений выглядит очень уродливо, и я уверен, что есть другой способ.

Любые предложения?

псевдопользователей, что я делаю

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

Это становится, очень .. очень некрасиво. Он работает, но он уродлив. Я уверен, что есть лучший способ сделать это.

ответ

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; 
    } 

Как Алекс упоминает вам может понадобиться использовать SortedDictionary или LINQ, чтобы заказать его во время итерации. Также помните, что вы не застряли в использовании Dictionary, вы можете объявить свой собственный тип коллекции и иметь одну и ту же последовательность инициализации, наследуя от IEnumerable и имея соответствующий метод добавления.

+2

Вам не нужен 'SortedDictionary' вместо' Словарь', чтобы гарантировать порядок ключей? – AlexD

+0

@ AlexD Я думал об этом. Либо Сортировка, либо просто сортировка во время итерации. –

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; 
     } 
    } 
} 
Смежные вопросы