using System.Collections;
using System.Collections.Generic;
public static void Main()
var box = new PrizeBox<string>();
var prize1 = box.Add( "1獎",20);
foreach (var result in Enumerable.Range(0, 100).Select(x => box.DrawOne()).GroupBy(x => x).Select(x => new
Console.WriteLine(result.Prize + " 出現 " + result.Count + " 次");
Console.WriteLine("更改機率");
foreach (var result in Enumerable.Range(0, 100).Select(x => box.DrawOne()).GroupBy(x => x).Select(x => new
Console.WriteLine(result.Prize + " 出現 " + result.Count + " 次");
Console.WriteLine("直接限制次數");
foreach (var result in Enumerable.Range(0, 100).Select(x => box.DrawOne()).GroupBy(x => x).Select(x => new
Console.WriteLine(result.Prize + " 出現 " + result.Count + " 次");
Console.WriteLine("關閉獎項");
foreach (var result in Enumerable.Range(0, 100).Select(x => box.DrawOne()).GroupBy(x => x).Select(x => new
Console.WriteLine(result.Prize + " 出現 " + result.Count + " 次");
public interface IPrizeBox
bool BoxCalculated { get; set; }
public interface IPrize<T>
int? MaxTimes { get; set; }
int DrawedTimes { get; set; }
bool CanDraw { get; set; }
public class PrizeBox<T> : IEnumerable<IPrize<T>>, IPrizeBox
internal class Prize : IPrize<T>
public T Item { get; set; }
Box.BoxCalculated = false;
Box.BoxCalculated = false;
public int DrawedTimes { get; set; }
Box.BoxCalculated = false;
public IPrizeBox Box { get; set; }
public Prize(T item, int weight, int? maxTimes) : this()
static Random random = new Random();
internal List<IPrize<T>> prizeList = new List<IPrize<T>>();
internal IPrize<T>[] pool;
public bool BoxCalculated { get; set; }
public int Count { get { return prizeList.Count; } }
public bool IsReadOnly { get { return false; } }
foreach (var prize in prizeList)
pool = prizeList.Where(x => x.CanDraw && x.Weight > 0 && (!x.MaxTimes.HasValue || x.DrawedTimes < x.MaxTimes.Value)).ToArray();
max = pool.Sum(x => x.Weight);
var getLuckNumber = random.Next(1, max);
foreach (var prize in pool)
getLuckNumber -= prize.Weight;
if (prize.MaxTimes.HasValue && prize.DrawedTimes >= prize.MaxTimes.Value)
throw new Exception("something wrong");
public IPrize<T> Add(T item, int weight, int? maxTimes = null)
var old = FindPrize(item);
throw new Exception("項目重複");
var prize = new Prize(item, weight, maxTimes);
public IPrize<T> FindPrize(T item)
return prizeList.FirstOrDefault(x => x.Item.Equals(item));
public bool Remove(T item)
var find = FindPrize(item);
public IEnumerator<IPrize<T>> GetEnumerator()
return prizeList.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
return prizeList.GetEnumerator();