我最近在C#中设计了一个战利品表,效果非常好。我想尽量添加最后一件事,这是一种计算从表中挑选物品的概率百分比的方法。我已经知道概率应该是多少,因为我已将所有数据输入到在线交互式图表中,我只是不知道如何手动计算它。这是我的LootTable类:
using System;
using System.Collections.Generic;
using System.Linq;
namespace NovaEngineFramework.Framework.Probability
{
public class LootTable
{
private readonly List<string> _lootTable;
private readonly Dictionary<string , uint> _cachedLoot;
private readonly Random _rngInstance;
private bool _isRebuildRequired;
public LootTable()
{
_rngInstance = new Random();
_cachedLoot = new Dictionary<string , uint>();
_lootTable = new List<string>();
}
public LootTable( Random random )
{
this._rngInstance = random;
_cachedLoot = new Dictionary<string , uint>();
_lootTable = new List<string>();
}
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<string> 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<string , uint> pair in _cachedLoot )
{
for( int i = 0; i < 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 ) ];
}
}
}
这是我的测试实现:
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());
图片有助于更好地理解:
以下是交互式图表链接,如果鼠标悬停,则显示实际的基于%的概率。 Interactive Chart
我正在寻求的输出的可视示例:
如在线图表那样计算战利品表概率的正确方法是什么?
上次修改 对于那些想要包含答案的最终产品的人,这里是类的pastebin链接:
答案 0 :(得分:2)
在_cachedLoot
中添加项目总数,然后将相关项目的金额除以总计。
double total = _cachedLoot.Values.Sum(n => (int)n);
return _cachedLoot[name] / total;
(请注意转化为double
- 这是防止integer division所必需的。)
如果要返回适合打印的值,可以稍微修改上述内容:
double total = _cachedLoot.Values.Sum(n => (int)n);
double percent = _cachedLoot[name] / total;
return Math.Round(percent * 100, 2);