从通用物料工厂返回的随机物料(加权)

时间:2019-07-18 14:53:55

标签: c# linq random

我的商品工厂类遇到了我目前正在尝试编写的小游戏问题。我目前正在做的事情如下:

  • 我有一个列表,其中包含我所有可能的类型为x(装甲,武器等)的游戏项目,基类为Item
  • 每个项目在稀有性枚举中都具有稀有性(0 =普通,1 =不普通,依此类推)
  • 实际的稀有度“ spawn”百分比保存在包含稀有度和百分比的字典中
  • 当前,我有一个通用方法返回随机项目的新实例:
public IEnumerable<T> GetRandomItem<T>(int count = 1, Rarity maxRarity = Rarity.Common, List<int> ids = null)
  where T : Item
{
  InitializeActualRarities(maxRarity);
  return GetItems<T>().ToList().Where(i => CheckItemConditions(ref i, maxRarity, ids)).Clone().PickRandom(count);
}
  • 由GetRandomItem方法返回的项目始终是项目列表中随机选择的对象的副本。

  • InitializeActualRarities方法为低于最大稀有度的所有稀有度生成百分比:

    private void InitializeActualRarities(Rarity maxRarity)
    {
      _actualRarityPercentages.Clear();

      var remaining = 100;
      Enum.GetValues(typeof(Rarity)).OfType<Rarity>().Where(r => _staticRarityPercentages[r] >= _staticRarityPercentages[maxRarity]).ToList().ForEach(r =>
      {
        remaining -= _staticRarityPercentages[r];
        _actualRarityPercentages.Add(r, _staticRarityPercentages[r]);
      });

      var key = _actualRarityPercentages.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;
      _actualRarityPercentages[key] += remaining;
    }

目前,我显然没有在GetRandomItem方法中使用实际的稀有百分比,而这正是我要更改的内容。

我想以某种方式调整linq,以确保只返回给定最大稀有度的物品以及_actualRarityPercentages词典中的稀有度百分比。

有人对我以编码方式解决此类任务有任何想法或建议吗?

提前谢谢!

2 个答案:

答案 0 :(得分:1)

类似的事情可能会起作用:

// Assuming this is the type
Dictionary<Rarity, int> _actualRarityPercentages;

public IEnumerable<T> GetRandomItem<T>(int count = 1, Rarity maxRarity = Rarity.Common, List<int> ids = null)
  where T : Item
{
  InitializeActualRarities(maxRarity);

  int maxRarityValue = _actualRarityPercentages[maxRarity];

  return GetItems<T>().ToList()
        .Where(item => _actualRarityPercentages[item.Rarity] <= maxRarityValue)
        .Clone()
        .PickRandom(count)
}

我假设_actualRarityPercentages是从Rarityint的简单字典。使用LINQ Where,您应该可以过滤比maxRarity更稀有的项目。

希望有帮助

答案 1 :(得分:-1)

尝试以下操作:

public IEnumerable<T> GetRandomItem<T>(int count = 1, Rarity maxRarity = Rarity.Common, List<int> ids = null)
  where T : Item
{
  InitializeActualRarities(maxRarity);
  Random rand = new Rand();
  return GetItems<T>().ToList().Where(i => CheckItemConditions(ref i, maxRarity, ids)).Clone().Select((x,i) => new {item = x, rand = rand.Next()}).OrderBy(x => x.rand).Select(x => x.item).Take(count);
}