title: Calculate probability from a Loot Table
body: <p>I recently designed a loot table in C#, which works splendidly. I wanted to add one last thing to it though, which is a way to calculate the percent probability that an item can be picked from the table. I already know what the percent probability should be, given that I have entered all the data into an online interactive graph, I just don't know how to manually calculate it. Here is my LootTable class:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  
  namespace NovaEngineFramework.Framework.Probability
  {
      public class LootTable
      {
          private readonly List&lt;string&gt; _lootTable;
          private readonly Dictionary&lt;string , uint&gt; _cachedLoot;
          private readonly Random _rngInstance;
          private bool _isRebuildRequired;
  
          public LootTable()
          {
              _rngInstance = new Random();
              _cachedLoot = new Dictionary&lt;string , uint&gt;();
              _lootTable = new List&lt;string&gt;();
          }
  
          public LootTable( Random random )
          {
              this._rngInstance = random;
              _cachedLoot = new Dictionary&lt;string , uint&gt;();
              _lootTable = new List&lt;string&gt;();
          }
  
          public void AddLoot( uint probability , string name )
          {
              if( !_cachedLoot.ContainsKey( name ) )
              {
                  this._cachedLoot.Add( name , probability );
                  _isRebuildRequired = true;
              }
              else
              {
                  throw new Exception( "Item: " + name + " Already Exists!" );
              }
  
          }
  
          public void DeleteLoot( string name )
          {
              if( _cachedLoot.ContainsKey( name ) )
              {
                  this._cachedLoot.Remove( name );
                  _isRebuildRequired = true;
              }
              else
              {
                  throw new Exception( "Item: " + name + " Did not exist!" );
              }
          }
  
          public double CalculateProbability(string name)
          {
              if( _cachedLoot.ContainsKey( name ) )
              {
                  return 0; // Calculate the actual percent probability here
              }
              throw new Exception( "Item: " + name + " Does not exist." );
          }
  
          public uint CheckRarity( string name )
          {
              if( _cachedLoot.ContainsKey( name ) )
              {
                  return _cachedLoot[ name ];
              }
              throw new Exception( "Item: " + name + " Does not exist." );
          }
  
          public List&lt;string&gt; CheckLoot()
          {
              return this._cachedLoot.Keys.ToList();
          }
  
          public void EditLoot( string name , uint newProbability )
          {
              if( _cachedLoot.ContainsKey( name ) )
              {
                  this._cachedLoot[ name ] = newProbability;
                  _isRebuildRequired = true;
              }
              else
              {
                  throw new Exception( "Item: " + name + " Does not exist." );
              }
          }
  
          public void ClearAllLoot()
          {
              this._cachedLoot.Clear();
              this._isRebuildRequired = true;
          }
  
          private void Build()
          {
              _lootTable.Clear();
              foreach( KeyValuePair&lt;string , uint&gt; pair in _cachedLoot )
              {
                  for( int i = 0; i &lt; pair.Value; i++ )
                  {
                      _lootTable.Add( pair.Key );
                  }
              }
              _isRebuildRequired = false;
          }
  
          public string NextRandomItem()
          {
              if( !_isRebuildRequired )
              {
                  return _lootTable[ _rngInstance.Next( _lootTable.Count ) ];
              }
              this.Build(); // A rebuild is needed, let's go ahead and take care of it!
              return _lootTable[ _rngInstance.Next( _lootTable.Count ) ];
          }
      }
  }
  </code></pre>
  
  <p>And here is my testing implementation:</p>
  
  <pre><code>        LootTable swordTable = new LootTable();
          swordTable.AddLoot( 1 , "Sword_Legendary_SwordOfIllimitableDemise" );
          swordTable.AddLoot( 200 , "Sword_Common_SteelGreatSword" );
          swordTable.AddLoot( 50 , "Sword_Rare_MagicImbuedLongBlade" );
          swordTable.AddLoot( 15 , "Sword_Epic_Hopesfire" );
          swordTable.AddLoot( 400 , "Sword_Trash_RustySword" );
          Console.WriteLine(swordTable.NextRandomItem());
  </code></pre>
  
  <p>And an image to help facilitate better understanding:
  <img src="https://i.stack.imgur.com/qk7BN.png" alt="enter image description here"></p>
  
  <p>Here is the interactive chart link which if moused over, shows the actual % based probabilities.
  <a href="https://www.meta-chart.com/share/untitled-3786" rel="nofollow noreferrer">Interactive Chart</a></p>
  
  <p>Visual Example of the output I am seeking:
  <img src="https://i.stack.imgur.com/P75ye.png" alt="enter image description here"></p>
  
  <p><strong>What is the proper way to calculate the probabilites of the loot table like the online chart does?</strong></p>
  
  <p><strong>Last Edit</strong>
  For those who want the final product with answer included, here is a pastebin link of the class:</p>
  
  <p><a href="http://pastebin.com/5rFbVn90" rel="nofollow noreferrer">LootTable.cs</a></p>