using System.Collections.Generic;
public class DropTable<T>
private Random _random = new Random();
private List<DropTableEntry<T>> _entries = new List<DropTableEntry<T>>();
public void AddDrop(T item, int chance)
throw new ArgumentNullException(nameof(item));
if (chance <= 0 || chance > 10000)
throw new ArgumentOutOfRangeException(nameof(item));
_entries.Add(new DropTableEntry<T>(item, chance, 1, 1));
public void AddRangedDrop(T item, int chance, int min, int max)
throw new ArgumentNullException(nameof(item));
if (chance < 0 || chance > 10000)
throw new ArgumentOutOfRangeException(nameof(item));
_entries.Add(new DropTableEntry<T>(item, chance, min, max));
public List<Drop<T>> CalculateDrops()
List<Drop<T>> drops = new List<Drop<T>>(_entries.Count);
foreach (var item in _entries)
int roll = _random.Next(10000);
int count = _random.Next(item.Min, item.Max);
drops.Add(new Drop<T>(item.Item, count));
internal class DropTableEntry<T>
internal DropTableEntry(T item, int chance, int min, int max)
public int Chance { get; }
internal Drop(T item, int count = 1)
public int Count { get; }
static void Main(string[] args)
DropTable<string> table = new DropTable<string>();
table.AddDrop("Sword", 2500);
table.AddDrop("Mushroom", 7500);
table.AddDrop("Mushroom", 7500);
table.AddRangedDrop("Dirt", 8500, 100, 100);
table.AddRangedDrop("Gold", 10000, 100, 200);
for (int i = 0; i < 5; i++)
var drops = table.CalculateDrops();
Console.WriteLine($"Drop {i + 1}");
foreach (var drop in drops)
Console.WriteLine($"{drop.Item} x{drop.Count}");