- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个非常具体且冗长的问题要问大家。这个问题既关于编程又关于博弈论。我最近在我的回合制策略游戏中添加了可生成的矿石:http://imgur.com/gallery/0F5D5Ij (对于你们中的那些人,请原谅开发纹理)。
现在,进入我一直在思考的谜题。在我的游戏中,每次创建新 map 时都会生成矿石。每次创建关卡都会生成 0-8 个矿石节点。我已经有这个工作了;除了此时它只生成“Emeraldite”,这让我想到了我的问题。
作为程序员,我将如何使节点具有特定的稀有度?考虑这个实际上不是游戏数据的简短模型:
(一个节点将是以下之一的伪概率)
Bloodstone 1 in 100
Default(Empty Node) 1 in 10
Copper 1 in 15
Emeraldite 1 in 35
Gold 1 in 50
Heronite 1 in 60
Platinum 1 in 60
Shadownite 1 in 75
Silver 1 in 35
Soranite 1 in 1000
Umbrarite 1 in 1000
Cobalt 1 in 75
Iron 1 in 15
我想让生成的节点在理论上可以是上述任何一种,但是,还要考虑几率。我希望这个问题足够清楚。我一直在努力解决这个问题,甚至试图用随机数写出一些 if 语句,但是,我总是空手而归。
基本上,我只是想让你们看看我的问题,并希望能为我提供一些关于如何以动态方式解决这个问题的见解。
如果需要任何说明,请询问;如果这令人费解,再次抱歉。
(我添加 C# 作为标签只是因为这是我在这个项目中使用的语言)
最佳答案
我首先将每种战利品类型的概率表示为一个简单的数字。纯数学中的概率通常表示为 0 到 1 范围内的 float ,但为了效率,您可以使用任何(足够大)范围内的整数(每个值是 0-1 值乘以最大值(我在这里调用 MaxProbability))。
e.g. Bloodstone (1 in 100) is 1/100 = 0.01, or MaxProbability * (1/100).
Copper (1 in 15) is 1/15 = 0.06667, or MaxProbability * (1/15).
我假设“默认(空节点)”表示没有其他节点的概率。在这种情况下,最简单的方法是不定义它 - 如果没有选择其他任何一个,您就会得到它。
如果包含“默认”,所有这些概率的总和将为 1(即 100%)(或 MaxProbability,如果使用整数)。
在您的示例中,“默认”的 1/10 概率实际上是一个矛盾,因为所有这些概率的总和不是 1(它是 0.38247619 - 在我上面的示例中计算的概率总和)。
然后您将选择一个 0 到 1 范围内的随机数(如果使用整数,则选择 MaxProbability),并且选择的战利品类型是列表中的第一个,使得概率之和它和之前所有的(“累积概率”)大于随机数。
例如
MaxProbability = 1000 (I'm using this to make it easy to read).
(For accurate probabilities, you could use 0x7FFFFFFF).
Type Probability Cumulative
---- ----------- ----------
Bloodstone 10 10 (0..9 yield Bloodstone)
Copper 67 77 (10+67) (10..76 yield Copper)
Emeraldite 29 105 (77+29)
Gold 20 125 etc.
Heronite 17 142
Platinum 17 159
Shadownite 13 172
Silver 29 200
Soranite 1 201
Umbrarite 1 202
Cobalt 13 216
Iron 67 282
Default (Empty Node) 7175 1000 (anything else)
例如如果您在 0 到 999(含)范围内的随机数是 184(或 172 到 199 范围内的任何数字),您将选择“银”(累积概率大于此的第一个)。
您可以将累积概率保存在一个数组中并循环遍历它,直到找到一个比随机数更高的数,或者到达末尾。
列表的顺序无关紧要。每个实例您只选择了一个随机数。
在列表中包含“默认(空节点)”意味着最后的累积概率将始终是 MaxProbability 并且搜索它的循环永远不会结束。 (或者,'Default' 可以省略,如果循环到达列表末尾则选择它。)
请注意,依次为每个人选择一个随机数,例如1/10 的几率是“血石”,如果不是血石,则有 1/15 的几率是铜,使概率偏向较早的项目:铜的实际概率为 (1/15) * (1 - (1/10)) - 比 1/15 少 10%。
这是执行此操作的代码(实际选择是 5 个语句 - 在方法 Choose 中)。
using System;
namespace ConsoleApplication1
{
class LootChooser
{
/// <summary>
/// Choose a random loot type.
/// </summary>
public LootType Choose()
{
LootType lootType = 0; // start at first one
int randomValue = _rnd.Next(MaxProbability);
while (_lootProbabilites[(int)lootType] <= randomValue)
{
lootType++; // next loot type
}
return lootType;
}
/// <summary>
/// The loot types.
/// </summary>
public enum LootType
{
Bloodstone, Copper, Emeraldite, Gold, Heronite, Platinum,
Shadownite, Silver, Soranite, Umbrarite, Cobalt, Iron, Default
};
/// <summary>
/// Cumulative probabilities - each entry corresponds to the member of LootType in the corresponding position.
/// </summary>
protected int[] _lootProbabilites = new int[]
{
10, 77, 105, 125, 142, 159, 172, 200, 201, 202, 216, 282, // (from the table in the answer - I used a spreadsheet to generate these)
MaxProbability
};
/// <summary>
/// The range of the probability values (dividing a value in _lootProbabilites by this would give a probability in the range 0..1).
/// </summary>
protected const int MaxProbability = 1000;
protected Random _rnd = new Random((int)(DateTime.Now.Ticks & 0x7FFFFFFF));
/// <summary>
/// Simple 'main' to demonstrate.
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
var chooser = new LootChooser();
for(int n=0; n < 100; n++)
Console.Out.WriteLine(chooser.Choose());
}
}
}
关于c# - 游戏设计/理论,战利品掉落几率/生成率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25991198/
抱歉,我不知道如何正确表达标题。但我正在制作一个 Java 游戏,屏幕底部有一个桨,您可以左右移动它以避免小行星坠落。我的桨可以工作,但我不知道如何制作一颗下落的小行星。小行星目前只是一个矩形。我还希
我制作了一个 x=25 & y= 25 的正方形并附加了一个 SKPhysicsBody。我制作了一个标准平台关卡,其中有几个高的下降区域。我希望正方形“破裂”/因从高处坠落而受到损坏。我查了一下维基
我是一名初级游戏程序员,我正在学习如何使用适用于 Android 的 AndEngine。我想让一个 Sprite 从屏幕上掉下来,并在用户触摸时向上跳。关于如何做到这一点的任何想法?如果这样更容易,
我刚刚开始在我的 Ogre 项目中实现 bullet。我按照此处的安装说明进行操作:http://www.ogre3d.org/tikiwiki/OgreBullet+Tutorial+1 剩下的教程
将我的项目升级到 iOS7 后 当我执行 BACK 按钮并且 UINavigationController 返回上一页时,屏幕顶部的 ImageView 会向下移动。 我使用 IB 来做我的布局。这些
我有两个内联 div,其中一个内联 div 有两个彼此下方的 div。 JSFiddle 点击#notLoginStudentBtn 我在做什么我正在切换#notLoginStudentBox 但在切
我有一个移动的对象,它生成由滑动关节连接的 object2 当我按下按钮时,关节被移除,object2 在重力作用下落下 这可行,但只在 x 轴上落下而不会保持其 y 轴速度。 如何让 Object2
如何从购物车中删除商品? 自然地,您希望能够将项目拖放回去。 $(function() { $( "#catalog" ).accordion(); $( "#cata
Swift 标准库中是否有作用于集合、采用谓词并返回从该集合中移除的值的函数? 目前,我必须分两步实现它: guard let idx = allAnnotations.index(where: {$
我真的需要一些关于我的游戏对象的帮助。 我正在开发一款游戏,我想要一个拾取元素来产生物理力爆炸来炸毁敌人。我做了一个简单的炸弹对象来测试这个想法。我添加了一个简单的代码,使用一个循环来收集其半径内的所
平台:iOS (Swift)Mapbox SDK版本:3.6 嗨,我有一个自定义 MGLCalloutView,当我点击 MGLAnnotationView 时,标注会按预期显示在注释上方,但如果我稍
我正在使用 WKWebView 查看自定义 HTML。 无论 HTML 内容如何,在真实设备上进行测试时,我都会在 Could not signal service com.apple.WebKi
我正在使用 WKWebView 查看自定义 HTML。 无论 HTML 内容如何,在真实设备上进行测试时,我都会在 Could not signal service com.apple.WebKi
我是一名优秀的程序员,十分优秀!