计算战利品的概率 Table
Calculate probability from a Loot Table
我最近用 C# 设计了一个战利品 table,效果非常好。不过,我想添加最后一件事,这是一种计算可以从 table 中挑选项目的概率百分比的方法。我已经知道百分比概率应该是多少,因为我已经将所有数据输入到在线交互式图表中,我只是不知道如何手动计算它。这是我的战利品表 class:
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());
还有一张有助于更好理解的图片:
这是交互式图表 link,如果将鼠标悬停在该图表上,则会显示实际的基于百分比的概率。
Interactive Chart
我正在寻找的输出的视觉示例:
像在线图表那样计算战利品概率 table 的正确方法是什么?
上次编辑
对于那些想要包含答案的最终产品的人,这里是 class:
的 pastebin link
将 _cachedLoot
中的项目总数相加,然后将相关项目的数量除以总数。
double total = _cachedLoot.Values.Sum(n => (int)n);
return _cachedLoot[name] / total;
(注意转换为 double
- 这是防止 integer division 所必需的。)
如果想return一个适合打印的值,可以稍微修改上面的:
double total = _cachedLoot.Values.Sum(n => (int)n);
double percent = _cachedLoot[name] / total;
return Math.Round(percent * 100, 2);
我最近用 C# 设计了一个战利品 table,效果非常好。不过,我想添加最后一件事,这是一种计算可以从 table 中挑选项目的概率百分比的方法。我已经知道百分比概率应该是多少,因为我已经将所有数据输入到在线交互式图表中,我只是不知道如何手动计算它。这是我的战利品表 class:
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());
还有一张有助于更好理解的图片:
这是交互式图表 link,如果将鼠标悬停在该图表上,则会显示实际的基于百分比的概率。 Interactive Chart
我正在寻找的输出的视觉示例:
像在线图表那样计算战利品概率 table 的正确方法是什么?
上次编辑 对于那些想要包含答案的最终产品的人,这里是 class:
的 pastebin link将 _cachedLoot
中的项目总数相加,然后将相关项目的数量除以总数。
double total = _cachedLoot.Values.Sum(n => (int)n);
return _cachedLoot[name] / total;
(注意转换为 double
- 这是防止 integer division 所必需的。)
如果想return一个适合打印的值,可以稍微修改上面的:
double total = _cachedLoot.Values.Sum(n => (int)n);
double percent = _cachedLoot[name] / total;
return Math.Round(percent * 100, 2);